blob: bdbd00f94680117f52ecc6009a6b0846b267d0f6 (
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
# - herbe (optional): -s
repos="${XDG_DATA_HOME:-$HOME}"/git-track.txt
touch "$repos"
help() {
>&2 cat <<EOF
usage: gt [OPTION]
-a PATH add repo
-s update and show status of each repo
-c COMMAND run 'git COMMAND' in each repo
-h show this help
-l list repos
-e edit repos in $EDITOR
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
# \r\033[0K : clear current line
do >&2 printf '\r\033[0K%s' "$line"
done
}
# Print repositories prettily
# This function function prints animations (eg. clearing the line)
# to stderr and the final status line is outputted to stdout.
status() {
while read -r repo
do
repo_pretty="$(printf '%s' "$repo" | sed "s@$HOME@~@" )"
# absolute path
cd "$repo"
# replace line with status
>&2 printf '\r\033[0K'
status="$(git status --porcelain 2> /dev/null | awk '{print $1}' | uniq | tr -d '\n')"
remote="$(git branch -v 2>/dev/null | sed 's/ahead/↑/;s/behind/↓/;s/[^↓↑]*//g')"
printf '%s %s %s\n' "$repo_pretty" "$status" "$remote"
done < "$repos"
}
# run git command in each repo
# $1: command
repos_cmd() {
while read -r repo
do
repo_pretty="$(printf '%s' "$repo" | sed "s@$HOME@~@" )"
printf ''\''%s'\'' in %s' "$1" "$repo_pretty"
(
cd "$repo"
git "$1" > /dev/null 2>&1
[ $? -gt 0 ] && s="x" || s="o"
printf '\r\033[0K%s: %s\n' "$repo_pretty" "$s"
)
done < "$repos"
}
# no options
if [ -z "$1" ]
then
help
exit 1
fi
while getopts ":a:c:f:lshe" opt
do
case "$opt" in
a)
cd "$OPTARG" || exit 1
r="$(git rev-parse --show-toplevel)"
[ "$r" ] || exit 2
if grep "$r" "$repos" > /dev/null 2>&1
then
>&2 printf 'added already.\n'
exit 2
fi
printf '%s\n' "$r" >> "$repos"
>&2 printf 'added.\n' ;;
c) repos_cmd "$OPTARG" ;;
s) status=1 ;;
l) cat "$repos" ;;
e) $EDITOR "$repos" ;;
f) repos="$OPTARG" ;;
T) help ;;
:) >&2 printf -- '-%s requires argument\n' "$OPTARG"; exit 1 ;;
?) >&2 printf -- 'Invalid option: -%s\n' "$OPTARG"; exit 1 ;;
esac
done
if [ "$status" ]
then
status
which herbe > /dev/null 2>&1 &&
eval "herbe $(status | sed 's/"/\"/g;s/.*/"&"/' | tr '\n' ' ')" &
fi
|