mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-25 09:35:54 +02:00
Calling make git-pull-xxx from a projects directory stops iterating projects if one has a dirty workspace. Calling --autostash fixes that. With this in place, a failed rebase leaves the local changes behind stashed. So, after manually fixing the rebase, the stash needs to be manually reapplied. The commands that led up to the failure are logged right before, so I have hope that this is learnable, and not too much of a footgun. Signed-off-by: Jan Lindemann <jan@janware.com>
264 lines
5.5 KiB
Bash
264 lines
5.5 KiB
Bash
#!/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 [ ! -r Makefile ] || ! grep -q some-random-string-to-id-this-makefile Makefile; 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 "$@"
|
|
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
|
|
)}
|
|
|
|
clone()
|
|
{(
|
|
run_clone() {
|
|
local url="$1"
|
|
local p="$2"
|
|
run_git $GIT_GLOBAL_OPTS clone "$url" "$p"
|
|
if [[ "$GIT_GLOBAL_OPTS" =~ proactiveAuth ]]; then
|
|
run_git -C $p config set http.proactiveAuth basic
|
|
fi
|
|
}
|
|
|
|
local remote_base="$global_remote_base"
|
|
local remote_subpath="$global_remote_subpath"
|
|
local p
|
|
local whoami="$(id -un)"
|
|
config
|
|
cd $pdir
|
|
local projects="$PGIT_CLONE_PROJECTS"
|
|
local ignore="$PGIT_IGNORE"
|
|
local thisdir="${0%/*}"
|
|
local jw_projects="/usr/bin/python3 $thisdir/jw-pkg.py"
|
|
local create_remote_user_repos=false
|
|
local long_opts="create-remote-user-repos"
|
|
local refspec=()
|
|
long_opts="$long_opts,refspec:"
|
|
local login="$whoami"
|
|
[ "$cmd_login" ] && login="$cmd_login"
|
|
|
|
local opts
|
|
opts=$(getopt -o C --long "$long_opts" -n clone -- "$@") || fatal "Failed to parse options $@"
|
|
eval set -- "$opts"
|
|
while [ "$1" != -- ]; do
|
|
case "$1" in
|
|
-C | --create-remote-user-repos)
|
|
create_remote_user_repos=true
|
|
;;
|
|
--refspec)
|
|
refspec=(${2//:/ })
|
|
shift
|
|
;;
|
|
*)
|
|
fatal "Unknown option $1"
|
|
;;
|
|
|
|
esac
|
|
shift
|
|
done
|
|
|
|
local fromuser="${refspec[0]}"
|
|
local fromref="${refspec[1]}"
|
|
local toref="${refspec[2]}"
|
|
[ "$fromuser" ] || fromuser=$whoami
|
|
[ "$fromref" ] || fromref=master
|
|
local git_srv_admin="$SSH $login@git.janware.com /opt/jw-pkg/bin/git-srv-admin.sh"
|
|
|
|
if [ -z "$projects" ]; then
|
|
projects=`$jw_projects projects list-repos --from-user $fromuser $remote_base`
|
|
[ "$?" != 0 ] && exit 1
|
|
fi
|
|
|
|
if [ "$login" ]; then
|
|
[ "${remote_base/@/}" = "${remote_base}" ] || fatal "Specified both --login $login and user in URL $remote_base"
|
|
remote_base=$(echo $remote_base | sed "s|://|://$login@|")
|
|
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=$remote_base/$fromuser$remote_subpath/$p
|
|
local pushurl=$remote_base/$login$remote_subpath/$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
|
|
run_git -C $p submodule foreach --recursive 'git fetch --tags -f origin'
|
|
else
|
|
run_clone $remote_base/$fromuser$remote_subpath/$p $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
|
|
run_git -C $p submodule foreach --recursive 'git fetch --tags -f origin'
|
|
if [ "$toref" ]; then
|
|
run_git -C $p rebase --autostash $remotename/$fromref $toref
|
|
run_git -C $p merge --ff-only $remotename/$fromref $toref
|
|
fi
|
|
else
|
|
# set -x
|
|
run_clone $remote_base/$fromuser$remote_subpath/$p $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
|
|
if [ $create_remote_user_repos = true ]; then
|
|
$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
|
|
fi
|
|
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
|
|
|
|
cur=0
|
|
SSH=ssh
|
|
[ "$GIT_SSH" ] && SSH=$GIT_SSH
|
|
global_remote_base="ssh://git.janware.com/srv/git"
|
|
|
|
while [ "${1:0:1}" = - ]; do
|
|
case "$1" in
|
|
'--remote-base')
|
|
global_remote_base="$2"
|
|
shift
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Only janware.com ssh git supports subdirectories below users
|
|
if [[ "$global_remote_base" =~ git.janware.com ]]; then
|
|
global_remote_subpath="/proj"
|
|
else
|
|
global_remote_subpath=""
|
|
fi
|
|
|
|
cmd=$1
|
|
shift
|
|
|
|
while [ "${1:0:1}" = - ]; do
|
|
case $1 in
|
|
'--login')
|
|
cmd_login="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
case $cmd in
|
|
clone|diff|commit)
|
|
$cmd "$@"
|
|
;;
|
|
*)
|
|
run $cmd "$@"
|
|
;;
|
|
esac
|