-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgit-recurse
executable file
·99 lines (94 loc) · 1.91 KB
/
git-recurse
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
#!/bin/sh
SEPARATOR=@@
# TODO this logic should probably rather be in rev-parse itself
# what it does:
# whenever an expression foo@@bar is used as an argument
# it checks whether foo is a valid reference, and if not, bar is used instead
processarg()
{
prefix=
suffix=
case "$1" in
# have to detect some rev-parse syntax
*..*)
first=${1%%..*}
rest=${1#*..}
first=`processarg "$first"`
rest=`processarg "$rest"`
echo "$first..$rest"
;;
*@\{*)
first=${1%%@\{*}
rest=${1#*@\{}
first=`processarg "$first"`
echo "$first@{$rest"
;;
*^*)
first=${1%%^*}
rest=${1#*^}
first=`processarg "$first"`
echo "$first^$rest"
;;
*~*)
first=${1%%~*}
rest=${1#*~}
first=`processarg "$first"`
echo "$first~$rest"
;;
*:*)
first=${1%%:*}
rest=${1#*:}
first=`processarg "$first"`
echo "$first:$rest"
;;
^*)
first=${1#^}
first=`processarg "$first"`
echo "^$first"
;;
# handle foo@@bar so that if foo exists, foo stays, otherwise bar
*$SEPARATOR*)
first=${1%%$SEPARATOR*}
rest=${1#*$SEPARATOR}
if git rev-parse "$first" >/dev/null 2>&1; then
echo "$first"
else
processarg "$rest"
fi
;;
# other args stay as is
*)
echo "$1"
;;
esac
}
processargs()
{
first=true
for X in "$@"; do
if $first; then
first=false
# clear arg list
set --
fi
set -- "$@" "`processarg "$X"`"
done
echo >&2 "In `pwd`: $*"
"$@"
}
# save stdin
exec 3<&0
# recurse through all sub-repos
status=0
# TODO is there a better way to identify all sub-repos?
find . -type d -name \*.git -prune | while IFS= read -r GITDIR; do
# TODO I would LIKE to do this, but then some commands (like pull) fail
#export GIT_DIR="$GITDIR"
#export GIT_WORK_TREE="${GITDIR%/.git}"
# so I will have to chdir instead
( cd "$GITDIR/.." && processargs git "$@" <&3 3<&- ) # use restored stdin
if [ "$?" -gt "$status" ]; then
status=$?
fi
done
exit "$status"