1659bbe429
we use perl to determine the absolute path of argument thought to be fiels. but sometime they are not file at all and that call 'fail'. The code is meant to deal with such case, but on some platform that produce a scary message on stderr in the middle of the build log. This hide these messages. Change-Id: I52d43e0b26847ab091d76fd446a05c4d84836a77
421 lines
13 KiB
Bash
Executable file
421 lines
13 KiB
Bash
Executable file
#!/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 " -v Verbose - Print git commands."
|
|
echo " -1 report the repos name on the first line of the output as <repo>:"
|
|
echo " -z just to some house cleaning (hooks mostly). this is a stand-alone option as in ./g -z"
|
|
echo " --set-push-user [username] re-write an existing tree's config with an fd.o commit account name"
|
|
echo " --last-working checks out the last known working build (useful for windows)";
|
|
echo " --set-last-working adds a note denoting a working build";
|
|
echo " --push-notes pushes all notes";
|
|
exit $?
|
|
fi
|
|
|
|
if [ ! "`type -p git`" ]; then
|
|
echo "Cannot find the git binary! Is git installed and is in PATH?"
|
|
exit 1
|
|
fi
|
|
|
|
pushd $(dirname $0) > /dev/null
|
|
COREDIR=$(pwd)
|
|
popd > /dev/null
|
|
|
|
if test -f $COREDIR/bin/repo-list
|
|
then
|
|
ALLREPOS="core `cat "$COREDIR/bin/repo-list"`"
|
|
else
|
|
ALLREPOS=core
|
|
fi
|
|
|
|
refresh_hooks()
|
|
{
|
|
repo=$1
|
|
case "$repo" in
|
|
core)
|
|
pushd $COREDIR > /dev/null
|
|
for hook_name in $(ls -1 $COREDIR/git-hooks) ; do
|
|
hook=".git/hooks/$hook_name"
|
|
if [ ! -x "$hook" ] ; then
|
|
rm -f "$hook"
|
|
ln -sf "$COREDIR/git-hooks/$hook_name" "$hook"
|
|
fi
|
|
done
|
|
popd > /dev/null
|
|
;;
|
|
translations)
|
|
if [ -d $COREDIR/clone/translations ] ; then
|
|
pushd $COREDIR/clone/translations > /dev/null
|
|
for hook_name in $(ls -1 $COREDIR/clone/translations/git-hooks); do
|
|
hook=".git/hooks/$hook_name"
|
|
if [ ! -x "$hook" ] ; then
|
|
rm -f "$hook"
|
|
ln -sf "$COREDIR/clone/translations/git-hooks/$hook_name" "$hook"
|
|
fi
|
|
done
|
|
# .gitattribute should be per-repo, avoid entangling repos
|
|
if [ -L .gitattributes ] ; then
|
|
rm -f .gitattributes
|
|
fi
|
|
popd > /dev/null
|
|
fi
|
|
;;
|
|
binfilter|help|dictionaries)
|
|
if [ -d $COREDIR/clone/$repo ] ; then
|
|
pushd $COREDIR/clone/$repo > /dev/null
|
|
# fixme: we should really keep these per-repo to
|
|
# keep the repos independant. since these two
|
|
# are realy not independant yet, we keep using core's hooks
|
|
for hook_name in $(ls -1 $COREDIR/git-hooks) ; do
|
|
hook=".git/hooks/$hook_name"
|
|
if [ ! -x "$hook" ] ; then
|
|
rm -f "$hook"
|
|
ln -sf "$COREDIR/git-hooks/$hook_name" "$hook"
|
|
fi
|
|
done
|
|
# .gitattribute should be per-repo, avoid entangling repos
|
|
if [ -L .gitattributes ] ; then
|
|
rm -f .gitattributes
|
|
fi
|
|
popd > /dev/null
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
refresh_all_hooks()
|
|
{
|
|
repos="$ALLREPOS"
|
|
for repo in $repos ; do
|
|
refresh_hooks $repo
|
|
done
|
|
}
|
|
|
|
postprocess()
|
|
{
|
|
rc=$1
|
|
if $DO_HOOK_REFRESH ; then
|
|
refresh_all_hooks
|
|
fi
|
|
|
|
exit $rc;
|
|
}
|
|
|
|
CLONEDIR="$COREDIR/clone"
|
|
if [ ! -e ${CLONEDIR} ]; then mkdir -p "$CLONEDIR"; fi
|
|
|
|
# extra params for some commands, like log
|
|
EXTRA=
|
|
COMMAND="$1"
|
|
PAGER=
|
|
RELATIVIZE=1
|
|
PUSH_ALL=
|
|
PUSH_USER=
|
|
PUSH_NOTES=
|
|
LAST_WORKING=
|
|
SET_LAST_WORKING=
|
|
ALLOW_EMPTY=
|
|
KEEP_GOING=0
|
|
REPORT_REPOS=1
|
|
REPORT_COMMANDS=0
|
|
REPORT_COMPACT=0
|
|
DO_HOOK_REFRESH=false
|
|
|
|
while [ "${COMMAND:0:1}" = "-" ] ; do
|
|
case "$COMMAND" in
|
|
-f) KEEP_GOING=1
|
|
;;
|
|
-s) REPORT_REPOS=0
|
|
;;
|
|
-v) REPORT_COMMANDS=1
|
|
;;
|
|
-1) REPORT_COMPACT=1
|
|
;;
|
|
--set-push-user)
|
|
shift
|
|
PUSH_USER="$1"
|
|
;;
|
|
--last-working) LAST_WORKING=1
|
|
;;
|
|
--set-last-working) SET_LAST_WORKING=1
|
|
;;
|
|
--push-notes) PUSH_NOTES=1
|
|
;;
|
|
-z)
|
|
DO_HOOK_REFRESH=true
|
|
postprocess 0
|
|
;;
|
|
esac
|
|
shift
|
|
COMMAND="$1"
|
|
done
|
|
|
|
case "$COMMAND" in
|
|
apply)
|
|
EXTRA="-p0 --stat --apply --index --ignore-space-change --whitespace=error"
|
|
RELATIVIZE=0
|
|
;;
|
|
clone|fetch|pull)
|
|
DO_HOOK_REFRESH=true
|
|
;;
|
|
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
|
|
if [ "$COMMAND" == "rev-parse" ] ; then
|
|
# this is not a file
|
|
FILES[$FILESNUM]="$PARAM"
|
|
FILESNUM=$(($FILESNUM+1))
|
|
else
|
|
# make the paths absolute
|
|
FILES[$FILESNUM]=$(perl -e 'use Cwd "abs_path"; print abs_path(shift);' "$PARAM" 2>/dev/null)
|
|
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
|
|
fi
|
|
done
|
|
|
|
# do it!
|
|
DIRS="core $(cd $CLONEDIR ; ls)"
|
|
if [ "$COMMAND" = "clone" ] ; then
|
|
DIRS="$ALLREPOS"
|
|
fi
|
|
for REPO in $DIRS ; do
|
|
DIR="$CLONEDIR/$REPO"
|
|
NAME="$REPO"
|
|
if [ "$REPO" = "core" ] ; then
|
|
DIR="$COREDIR"
|
|
NAME="main repo"
|
|
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 "z$LAST_WORKING" != "z" ]; then
|
|
echo "fetching notes for $REPO ..."
|
|
(cd $DIR && git fetch origin 'refs/notes/*:refs/notes/*')
|
|
hash=`(cd $DIR && git log --pretty='%H %N' | grep 'win32 working build' | head -n1 | sed 's/ win32.*//')`
|
|
if test "z$hash" != "z"; then
|
|
echo "update to $hash"
|
|
(cd $DIR && git checkout $hash)
|
|
else
|
|
echo "Warning: missing known working note on repo $REPO"
|
|
fi
|
|
elif [ -d "$DIR" -a "z$SET_LAST_WORKING" != "z" ]; then
|
|
echo "fetching notes for $REPO ..."
|
|
(cd $DIR && git fetch origin 'refs/notes/*:refs/notes/*')
|
|
(cd $DIR && git notes add -m 'win32 working build')
|
|
elif [ -d "$DIR" -a "z$PUSH_NOTES" != "z" ]; then
|
|
echo "pushing notes for $REPO ..."
|
|
(cd $DIR && git push origin 'refs/notes/*:refs/notes/*')
|
|
elif [ \( -d "$DIR" -a -d "$DIR"/.git \) -o \( "$COMMAND" = "clone" \) ] ; then
|
|
(
|
|
# executed in a subshell
|
|
if [ "$COMMAND" != "clone" ] ; then
|
|
cd "$DIR"
|
|
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 @{upstream}..HEAD)" ] || exit 0
|
|
fi
|
|
;;
|
|
status)
|
|
LOCALCOMMITS="$(git rev-list @{upstream}..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
|
|
if [ "$REPORT_COMMANDS" = "1" ] ; then
|
|
echo "+ git $PAGER $COMMAND $EXTRA ${FILES[@]}"
|
|
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
|
|
fi
|
|
|
|
case "$COMMAND" in
|
|
pull|clone)
|
|
# update links
|
|
if [ "$DIR" != "$COREDIR" ]; then
|
|
for link in $(ls) ; do
|
|
if [ ! -e "$COREDIR/$link" ] ; then
|
|
if test -h "$COREDIR/$link"; then
|
|
rm "$COREDIR/$link"
|
|
echo -n "re-"
|
|
fi
|
|
echo "creating missing link $link"
|
|
ln -s "$DIR/$link" "$COREDIR/$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
|
|
) || postprocess $?
|
|
fi
|
|
done
|
|
|
|
# Cleanup the broken links
|
|
if [ "$COMMAND" = "pull" ] ; then
|
|
for link in $(ls $COREDIR) ; do
|
|
if [ -h "$COREDIR/$link" -a ! -e "$COREDIR/$link" ]; then
|
|
echo "Removing broken link $link"
|
|
rm $COREDIR/$link
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# warn
|
|
if [ "$COMMAND" = "apply" ] ; then
|
|
echo
|
|
echo "Don't forget to check the status & commit now ;-)"
|
|
echo
|
|
fi
|
|
|
|
postprocess $?
|
|
|
|
# vi:set shiftwidth=4 expandtab:
|