diff --git a/scripts/pgit.sh b/scripts/pgit.sh new file mode 100644 index 00000000..94a4b6f2 --- /dev/null +++ b/scripts/pgit.sh @@ -0,0 +1,202 @@ +#!/bin/sh + +log() +{ + echo $@ +} + +err() +{ + log $@ +} + +fatal() +{ + err $@ + exit 1 +} + +marker() +{ + log "# ------------- [$cur/$n_projects] $@" +} + +fat_marker() +{ + log "# ==================================================== [$cur/$n_projects] $@" +} + +config() +{ + [ "$pdir" ] || { + # guess pdir + pdir=`pwd` + while [ `cat $pdir/CVS/Repository 2>/dev/null` != proj ]; do + [ "$pdir" = / ] && fatal "didn't find \"proj\" in directory components" + pdir=`dirname $pdir` + done + } + + [ "$pdirs" ] || { + pdirs=`(cd $pdir; ls -d */.git 2>/dev/null | sed 's%/.git%%')` + } + n_projects=`echo $pdirs | wc -w` +} + +run_git() +{ + marker git "$@" + # sadly, CentOS 7 has git 1.8.3.1, which doesn't support -C + if [ "$1" = -C ]; then + ( + cd $2 + shift 2 + git "$@" + ) + return $? + fi + git "$@" +} + +# ------------- commands +run() +{( + local cmd=$1 + local d + + shift + config + cd $pdir + + if [ "$PGIT_KEEP_GOING" != y ]; then set -e; fi + for d in $pdirs; do + cur=`expr $cur + 1` + run_git -C $d $cmd "$@" + done +)} + +commit() +{( + local d do_cvs + + if [ "$1" = --cvs ]; then + do_cvs=true + shift + fi + + config + cd $pdir + + if [ "$PGIT_KEEP_GOING" != y ]; then set -e; fi + for d in $pdirs; do + cur=`expr $cur + 1` + if run_git -C $d diff-index --quiet HEAD --; then + log "Nothing to commit" + continue + fi + run_git -C $d commit "$@" + done + + if [ "$do_cvs" = true -a -d CVS ]; then + cvs commit "$@" + fi +)} + +clone() +{( + local p + config + cd $pdir + local refspec=(${PGIT_CLONE_FROM_USER//:/ }) + local fromuser=${refspec[0]} + local fromref=${refspec[1]} + local toref=${refspec[2]} + local login=$JANWARE_USER + local projects="$PGIT_CLONE_PROJECTS" + local ignore="$PGIT_IGNORE" + [ "$login" ] || login=`whoami` + [ "$fromuser" ] || fromuser=`whoami` + [ "$fromref" ] || fromref=master + local git_srv_admin="$SSH $login@git.janware.com /opt/jw-build/bin/git-srv-admin.sh" + if [ -z "$projects" ]; then + projects=`$git_srv_admin -u $fromuser -j list-personal-projects` + [ "$?" != 0 ] && exit 1 + fi + n_projects=`echo $projects | wc -w` + if [ "$PGIT_KEEP_GOING" != y ]; then set -e; fi + for p in $projects; do + if echo $ignore | grep -q "\b$p\b"; then + continue + fi + cur=`expr $cur + 1` + local pullurl=ssh://$login@git.janware.com/srv/git/$fromuser/proj/$p + local pushurl=ssh://$login@git.janware.com/srv/git/$login/proj/$p + local curref="" + fat_marker "Fetching project $p from user $fromuser" + if [ "$fromuser" = "$login" ]; then + if [ -d $p ]; then + run_git -C $p pull --recurse-submodules=on-demand + else + run_git clone ssh://$login@git.janware.com/srv/git/$fromuser/proj/$p + fi + else + local remotename="jw-$fromuser" + if [ -d $p ]; then + run_git -C $p remote | grep -q "^$remotename$" || { + run_git -C $p remote add $remotename $pullurl + run_git -C $p remote set-url --push $remotename no_push + } + run_git -C $p fetch --prune --recurse-submodules=on-demand $remotename $fromref + if [ "$toref" ]; then + curref=`git -C $p branch --show-current` + if [ "$curref" = "$toref" ]; then + run_git -C $p pull --recurse-submodules=on-demand $remotename $fromref + else + run_git -C $p fetch --recurse-submodules=on-demand $remotename $fromref:$toref + fi + fi + else + # set -x + run_git clone ssh://$login@git.janware.com/srv/git/$fromuser/proj/$p + run_git -C $p remote rename origin $remotename || fatal failed to rename remote in $p + run_git -C $p remote set-url --push $remotename no_push + $git_srv_admin -u $login -j create-personal-project $p + run_git -C $p remote add origin $pushurl + run_git -C $p push --recurse-submodules=on-demand origin master + $git_srv_admin -u $login -j update-descriptions $p + run_git -C $p branch --set-upstream-to origin/master master + # set +x + fi + fi + run_git -C $p submodule update --init --recursive || fatal git submodule update failed in $p + done +)} + +diff() +{( + local d + config + cd $pdir + for d in $pdirs; do + cur=`expr $cur + 1` + # marker $d + run_git -C $d diff --src-prefix=$d/ --dst-prefix=$d/ "$@" + done +)} + +echo "running $0 $@ GIT_SSH=$GIT_SSH" >&2 + +SSH=ssh +[ "$GIT_SSH" ] && SSH=$GIT_SSH + +cmd=$1 +cur=0 +shift +case $cmd in + clone|diff|commit) + $cmd "$@" + ;; + *) + run $cmd "$@" + ;; +esac