blob: e048912433c437847d6564dd6fc6f85f0c3ecc00 (
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/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, gt-st
if [ "$GIT_TRACK_REPOS" ]; then
export REPOS="$GIT_TRACK_REPOS"
else
export REPOS="$HOME/sync/share/git-track.txt"
fi
# 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"; }
quit_when_no_repos() {
if [ "$(wc -l <"$REPOS")" -eq 0 ];
then
>&2 printf 'No repositories added.\n'
exit 1
fi
}
# 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
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}')"
# TODO: check if remote_url is not empty
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)
quit_when_no_repos
list_repos |
if [ "$parallel" ]; then
parallel gt-cmd "{}" "$OPTARG"
else
xargs -I{} gt-cmd "{}" "$OPTARG"
fi
;;
s)
quit_when_no_repos
list_repos | xargs -I{} gt-st {} ;;
l)
quit_when_no_repos
list_repos ;;
e) $EDITOR "$REPOS" ;;
f) REPOS="$OPTARG" ;;
u)
quit_when_no_repos
>&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
|