#!/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 *..*) 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" ;; *$SEPARATOR*) first=${1%%$SEPARATOR*} rest=${1#*$SEPARATOR} if git rev-parse "$first" >/dev/null 2>&1; then echo "$first" else processarg "$rest" fi ;; *) echo "$1" ;; esac } processargs() { first=true for X in "$@"; do if $first; then first=false # clear arg list set -- fi set -- "$@" "`processarg "$X"`" done "$@" } # recurse through all sub-repos status=0 for GITDIR in `find . -type d -name \*.git`; 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 "$@" ) if [ "$?" -gt "$status" ]; then status=$? fi done exit "$status"