git-sync

Tool for periodic syncing of git repositories
git clone https://git.sinitax.com/sinitax/git-sync
Log | Files | Refs | sfeed.txt

git-syncd (3199B)


      1#!/bin/bash
      2
      3GIT_SYNCD_CONFIG_DIR=${GIT_SYNCD_CONFIG_DIR:-"$HOME/.config/git-sync"}
      4GIT_SYNCD_CONFIG=${GIT_SYNCD_CONFIG:-"$GIT_SYNCD_CONFIG_DIR/syncd.rc"}
      5
      6git_syncd=$0
      7
      8git_syncd_repos=()
      9
     10# auto sync exclude regex pattern
     11declare -g -A git_syncd_exclude=()
     12
     13# maximum time seconds between fetching changes and syncing
     14git_syncd_default_sync_timeout=600
     15declare -g -A git_syncd_sync_timeout=()
     16
     17# number of seconds to wait after deteced change to push
     18git_syncd_default_sync_delay=300
     19declare -g -A git_syncd_sync_delay=()
     20
     21sync() {
     22	echo "starting sync.."
     23	cd "$repo" && git-sync -n -s
     24}
     25
     26watcher() {
     27	repo=$1
     28	echo $repo ${git_syncd_exclude[@]} ${git_syncd_exclude[$repo]}
     29	exclude=${git_syncd_exclude[$repo]:-'\.git'}
     30	sync_delay=${git_syncd_sync_delay[$repo]:-$git_syncd_default_sync_delay}
     31	sync_timeout=${git_syncd_sync_timeout[$repo]:-$git_syncd_default_sync_timeout}
     32	sync "$repo"
     33	timeout=$sync_timeout
     34	while true; do
     35		if [ ! -e "$repo" ]; then
     36			echo "Repo does not exist"
     37			echo "sleeping (${timeout}s)"
     38			sleep $timeout
     39			continue
     40		fi
     41		echo "watching (${timeout}s)"
     42		file=$(timeout "$timeout" wd "$repo" inotifywait "." -r \
     43			-e modify,move,create,delete --exclude "$exclude" 2>/dev/null)
     44		rc=$?
     45		if [ ! -z "$file" ]; then
     46			echo "inotify wake: $file"
     47			timeout=$sync_delay
     48		elif [ $rc -eq 124 ]; then
     49			sync "$repo"
     50			timeout=$sync_timeout
     51		fi
     52		sleep 1
     53	done
     54}
     55
     56log_prefix() {
     57	repo="$1"
     58	repo_name=$(basename "$repo")
     59	repo_dir_name=$(basename $(dirname "$repo"))
     60	while read -r line; do
     61		prefix="$(date "+%Y-%m-%d %T")" #$repo_dir_name/$repo_name"
     62		prefix="$(echo "$prefix" | tr -d "\"" | tr -d "'")"
     63		echo "[$prefix] $line"
     64	done
     65}
     66
     67kill_all() {
     68	pkill -A -9 git-syncd
     69}
     70
     71git_syncd_watchers=()
     72kill_watchers() {
     73	kill_all
     74	return
     75	fail=0
     76	for pid in "${git_syncd_watchers[@]}"; do
     77		echo "killing $pid.." >&2
     78		pkill -P "$pid" &>/dev/null
     79		waitpid -t 10 "$pid" &>/dev/null
     80		kill -0 -P "$pid" &>/dev/null && notify-send "Failed to kill git-syncd watcher" && fail=1
     81	done
     82	[ $fail -ne 0 ] && exit 1
     83	git_syncd_watchers=()
     84}
     85start_watchers() {
     86	for repo in "${git_syncd_repos[@]}"; do
     87		echo "watching '$repo'.."
     88		$git_syncd watch "$repo" &
     89		git_syncd_watchers+=($!)
     90	done
     91}
     92
     93load_config() {
     94	git_syncd_repos=()
     95	declare -g -A git_syncd_exclude=()
     96	declare -g -A git_syncd_sync_delay=()
     97	declare -g -A git_syncd_sync_timeout=()
     98	if [ -e "$GIT_SYNCD_CONFIG" ]; then
     99		echo "sourcing '$GIT_SYNCD_CONFIG'.."
    100		source "$GIT_SYNCD_CONFIG"
    101	fi
    102}
    103
    104if [ "$1" = "watch" ]; then
    105	shift
    106	repo="$1"; shift
    107	repo_dir_name="$(basename $(dirname "$repo"))"
    108	repo_name="$(basename "$repo")"
    109	log_path="$HOME/.log/git-sync/$repo_dir_name"
    110	mkdir -p "$log_path"
    111	load_config
    112	watcher "$repo" 2>&1 | log_prefix "$repo" > "$log_path/$repo_name"
    113	exit
    114fi
    115
    116load_config
    117trap kill_all EXIT
    118start_watchers
    119while true; do
    120	file=$(inotifywait --format "%w%f" -e modify,delete "$GIT_SYNCD_CONFIG")
    121	if [ ! -z "$file" ]; then
    122		mod_path="$(realpath "$file" 2>/dev/null)"
    123		config_path="$(realpath "$GIT_SYNCD_CONFIG" 2>/dev/null)"
    124		echo "config $mod_path $config_path"
    125		if [ "$mod_path" = "$config_path" ]; then
    126			kill_watchers
    127			load_config
    128			start_watchers
    129		fi
    130	fi
    131	sleep 2
    132done