2020-06-06 07:22:14 +00:00
#!/usr/bin/env sh
2020-06-17 19:00:41 +00:00
#
# Keeps a git directory synced by automatically committing every x seconds.
# After y number of runs without changes automatically pushes the directory to a remote.
2020-06-06 07:22:14 +00:00
# time in seconds to check for changes to commit
TIME_TO_COMMIT=${GS_TIME_TO_COMMIT:-120}
# amount of times to check for changes *without changes occurring* to push to origin
UNCHANGED_RUNS_TO_PUSH=${GS_UNCHANGED_RUNS_TO_PUSH:-30}
2020-06-17 19:00:41 +00:00
# logging verbosity level -- 0=error, 1=info, 2=debug
VERBOSITY=${GS_LOG_VERBOSITY:-1}
2020-06-06 07:22:14 +00:00
2020-06-17 19:00:41 +00:00
set_target() {
[ -z "$GS_TARGETDIR" ] && [ -z "$1" ] && {
msg "ERROR: git-sync requires a target directory to keep in sync to be passed in." 0
exit 1
}
DIR="${GS_TARGETDIR:-$1}"
}
2020-06-06 07:22:14 +00:00
2020-11-13 07:21:16 +00:00
pull() {
msg "Pulling upstream changes into $DIR"
2020-06-06 07:22:14 +00:00
run_git pull --ff-only --ff
2020-11-13 07:21:16 +00:00
}
2020-06-06 07:22:14 +00:00
2020-11-13 07:21:16 +00:00
commit() {
2020-06-06 07:22:14 +00:00
msg "Committing changes to $DIR"
run_git add .
# shellcheck disable=2039
2020-11-13 07:21:16 +00:00
run_git commit --no-gpg-sign -m "Git sync: $(date +%F_%R) from ${HOSTNAME:-"${HOST:-undefined}"}"
2020-06-06 07:22:14 +00:00
}
push() {
msg "No changes for $((UNCHANGED_RUNS_TO_PUSH * TIME_TO_COMMIT)) seconds, pushing to origin"
run_git push
}
should_commit() {
2020-06-17 19:00:41 +00:00
if [ "$(run_git diff-files --name-only | wc -l)" -eq 0 ]; then
msg "No changes to commit in $DIR" 2
2020-06-06 07:22:14 +00:00
false
2020-06-08 20:33:12 +00:00
else
2020-11-13 07:21:16 +00:00
msg "Found changes to commit in $DIR" 2
2020-06-08 20:33:12 +00:00
true
2020-06-06 07:22:14 +00:00
fi
}
should_push() {
if [ "$no_change_cycle" -ge "$UNCHANGED_RUNS_TO_PUSH" ]; then
true
else
false
fi
}
2020-11-13 07:21:16 +00:00
should_pull() {
run_git fetch
# shellcheck disable=1083
if [ "$(run_git rev-parse HEAD)" = "$(run_git rev-parse @{u})" ]; then
false
else
true
fi
}
2020-06-06 07:22:14 +00:00
run_git() {
git -C "$DIR" "$@"
}
2020-06-17 19:00:41 +00:00
# echos its first argument
# verbosity level optionally set through second argument
2020-11-13 07:21:16 +00:00
# default verbosity 1 (info), can be set to 2 (debug), or 0 (error)
2020-06-06 07:22:14 +00:00
msg() {
2020-06-17 19:00:41 +00:00
lvl=${2:-1}
[ "$lvl" -gt "$VERBOSITY" ] && return 0
2020-06-06 07:22:14 +00:00
echo "$1"
}
2020-06-17 19:00:41 +00:00
watch_changes() {
no_change_cycle=0
while true; do
2020-11-13 07:21:16 +00:00
if should_pull; then
pull
fi
2020-06-17 19:00:41 +00:00
if should_commit; then
commit
no_change_cycle=0
fi
2020-06-06 07:22:14 +00:00
2020-06-17 19:00:41 +00:00
if should_push; then
push
no_change_cycle=-9999
fi
2020-06-06 07:22:14 +00:00
2020-06-17 19:00:41 +00:00
msg "No changes for $((no_change_cycle * TIME_TO_COMMIT)) of $((UNCHANGED_RUNS_TO_PUSH * TIME_TO_COMMIT)) seconds, going back to sleep for $((TIME_TO_COMMIT)) seconds." 2
no_change_cycle=$((no_change_cycle + 1))
sleep "$TIME_TO_COMMIT"
done
}
main() {
set_target "$1"
watch_changes
}
2020-06-06 07:22:14 +00:00
2020-06-17 19:00:41 +00:00
main "$1"