summaryrefslogtreecommitdiffstats
path: root/g
diff options
context:
space:
mode:
Diffstat (limited to 'g')
-rwxr-xr-xg306
1 files changed, 306 insertions, 0 deletions
diff --git a/g b/g
new file mode 100755
index 000000000000..0e4165e9bede
--- /dev/null
+++ b/g
@@ -0,0 +1,306 @@
+#!/usr/bin/env bash
+#
+# Wrapper for git to handle more subdirs at the same time
+#
+
+# no params, no action
+if [ "$#" -eq "0" ] ; then
+ git
+ echo
+ echo "Additional options available only in this 'g' wrapper:"
+ echo
+ echo "Usage: g [options] [git commands]"
+ echo " -f Force - act on all the repos, not only the changed ones"
+ echo " -s Silent - do not report the repo names."
+ echo " -1 report the repos name on the first line of the output as <repo>:"
+ echo " --set-push-user [username] re-write an existing tree's config with an fd.o commit account name"
+ exit $?
+fi
+
+CLONEDIR=$(perl -e 'use Cwd "abs_path"; print abs_path(shift);' $0 | sed -e ' s/\/g$/\/clone/')
+if [ ! -e ${CLONEDIR} ]; then mkdir -p $CLONEDIR; fi
+RAWBUILDDIR=$(perl -e 'use Cwd "abs_path"; print abs_path(shift);' $0 | sed -e ' s/\/g$//')
+if [ ! -e ${RAWBUILDDIR} ]; then mkdir -p $RAWBUILDDIR; fi
+
+# should we need to update the hooks
+function update_hooks()
+{
+ HOOKDIR="$1"
+ for H in $(cd "$RAWBUILDDIR/git-hooks" ; echo *) ; do
+ HOOK=".git/hooks/$H"
+ if [ ! -x "$HOOK" -a ! -L "$HOOK" ] ; then
+ rm -f "$HOOK"
+ ln -s "$HOOKDIR/$H" "$HOOK"
+ fi
+ done
+ if [ -z "$(git config push.default)" ] ; then
+ git config push.default tracking
+ fi
+ if [ "$PWD" != "$RAWBUILDDIR" -a ! -e .gitattributes ]; then
+ ln -s $RAWBUILDDIR/.gitattributes .
+ fi
+}
+
+# extra params for some commands, like log
+EXTRA=
+COMMAND="$1"
+PAGER=
+RELATIVIZE=1
+PUSH_ALL=
+ALLOW_EMPTY=
+KEEP_GOING=0
+REPORT_REPOS=1
+REPORT_COMPACT=0
+
+while [ "${COMMAND:0:1}" = "-" ] ; do
+ case "$COMMAND" in
+ -f) KEEP_GOING=1
+ ;;
+ -s) REPORT_REPOS=0
+ ;;
+ -1) REPORT_COMPACT=1
+ ;;
+ --set-push-user)
+ shift
+ PUSH_USER="$1"
+ ;;
+ esac
+ shift
+ COMMAND="$1"
+done
+
+case "$COMMAND" in
+ apply)
+ EXTRA="-p0 --stat --apply --index --ignore-space-change --whitespace=error"
+ RELATIVIZE=0
+ ;;
+ diff)
+ PAGER='--no-pager'
+ REPORT_REPOS=0
+ ;;
+ log)
+ if [ "$#" = "1" ] ; then
+ EXTRA='-1'
+ fi
+ PAGER='--no-pager'
+ ;;
+ push)
+ if [ "$#" != "1" ] ; then
+ PUSH_ALL=1
+ fi
+ ;;
+esac
+
+# absolutize the parameters first
+unset FILES
+FILESNUM=0
+while shift ; do
+ PARAM="$1"
+ if [ -z "$PARAM" ] ; then
+ continue
+ elif [ "${PARAM:0:1}" = "-" ] ; then
+ if [ \( "$COMMAND" = "checkout" -a "$PARAM" = "-b" \) -o \
+ \( "$COMMAND" = "clone" -a "$PARAM" = "--reference" \) -o \
+ \( "$COMMAND" = "commit" -a "$PARAM" = "-m" \) -o \
+ \( "$COMMAND" = "commit" -a "$PARAM" = "-am" \) -o \
+ \( "$COMMAND" = "tag" -a "$PARAM" = "-m" \) ]
+ then
+ # params that take an argument
+ FILES[$FILESNUM]="$PARAM"
+ FILESNUM=$(($FILESNUM+1))
+ shift
+ FILES[$FILESNUM]="$1"
+ FILESNUM=$(($FILESNUM+1))
+ else
+ if [ "$COMMAND" = "commit" -a "$PARAM" = "-F" ]
+ then
+ shift
+ # this still needs some magic to handle relative paths
+ EXTRA="${EXTRA} -F ${1}"
+ else
+ [ "$COMMAND" = "commit" -a "$PARAM" = "--allow-empty" ] && ALLOW_EMPTY=1
+ FILES[$FILESNUM]="$PARAM"
+ FILESNUM=$(($FILESNUM+1))
+ fi
+ fi
+ else
+ if [ "$COMMAND" = "apply" ] ; then
+ grep -qs $'^+ *\t' "$PARAM" && {
+ echo "Patch '$PARAM' introduces tabs in indentation, aborting."
+ echo
+ echo "Please fix the patch (something like s/^\(+ *\)\t/\1 /) and try again."
+ echo
+ exit 1
+ }
+ fi
+
+ # make the paths absolute
+ FILES[$FILESNUM]=$(perl -e 'use Cwd "abs_path"; print abs_path(shift);' "$PARAM")
+ if [ -z "${FILES[$FILESNUM]}" -o ! -e "${FILES[$FILESNUM]}" ] ; then
+ # it is probably not a file, but a tag name, or something
+ FILES[$FILESNUM]="$PARAM"
+ fi
+ FILESNUM=$(($FILESNUM+1))
+ fi
+done
+
+# do it!
+DIRS="core $(cd $CLONEDIR ; ls)"
+if [ "$COMMAND" = "clone" ] ; then
+ DIRS=$(cat "$RAWBUILDDIR/bin/repo-list")
+ # update hooks in the main repo too
+ ( cd "$RAWBUILDDIR" ; update_hooks "../../git-hooks" )
+fi
+for REPO in $DIRS ; do
+ DIR="$CLONEDIR/$REPO"
+ NAME="$REPO"
+ HOOKDIR="../../../../git-hooks"
+ if [ "$REPO" = "core" ] ; then
+ DIR="$RAWBUILDDIR"
+ NAME="main repo"
+ HOOKDIR="../../git-hooks"
+ fi
+
+ if [ -d "$DIR" -a "z$PUSH_USER" != "z" ]; then
+ echo "setting up push url for $DIR"
+ (cd $DIR && git config remote.origin.pushurl "ssh://${PUSH_USER}@git.freedesktop.org/git/libreoffice/${REPO}")
+ elif [ \( -d "$DIR" -a -d "$DIR"/.git \) -o \( "$COMMAND" = "clone" \) ] ; then
+ (
+ # executed in a subshell
+ if [ "$COMMAND" != "clone" ] ; then
+ cd "$DIR"
+ update_hooks "$HOOKDIR"
+ else
+ cd "$CLONEDIR"
+ fi
+
+ # relativize the absolutized params again if we want to operate
+ # only on the files belonging to this exact repo
+ if [ "$RELATIVIZE" = "1" -a -n "$FILES" ] ; then
+ FILESNUM=0
+ INSERTNUM=0
+ PWD=$(pwd)
+ PWDLEN=$(pwd | wc -c)
+ for I in "${FILES[@]}" ; do
+ I="${I//@REPO@/${REPO}}"
+ unset FILES[$FILESNUM]
+ FILESNUM=$(($FILESNUM+1))
+ # filter out files that don't belong to this repo
+ if [ \( "${I:0:1}" = "/" \) -a \( "$COMMAND" != "clone" \) ] ; then
+ if [ "${I:0:$PWDLEN}" = "$PWD/" ] ; then
+ FILES[$INSERTNUM]="${I:$PWDLEN}"
+ INSERTNUM=$(($INSERTNUM+1))
+ fi
+ else
+ FILES[$INSERTNUM]="$I"
+ INSERTNUM=$(($INSERTNUM+1))
+ fi
+ done
+ [ "$INSERTNUM" = "0" ] && exit 0
+ fi
+
+ # some extra params
+ case "$COMMAND" in
+ apply)
+ for I in * ; do
+ if [ -d "$I" ] ; then
+ EXTRA="$EXTRA --include=$I/*"
+ else
+ EXTRA="$EXTRA --include=$I"
+ fi
+ done
+ ;;
+ commit)
+ if [ "$ALLOW_EMPTY" != "1" ] ; then
+ [ -z "$(git diff-index --name-only HEAD --)" ] && exit 0
+ fi
+ ;;
+ push)
+ if [ "$PUSH_ALL" != "1" ] ; then
+ [ -n "$(git rev-list origin..HEAD)" ] || exit 0
+ fi
+ ;;
+ status)
+ LOCALCOMMITS="$(git rev-list origin..HEAD)"
+ if [ -z "$LOCALCOMMITS" ] ; then
+ [ -z "$(git diff-index --name-only HEAD --)" ] && exit 0
+ fi
+ ;;
+ clone)
+ EXTRA="$(git config remote.origin.url)"
+ EXTRA=${EXTRA/core/${REPO}}
+ ;;
+ esac
+
+ # do it!
+ if [ "$COMMAND" != "clone" -o ! -d $DIR ] ; then
+ if [ "$REPORT_REPOS" = "1" -a "$COMMAND" != "grep" ] ; then
+ if [ "$REPORT_COMPACT" = "1" ] ; then
+ echo -n "${REPO}:"
+ else
+ echo "===== $NAME ====="
+ fi
+ fi
+ git $PAGER "$COMMAND" $EXTRA "${FILES[@]}"
+ RETURN=$?
+ fi
+
+ # now we can change the dir in case of clone as well
+ if [ "$COMMAND" = "clone" ] ; then
+ cd $DIR
+ update_hooks "$HOOKDIR"
+ fi
+
+ case "$COMMAND" in
+ pull|clone)
+ # update links
+ if [ "$DIR" != "$RAWBUILDDIR" ]; then
+ for link in $(ls) ; do
+ if [ ! -e "$RAWBUILDDIR/$link" ] ; then
+ if test -h "$RAWBUILDDIR/$link"; then
+ rm "$RAWBUILDDIR/$link"
+ echo -n "re-"
+ fi
+ echo "creating missing link $link"
+ ln -s "$DIR/$link" "$RAWBUILDDIR/$link"
+ fi
+ done
+ fi
+ ;;
+ status)
+ # git status returns error in some versions, clear that
+ RETURN=0
+ ;;
+ grep)
+ # git grep return an 'error' if nothing is found
+ # still we should continue grepping the other repos
+ RETURN=0
+ ;;
+ esac
+ if [ "$KEEP_GOING" = "1" ] ; then
+ RETURN=0
+ fi
+
+ exit $RETURN
+ ) || exit $?
+ fi
+done
+
+# Cleanup the broken links
+if [ "$COMMAND" = "pull" ] ; then
+ for link in $(ls $RAWBUILDDIR) ; do
+ if [ -h "$RAWBUILDDIR/$link" -a ! -e "$RAWBUILDDIR/$link" ]; then
+ echo "Removing broken link $link"
+ rm $RAWBUILDDIR/$link
+ fi
+ done
+fi
+
+# warn
+if [ "$COMMAND" = "apply" ] ; then
+ echo
+ echo "Don't forget to check the status & commit now ;-)"
+ echo
+fi
+
+# vi:set shiftwidth=4 expandtab: