3 # Wrapper for git to handle more subdirs at the same time
7 if [ "$#" -eq "0" ] ; then
10 echo "Additional options available only in this 'g' wrapper:"
12 echo "Usage: g [options] [git commands]"
13 echo " -f Force - act on all the repos, not only the changed ones"
14 echo " -s Silent - do not report the repo names."
15 echo " -1 report the repos name on the first line of the output as <repo>:"
16 echo " -z just to some house cleaning (hooks mostly). this is a stand-alone option as in ./g -z"
17 echo " --set-push-user [username] re-write an existing tree's config with an fd.o commit account name"
18 echo " --last-working checks out the last known working build (useful for windows)";
19 echo " --set-last-working adds a note denoting a working build";
20 echo " --push-notes pushes all notes";
24 if [ ! "`type -p git`" ]; then
25 echo "Cannot find the git binary! Is git installed and is in PATH?"
29 pushd $
(dirname $0) > /dev
/null
38 pushd $COREDIR > /dev
/null
39 for hook_name
in $
(ls -1 $COREDIR/git-hooks
) ; do
40 hook
=".git/hooks/$hook_name"
41 if [ ! -x "$hook" ] ; then
43 ln -sf "$COREDIR/git-hooks/$hook_name" "$hook"
49 if [ -d $COREDIR/clone
/translations
] ; then
50 pushd $COREDIR/clone
/translations
> /dev
/null
51 for hook_name
in $
(ls -1 $COREDIR/clone
/translations
/git-hooks
); do
52 hook
=".git/hooks/$hook_name"
53 if [ ! -x "$hook" ] ; then
55 ln -sf "$COREDIR/clone/translations/git-hooks/$hook_name" "$hook"
58 # .gitattribute should be per-repo, avoid entangling repos
59 if [ -L .gitattributes
] ; then
65 binfilter|
help|dictionaries
)
66 if [ -d $COREDIR/clone
/$repo ] ; then
67 pushd $COREDIR/clone
/$repo > /dev
/null
68 # fixme: we should really keep these per-repo to
69 # keep the repos independant. since these two
70 # are realy not independant yet, we keep using core's hooks
71 for hook_name
in $
(ls -1 $COREDIR/git-hooks
) ; do
72 hook
=".git/hooks/$hook_name"
73 if [ ! -x "$hook" ] ; then
75 ln -sf "$COREDIR/git-hooks/$hook_name" "$hook"
78 # .gitattribute should be per-repo, avoid entangling repos
79 if [ -L .gitattributes
] ; then
90 repos
="core $(cat "$COREDIR/bin
/repo-list
")"
91 for repo
in $repos ; do
99 if $DO_HOOK_REFRESH ; then
106 CLONEDIR
="$COREDIR/clone"
107 if [ ! -e ${CLONEDIR} ]; then mkdir
-p "$CLONEDIR"; fi
109 # extra params for some commands, like log
123 DO_HOOK_REFRESH
=false
125 while [ "${COMMAND:0:1}" = "-" ] ; do
137 --last-working) LAST_WORKING
=1
139 --set-last-working) SET_LAST_WORKING
=1
141 --push-notes) PUSH_NOTES
=1
154 EXTRA
="-p0 --stat --apply --index --ignore-space-change --whitespace=error"
165 if [ "$#" = "1" ] ; then
171 if [ "$#" != "1" ] ; then
177 # absolutize the parameters first
182 if [ -z "$PARAM" ] ; then
184 elif [ "${PARAM:0:1}" = "-" ] ; then
185 if [ \
( "$COMMAND" = "checkout" -a "$PARAM" = "-b" \
) -o \
186 \
( "$COMMAND" = "clone" -a "$PARAM" = "--reference" \
) -o \
187 \
( "$COMMAND" = "commit" -a "$PARAM" = "-m" \
) -o \
188 \
( "$COMMAND" = "commit" -a "$PARAM" = "-am" \
) -o \
189 \
( "$COMMAND" = "tag" -a "$PARAM" = "-m" \
) ]
191 # params that take an argument
192 FILES
[$FILESNUM]="$PARAM"
193 FILESNUM
=$
(($FILESNUM+1))
195 FILES
[$FILESNUM]="$1"
196 FILESNUM
=$
(($FILESNUM+1))
198 if [ "$COMMAND" = "commit" -a "$PARAM" = "-F" ]
201 # this still needs some magic to handle relative paths
202 EXTRA
="${EXTRA} -F ${1}"
204 [ "$COMMAND" = "commit" -a "$PARAM" = "--allow-empty" ] && ALLOW_EMPTY
=1
205 FILES
[$FILESNUM]="$PARAM"
206 FILESNUM
=$
(($FILESNUM+1))
210 if [ "$COMMAND" = "apply" ] ; then
211 grep -qs $
'^+ *\t' "$PARAM" && {
212 echo "Patch '$PARAM' introduces tabs in indentation, aborting."
214 echo "Please fix the patch (something like s/^\(+ *\)\t/\1 /) and try again."
220 # make the paths absolute
221 FILES
[$FILESNUM]=$
(perl
-e 'use Cwd "abs_path"; print abs_path(shift);' "$PARAM")
222 if [ -z "${FILES[$FILESNUM]}" -o ! -e "${FILES[$FILESNUM]}" ] ; then
223 # it is probably not a file, but a tag name, or something
224 FILES
[$FILESNUM]="$PARAM"
226 FILESNUM
=$
(($FILESNUM+1))
231 DIRS
="core $(cd $CLONEDIR ; ls)"
232 if [ "$COMMAND" = "clone" ] ; then
233 DIRS
=$
(cat "$COREDIR/bin/repo-list")
235 for REPO
in $DIRS ; do
236 DIR
="$CLONEDIR/$REPO"
238 if [ "$REPO" = "core" ] ; then
243 if [ -d "$DIR" -a "z$PUSH_USER" != "z" ]; then
244 echo "setting up push url for $DIR"
245 (cd $DIR && git config remote.origin.pushurl
"ssh://${PUSH_USER}@git.freedesktop.org/git/libreoffice/${REPO}")
246 elif [ -d "$DIR" -a "z$LAST_WORKING" != "z" ]; then
247 echo "fetching notes for $REPO ..."
248 (cd $DIR && git fetch origin
'refs/notes/*:refs/notes/*')
249 hash=`(cd $DIR && git log --pretty='%H %N' | grep 'win32 working build' | head -n1 | sed 's/ win32.*//')`
250 if test "z$hash" != "z"; then
251 echo "update to $hash"
252 (cd $DIR && git checkout
$hash)
254 echo "Warning: missing known working note on repo $REPO"
256 elif [ -d "$DIR" -a "z$SET_LAST_WORKING" != "z" ]; then
257 echo "fetching notes for $REPO ..."
258 (cd $DIR && git fetch origin
'refs/notes/*:refs/notes/*')
259 (cd $DIR && git notes add
-m 'win32 working build')
260 elif [ -d "$DIR" -a "z$PUSH_NOTES" != "z" ]; then
261 echo "pushing notes for $REPO ..."
262 (cd $DIR && git push origin
'refs/notes/*:refs/notes/*')
263 elif [ \
( -d "$DIR" -a -d "$DIR"/.git \
) -o \
( "$COMMAND" = "clone" \
) ] ; then
265 # executed in a subshell
266 if [ "$COMMAND" != "clone" ] ; then
272 # relativize the absolutized params again if we want to operate
273 # only on the files belonging to this exact repo
274 if [ "$RELATIVIZE" = "1" -a -n "$FILES" ] ; then
278 PWDLEN
=$
(pwd |
wc -c)
279 for I
in "${FILES[@]}" ; do
280 I
="${I//@REPO@/${REPO}}"
281 unset FILES
[$FILESNUM]
282 FILESNUM
=$
(($FILESNUM+1))
283 # filter out files that don't belong to this repo
284 if [ \
( "${I:0:1}" = "/" \
) -a \
( "$COMMAND" != "clone" \
) ] ; then
285 if [ "${I:0:$PWDLEN}" = "$PWD/" ] ; then
286 FILES
[$INSERTNUM]="${I:$PWDLEN}"
287 INSERTNUM
=$
(($INSERTNUM+1))
290 FILES
[$INSERTNUM]="$I"
291 INSERTNUM
=$
(($INSERTNUM+1))
294 [ "$INSERTNUM" = "0" ] && exit 0
301 if [ -d "$I" ] ; then
302 EXTRA
="$EXTRA --include=$I/*"
304 EXTRA
="$EXTRA --include=$I"
309 if [ "$ALLOW_EMPTY" != "1" ] ; then
310 [ -z "$(git diff-index --name-only HEAD --)" ] && exit 0
314 if [ "$PUSH_ALL" != "1" ] ; then
315 [ -n "$(git rev-list origin..HEAD)" ] ||
exit 0
319 LOCALCOMMITS
="$(git rev-list origin..HEAD)"
320 if [ -z "$LOCALCOMMITS" ] ; then
321 [ -z "$(git diff-index --name-only HEAD --)" ] && exit 0
325 EXTRA
="$(git config remote.origin.url)"
326 EXTRA
=${EXTRA/core/${REPO}}
331 if [ "$COMMAND" != "clone" -o ! -d $DIR ] ; then
332 if [ "$REPORT_REPOS" = "1" -a "$COMMAND" != "grep" ] ; then
333 if [ "$REPORT_COMPACT" = "1" ] ; then
336 echo "===== $NAME ====="
339 git
$PAGER "$COMMAND" $EXTRA "${FILES[@]}"
343 # now we can change the dir in case of clone as well
344 if [ "$COMMAND" = "clone" ] ; then
351 if [ "$DIR" != "$COREDIR" ]; then
352 for link
in $
(ls) ; do
353 if [ ! -e "$COREDIR/$link" ] ; then
354 if test -h "$COREDIR/$link"; then
358 echo "creating missing link $link"
359 ln -s "$DIR/$link" "$COREDIR/$link"
365 # git status returns error in some versions, clear that
369 # git grep return an 'error' if nothing is found
370 # still we should continue grepping the other repos
374 if [ "$KEEP_GOING" = "1" ] ; then
383 # Cleanup the broken links
384 if [ "$COMMAND" = "pull" ] ; then
385 for link
in $
(ls $COREDIR) ; do
386 if [ -h "$COREDIR/$link" -a ! -e "$COREDIR/$link" ]; then
387 echo "Removing broken link $link"
394 if [ "$COMMAND" = "apply" ] ; then
396 echo "Don't forget to check the status & commit now ;-)"
402 # vi:set shiftwidth=4 expandtab: