blob: 8b0a95f529a48a336489256d3167c02df4149bdb (
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
106
107
108
109
110
111
|
#!/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
-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
}
list_repos() { cut -f 1 -d ' ' "$repos"; }
# 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)
list_repos |
if [ "$parallel" ]; then
parallel gt-cmd "{}" "$OPTARG"
else
xargs -I{} gt-cmd "{}" "$OPTARG"
fi
;;
s) list_repos | xargs -I{} gt-st {} ;;
l) list_repos ;;
e) $EDITOR "$repos" ;;
f) repos="$OPTARG" ;;
u)
>&2 printf 'pull:\n'
if [ "$parallel" ]; then
list_repos | parallel gt-cmd {} pull
else
list_repos | xargs -I{} gt-cmd {} pull
fi
>&2 printf 'push:\n'
list_repos |
xargs -I{} gt-st {} |
awk -F: '/↑/ {print $1}' |
sed "s@^~@$HOME@" |
if [ "$parallel" ]; then
parallel gt-cmd {} push
else
xargs -I{} gt-cmd {} push
fi
;;
h) help ;;
:)
printf >&2 -- '-%s requires argument\n' "$OPTARG"
exit 1
;;
?)
printf >&2 -- 'Invalid option: -%s\n' "$OPTARG"
exit 1
;;
esac
done
|