#!/bin/zsh
die() {
print -r - "$@"
exit 1
}
if [[ -z $SNAP_SRC ]]; then
SNAP_SRC=$1;shift
fi
SNAP_SRC=${SNAP_SRC%%/}
if [[ -z $SNAP_DST ]]; then
SNAP_DST=$1;shift
fi
SNAP_DST=${SNAP_DST%%/}
rsync=( rsync -aA --delete "$@" )
marks=( $SNAP_SRC/.snapshot.[0-9]*(N) )
(( $#marks != 1 )) && die invalid marks ${(qqq)marks}
if [[ $SNAP_DST == *:* ]]; then
# remote
[[ $SNAP_DST == *.push ]] || SNAP_DST=$SNAP_DST.push
$rsync --exclude=/.snapshot.\* $SNAP_SRC/ $SNAP_DST/ && \
$rsync $SNAP_SRC/ $SNAP_DST/
else
# local
[[ -d $SNAP_DST ]] || die destination not a directory: ${(qqq)SNAP_DST}
ts=${marks##*.}
snapshots=( ${SNAP_DST}/.snapshot.[1-9]*(N) )
if (($#snapshots)); then
link=${SNAP_DST}/${${snapshots[-1]}##*.}
$rsync --link-dest=$link $SNAP_SRC/ $SNAP_DST/$ts/ || exit $?
else
$rsync $SNAP_SRC/ $SNAP_DST/$ts/ || exit $?
fi
touch ${SNAP_DST}/$marks:t
fi