summaryrefslogtreecommitdiff
path: root/bin/common/gt
blob: 8890ebbce1e5410fea95b4b9833be6a405e8aae8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/sh

# Git Trach, track the state of multiple repos from a single file.

# dependencies:
# - git
# - $EDITOR: -e
# - parallel: optional, if installed will run the commands on all repos with parallel
# - gt-[cmd,st,sync]

repos=$HOME/sync/share/git-track.txt
# prevent file not found errors
touch "$repos" || exit 1

which parallel >/dev/null 2>&1 && parallel=1

help() {
	cat >&2 <<EOF
usage: gt [OPTION]
-a PATH         add repo 
-y              show sync status
-c COMMAND      run 'git COMMAND' in each repo
-h              show this help
-l              list repos
-e 		edit repos in \$EDITOR
-f FILE         use FILE as list of repos
-u 		pull in repos out of sync
-s 		show status of files and remotes
EOF
}

# fetch repository prettily, outputs nothing if failed
fetch() {
	# fetch with one-line printing of progress
	git fetch --progress 2>/dev/null | while read -r line; do # \r\033[0K : clear current line
		printf >&2 '\r\033[0K%s' "$line"
	done
}

# no options
if [ -z "$1" ]; then
	help
	exit 1
fi

[ "$(wc -l <"$repos")" -gt 0 ] || exit 0

while getopts ":a:c:f:lsheu" opt; do
	case "$opt" in
	a)
		if ! cd "$OPTARG" 2>/dev/null; then
			>&2 printf 'Not a directory.\n'
			exit 1
		fi

		repo="$(git rev-parse --show-toplevel)"
		remote_url="$(git remote show -n origin | awk '/^  Fetch/ {print $NF}')"

		if grep "^$repo " "$repos" >/dev/null 2>&1; then
			printf >&2 'added already.\n'
			exit 3
		fi

		printf '%s %s\n' "$repo" "$remote_url" >>"$repos"

		printf >&2 'added.\n'
		;;
	c)
		cut -f 1 -d ' ' "$repos" |
			if [ "$parallel" ]; then
				parallel gt-cmd "{}" "$OPTARG"
			else
				xargs -I{} gt-cmd "{}" "$OPTARG"
			fi
		;;
	s) cut -f 1 -d ' ' "$repos" | xargs -I{} gt-st {} ;;
	l) cut -f 1 -d ' ' "$repos" ;;
	e) $EDITOR "$repos" ;;
	f) repos="$OPTARG" ;;
	u)
		if [ "$parallel" ]; then
			parallel --colsep ' ' gt-sync {1} {2} <"$repos"
		else
			IFS=' '
			while read -r repo remote_url; do
				gt-sync "$repo" "$remote_url"
			done <"$repos"
		fi | awk -F ':' '/x$/ {print $1}' | sed "s@~@$HOME@" |
			if [ "$parallel" ]; then
				parallel gt-cmd {} pull
			else
				xargs -I{} gt-cmd {} pull
			fi
		;;
	h) help ;;
	:)
		printf >&2 -- '-%s requires argument\n' "$OPTARG"
		exit 1
		;;
	?)
		printf >&2 -- 'Invalid option: -%s\n' "$OPTARG"
		exit 1
		;;
	esac
done