|
#!/bin/sh |
|
# |
|
# configs2git |
|
# configs2git -- backup filelist to Git/Mercurial repository. |
|
# |
|
# Required utilities: hg or git, rsync, mail (with "admins" alias) |
|
# |
|
# Written at Dec-2014 by [email protected] |
|
# Distributed as public domain. |
|
# |
|
|
|
INSTALL_ME_SO=' |
|
cd /usr/local/bin && |
|
wget -qO configs2git https://gist.githubusercontent.com/ilyaevseev/d34ade484e6782d71db1/raw/79ecef988737c5f1860a1c4482ce194619279f17/configs2git && |
|
chmod +x configs2git |
|
' |
|
|
|
ROOTDIR="/" |
|
DELMODE="warn" |
|
MYNAME="$(basename $0)" |
|
|
|
Err() { |
|
echo "$@" | mail -s "$MYNAME" admins |
|
logger -p user.err -t "$MYNAME" -s "$@" |
|
} |
|
|
|
Fail() { Err "$@"; exit 1; } |
|
|
|
case "$MYNAME" in |
|
*git* ) BASESYS="git" ;; |
|
*hg* | *mercurial* ) BASESYS="hg" ;; |
|
* ) Fail "my name is not configs2hg nor configs2git" ;; |
|
esac |
|
|
|
HgFail() { Fail "$BASESYS $@ failed in $DESTDIR"; } |
|
|
|
Doit() { |
|
test -n "$VERBOSE" && echo "$@" |
|
test -n "$DRY_RUN" || "$@" |
|
} |
|
|
|
while test $# != 0; do |
|
case "$1" in |
|
--trace ) shift; set -x ;; |
|
--dry ) shift; VERBOSE=1 ; DRY_RUN=1 ;; |
|
--verbose ) shift; VERBOSE=1 ;; |
|
--rootdir ) shift; test $# = 0 && Fail "missing --rootdir value"; ROOTDIR="$1"; shift ;; |
|
--delmode ) shift; test $# = 0 && Fail "missing --delmode value"; DELMODE="$1"; shift ;; |
|
-* ) Fail "wrong cmdline: $1" ;; |
|
* ) break ;; |
|
esac |
|
done |
|
|
|
test $# = 2 || Fail "usage: $0 filelist destdir" |
|
FILELIST="$1" |
|
DESTDIR="$2" |
|
|
|
test -d "$DESTDIR/.$BASESYS" || Fail "Missing subdir $DESTDIR/.$BASESYS" |
|
|
|
NOT_EMPTY= |
|
while read fn; do |
|
fn=${fn%%#*} # ..strip comments |
|
test "$fn" = "" && continue # ..skip empty lines. todo!!! trim spaces??? |
|
NOT_EMPTY=1 |
|
|
|
# todo??? support wildcards!!! |
|
src="$ROOTDIR/$fn" |
|
dst="$DESTDIR/$fn" |
|
|
|
if test -e "$dst" -a -e "$src"; then |
|
srctype="$(LANG=C stat -c '%F' "$src" 2>/dev/null)" |
|
dsttype="$(LANG=C stat -c '%F' "$dst" 2>/dev/null)" |
|
test "$srctype" = "$dsttype" || Fail "type changed: src:$src:$srctype dst:$dst:$dsttype" |
|
fi |
|
|
|
if test -d "$src/."; then |
|
mkdir -p "$dst" || Fail "mkdir $dst" |
|
Doit rsync -auq --delete --numeric-ids "$src/" "$dst/" || Fail "rsync $src $dst" |
|
# todo!!! use cp instead of rsync??? |
|
elif test -e "$src"; then |
|
Doit mkdir -p "$(dirname $dst)" || Fail "mkdir dirname $dst" |
|
Doit cp -auf "$src" "$dst" || Fail "cp $src $dst" |
|
else |
|
case "$DELMODE" in |
|
stop ) Fail "missing file $src" ;; |
|
skip ) ;; |
|
warn ) Err "missing file $src" ;; |
|
rm ) Doit rm -rf "$dst" ;; |
|
* ) Fail "wrong DELMODE value: $DELMODE" ;; |
|
esac |
|
fi |
|
done < $FILELIST |
|
|
|
test -z "$NOT_EMPTY" && Fail "nothing readed from $FILELIST" |
|
|
|
cd "$DESTDIR" |
|
"$BASESYS" status >/dev/null || HgFail "status" |
|
msg="$MYNAME: autocommit at $(date '+%Y-%m-%d_%H:%M:%S')" |
|
|
|
case "$BASESYS" in |
|
hg ) hg status | grep -q '' || exit # ..nothing to do |
|
Doit hg addremove || HgFail "addremove" |
|
Doit hg commit -m "$msg" || HgFail "commit" |
|
;; |
|
git ) git status | grep -qi 'nothing to commit' && exit |
|
Doit git add -A || HgFail "add -A" |
|
Doit git commit -am "$msg" || HgFail "commit" |
|
;; |
|
esac |