dotfiles/services/.local/share/services/git-sync
Marty Oehme 0b43d717d3
git-sync: Add sanity check before remote pull
Added check to fetch remote updates before actually pulling in remote
changes.
This may help somewhat with the modification of files when they are
simultaneously open in vim, though I am not entirely sure.
Needs further investigation.
2020-11-13 08:21:16 +01:00

111 lines
2.4 KiB
Bash
Executable file

#!/usr/bin/env sh
#
# 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.
# 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}
# logging verbosity level -- 0=error, 1=info, 2=debug
VERBOSITY=${GS_LOG_VERBOSITY:-1}
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}"
}
pull() {
msg "Pulling upstream changes into $DIR"
run_git pull --ff-only --ff
}
commit() {
msg "Committing changes to $DIR"
run_git add .
# shellcheck disable=2039
run_git commit --no-gpg-sign -m "Git sync: $(date +%F_%R) from ${HOSTNAME:-"${HOST:-undefined}"}"
}
push() {
msg "No changes for $((UNCHANGED_RUNS_TO_PUSH * TIME_TO_COMMIT)) seconds, pushing to origin"
run_git push
}
should_commit() {
if [ "$(run_git diff-files --name-only | wc -l)" -eq 0 ]; then
msg "No changes to commit in $DIR" 2
false
else
msg "Found changes to commit in $DIR" 2
true
fi
}
should_push() {
if [ "$no_change_cycle" -ge "$UNCHANGED_RUNS_TO_PUSH" ]; then
true
else
false
fi
}
should_pull() {
run_git fetch
# shellcheck disable=1083
if [ "$(run_git rev-parse HEAD)" = "$(run_git rev-parse @{u})" ]; then
false
else
true
fi
}
run_git() {
git -C "$DIR" "$@"
}
# echos its first argument
# verbosity level optionally set through second argument
# default verbosity 1 (info), can be set to 2 (debug), or 0 (error)
msg() {
lvl=${2:-1}
[ "$lvl" -gt "$VERBOSITY" ] && return 0
echo "$1"
}
watch_changes() {
no_change_cycle=0
while true; do
if should_pull; then
pull
fi
if should_commit; then
commit
no_change_cycle=0
fi
if should_push; then
push
no_change_cycle=-9999
fi
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
}
main "$1"