mirror of
https://gitlab.com/xonotic/xonotic
synced 2025-02-20 20:46:52 +00:00
984 lines
23 KiB
Plaintext
984 lines
23 KiB
Plaintext
initrepo_()
|
|
{
|
|
if [ x"$3" != x"." ]; then
|
|
return
|
|
fi
|
|
case "$1" in
|
|
*$4)
|
|
base=${1%$4}
|
|
;;
|
|
esac
|
|
case "$2" in
|
|
*$4)
|
|
pushbase=${2%$4}
|
|
;;
|
|
esac
|
|
}
|
|
initrepo()
|
|
{
|
|
base=
|
|
pushbase=
|
|
allrepos initrepo_ "`git config remote.origin.url`" "`git config remote.origin.pushurl`"
|
|
if [ -z "$base" ]; then
|
|
msg "The main repo is not xonotic.git, what have you done?"
|
|
exit 1
|
|
fi
|
|
msg "Found main repo = $base"
|
|
if [ -n "$pushbase" ]; then
|
|
msg "Found push repo = $pushbase"
|
|
fi
|
|
}
|
|
matchrepoflag()
|
|
{
|
|
case ",$2," in
|
|
*",$1,"*)
|
|
return 0
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
testrepoflag_()
|
|
{
|
|
[ x"$1" = x"$3" ] || return
|
|
if matchrepoflag "$6" "$2"; then
|
|
echo 0
|
|
fi
|
|
}
|
|
testrepoflag()
|
|
{
|
|
allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
|
|
}
|
|
|
|
mirrorspeed()
|
|
{
|
|
# first result is to be ignored, but we use it to check status
|
|
git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
|
|
# if we can't time, we only check availability
|
|
if ! $have_time; then
|
|
echo 0
|
|
return
|
|
fi
|
|
# now actually time it
|
|
(
|
|
set +x
|
|
export REPO="$1" # so that the sh -c subshell can use it
|
|
{ measure_time sh -c 'git ls-remote "$REPO" refs/heads/master >/dev/null 2>&1'; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,' | grep . || echo 0
|
|
# unit: clock ticks (depends on what "time" returns
|
|
)
|
|
}
|
|
bestmirror()
|
|
{
|
|
oldurl="$1"
|
|
newprotocol="$2"
|
|
newlocation="$3"
|
|
oldprotocol=
|
|
oldlocation=
|
|
testrepo=
|
|
bestmirror_firstrepo()
|
|
{
|
|
if [ -z "$testrepo" ]; then
|
|
testrepo=$2
|
|
fi
|
|
}
|
|
allrepos bestmirror_firstrepo
|
|
bestmirror_findold()
|
|
{
|
|
if [ x"$oldurl" = x"$3" ]; then
|
|
oldprotocol=$1
|
|
oldlocation=$2
|
|
fi
|
|
}
|
|
allmirrors bestmirror_findold
|
|
|
|
if [ -z "$newprotocol" ]; then
|
|
newprotocol=$oldprotocol
|
|
fi
|
|
if [ -z "$newlocation" ]; then
|
|
newlocation=$oldlocation
|
|
fi
|
|
|
|
besturl=
|
|
bestlocation=
|
|
besttime=
|
|
bestcount=
|
|
bestmirror_benchmark()
|
|
{
|
|
bmb_curloc=$1
|
|
bmb_proto=$2
|
|
bmb_loc=$3
|
|
bmb_url=$4
|
|
bmb_fudge=$5
|
|
|
|
if [ -z "$bmb_loc" ]; then
|
|
# empty location is not allowed
|
|
return
|
|
fi
|
|
case " $newprotocol " in
|
|
*" "*)
|
|
# no protocol requested? all match
|
|
;;
|
|
*" $bmb_proto "*)
|
|
;;
|
|
*)
|
|
return
|
|
;;
|
|
esac
|
|
|
|
# prefer location match
|
|
case " $newlocation " in
|
|
*" $bmb_loc "*)
|
|
# bmb_curloc is true in first run, false in second
|
|
# so first run gets all matching locations
|
|
# so second run gets all non-matching locations
|
|
if ! $bmb_curloc; then
|
|
return
|
|
fi
|
|
;;
|
|
*)
|
|
if $bmb_curloc; then
|
|
return
|
|
fi
|
|
case " $newlocation " in
|
|
*" $bestlocation "*)
|
|
# worse
|
|
return
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
case " $newlocation " in
|
|
*" $bmb_loc "*)
|
|
# see below
|
|
;;
|
|
*)
|
|
case " $newlocation " in
|
|
*" $bestlocation "*)
|
|
# worse
|
|
return
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
msg "Testing speed of $bmb_url..."
|
|
|
|
# only working mirrors
|
|
if ! thistime=`mirrorspeed "$bmb_url$testrepo"`; then
|
|
msg "-> FAILED"
|
|
return
|
|
fi
|
|
thistime=$(($thistime $bmb_fudge))
|
|
msg "-> $thistime"
|
|
|
|
# anything is better than nothing
|
|
if [ -z "$besttime" ]; then
|
|
besturl=$bmb_url
|
|
bestlocation=$bmb_loc
|
|
besttime=$thistime
|
|
bestcount=1
|
|
return
|
|
fi
|
|
|
|
# prefer location match
|
|
case " $newlocation " in
|
|
*" $bmb_loc "*)
|
|
case " $newlocation " in
|
|
*" $bestlocation "*)
|
|
# equality
|
|
;;
|
|
*)
|
|
# better
|
|
besturl=$bmb_url
|
|
bestlocation=$bmb_loc
|
|
besttime=$thistime
|
|
bestcount=1
|
|
return
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
# if newlocation matches bestlocation, then we already discarded it above
|
|
;;
|
|
esac
|
|
|
|
# if we get here, we must compare mirror speed as we have more than one match
|
|
if [ $thistime -gt $besttime ]; then
|
|
return
|
|
elif [ $thistime -lt $besttime ]; then
|
|
besturl=$bmb_url
|
|
bestlocation=$bmb_loc
|
|
besttime=$thistime
|
|
bestcount=1
|
|
return
|
|
fi
|
|
# both location and time match. Random decision.
|
|
bestcount=$(($bestcount + 1))
|
|
if [ $((($RANDOM + 0) % $bestcount)) -eq 0 ]; then
|
|
besturl=$bmb_url
|
|
bestlocation=$bmb_loc
|
|
fi
|
|
}
|
|
allmirrors bestmirror_benchmark true
|
|
allmirrors bestmirror_benchmark false
|
|
echo "$besturl"
|
|
}
|
|
|
|
testrepoflag_()
|
|
{
|
|
[ x"$1" = x"$3" ] || return
|
|
case ",$6," in
|
|
*",$2,"*)
|
|
echo 0
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
}
|
|
testrepoflag()
|
|
{
|
|
allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
|
|
}
|
|
listrepos_()
|
|
{
|
|
d=$1
|
|
f=$4
|
|
p="${d%dir}"
|
|
# if we have .no file, skip
|
|
if [ -f "$d.no" ]; then
|
|
msg "Repository $d disabled by a .no file, delete $d.no to enable"
|
|
return
|
|
fi
|
|
# if .yes file exists, always keep it
|
|
if [ -f "$d.yes" ]; then
|
|
msg "Repository $d enabled by a .yes file"
|
|
$ECHO "$d"
|
|
return
|
|
fi
|
|
# remove broken clones so they don't mess up stuff
|
|
if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
|
|
msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
|
|
verbose rm -rf "$d"
|
|
return
|
|
fi
|
|
# if we have the dir, always keep it
|
|
if [ -d "$d" ]; then
|
|
msg "Repository $d enabled because it already exists"
|
|
$ECHO "$d"
|
|
return
|
|
fi
|
|
# if we have matching pk3, skip
|
|
if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
|
|
msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
|
|
return
|
|
fi
|
|
# if "no" flag is set, skip
|
|
if matchrepoflag "$f" no; then
|
|
msg "Repository $d disabled by default, create $d.yes to enable"
|
|
return
|
|
fi
|
|
# default: enable
|
|
msg "Repository $d enabled by default"
|
|
$ECHO "$d"
|
|
}
|
|
|
|
listrepos()
|
|
{
|
|
$ECHO `allrepos listrepos_`
|
|
}
|
|
initrepo
|
|
repos=`listrepos`
|
|
|
|
ifrepoenabled()
|
|
{
|
|
eval ire_test=\$$(($1 + 3))
|
|
shift
|
|
case " $repos " in
|
|
*" $ire_test "*)
|
|
"$@"
|
|
;;
|
|
esac
|
|
}
|
|
check_mergeconflict() # overrides the one in ./all
|
|
{
|
|
if git ls-files -u | grep ' 1 '; then
|
|
$ECHO
|
|
$ECHO "MERGE CONFLICT."
|
|
$ECHO "change into the \"$1\" project directory, and then:"
|
|
$ECHO "- edit the files mentioned above with your favorite editor,"
|
|
$ECHO " and fix the conflicts (marked with <<<<<<< blocks)"
|
|
$ECHO "- for binary files, you can select the files using"
|
|
$ECHO " git checkout --ours or git checkout --theirs"
|
|
$ECHO "- when done with a file, 'git add' the file"
|
|
$ECHO "- when done, 'git commit'"
|
|
$ECHO
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
visible_repo_name()
|
|
{
|
|
case "$1" in
|
|
.)
|
|
$ECHO "the root directory"
|
|
;;
|
|
*)
|
|
$ECHO "\"$1\""
|
|
;;
|
|
esac
|
|
}
|
|
|
|
fix_upstream_rebase()
|
|
{
|
|
if [ -z "$r_me" ] || [ -z "$r_other" ]; then
|
|
return
|
|
fi
|
|
|
|
# one of the two sides of the merge should be remote upstream, or all is fine
|
|
r_r=`git symbolic-ref HEAD`
|
|
r_r=${r_r#refs/heads/}
|
|
r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
|
|
r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
|
|
r_bra=${r_bra#refs/heads/}
|
|
if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
|
|
if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
|
|
return
|
|
fi
|
|
fi
|
|
|
|
r_base=`git merge-base "$r_me" "$r_other"`
|
|
|
|
# no merge-base? upstream did filter-branch
|
|
if [ -n "$r_base" ]; then
|
|
# otherwise, check if the two histories are "similar"
|
|
r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
|
|
r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
|
|
|
|
# heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
|
|
r_lc_me=`$ECHO "$r_l_me" | wc -l`
|
|
r_lc_other=`$ECHO "$r_l_other" | wc -l`
|
|
r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
|
|
r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
|
|
|
|
if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
|
|
if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
|
|
git reset --hard "$r_me"
|
|
git pull --rebase
|
|
return 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
fix_upstream_rebase_mergeok()
|
|
{
|
|
r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
|
|
r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
|
|
fix_upstream_rebase
|
|
}
|
|
|
|
fix_upstream_rebase_mergefail()
|
|
{
|
|
r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
|
|
r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
|
|
fix_upstream_rebase
|
|
}
|
|
|
|
fix_git_config()
|
|
{
|
|
if ! [ -f ".git/config" ]; then
|
|
$ECHO "Not a git repository. Bailing out to not cause damage."
|
|
exit 1
|
|
fi
|
|
verbose git config remote.origin.url "$1"
|
|
if [ -n "$2" ]; then
|
|
verbose git config remote.origin.pushurl "$2"
|
|
else
|
|
verbose git config --unset remote.origin.pushurl || true
|
|
fi
|
|
verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
|
if testrepoflag "$d" noautocrlf; then
|
|
verbose git config --unset core.autocrlf || true
|
|
else
|
|
verbose git config core.autocrlf input
|
|
fi
|
|
if [ -z "`git config push.default || true`" ]; then
|
|
verbose git config push.default current # or is tracking better?
|
|
fi
|
|
verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
|
|
verbose git config filter.mapclean.smudge "cat"
|
|
}
|
|
|
|
setrepovars()
|
|
{
|
|
while [ $# -gt 4 ]; do
|
|
shift
|
|
done
|
|
d=$1
|
|
url="$base$2"
|
|
if [ -n "$pushbase" ]; then
|
|
pushurl="$pushbase$2"
|
|
else
|
|
pushurl=
|
|
fi
|
|
branch=$3
|
|
f=$4
|
|
}
|
|
|
|
handled=true
|
|
case "$cmd" in
|
|
fix_upstream_rebase)
|
|
fix_upstream_rebase_()
|
|
{
|
|
setrepovars "$@"
|
|
enter "$d0/$d" verbose
|
|
verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
|
|
}
|
|
allrepos ifrepoenabled 0 fix_upstream_rebase_
|
|
;;
|
|
fix_config)
|
|
fix_config_()
|
|
{
|
|
setrepovars "$@"
|
|
if [ -f "$d0/$d/.git/config" ]; then
|
|
verbose cd "$d0/$d"
|
|
fix_git_config "$url" "$pushurl"
|
|
cd "$d0"
|
|
fi
|
|
}
|
|
allrepos ifrepoenabled 0 fix_config_
|
|
;;
|
|
keygen)
|
|
if [ -f ~/.ssh/id_rsa.pub ]; then
|
|
msg ""
|
|
msg "A key already exists and no new one will be generated. If you"
|
|
msg "already have done the procedure for getting your key approved, you"
|
|
msg "can skip the following paragraph and already use the repository."
|
|
msg ""
|
|
msg "To get access, your key has to be approved first. For that, visit"
|
|
msg "$gitsite_url, then log in, enter the"
|
|
msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
|
|
msg "to apply for access and paste the following output into the issue:"
|
|
msg ""
|
|
msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
|
|
msg "and paste the following output:"
|
|
msg ""
|
|
msg "`cat ~/.ssh/id_rsa.pub`"
|
|
elif [ -f ~/.ssh/id_dsa.pub ]; then
|
|
msg ""
|
|
msg "A key already exists and no new one will be generated. If you"
|
|
msg "already have done the procedure for getting your key approved, you"
|
|
msg "can skip the following paragraph and already use the repository."
|
|
msg ""
|
|
msg "To get access, your key has to be approved first. For that, visit"
|
|
msg "$gitsite_url, then log in, enter the"
|
|
msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
|
|
msg "to apply for access and paste the following output into the issue:"
|
|
msg ""
|
|
msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
|
|
msg "and paste the following output:"
|
|
msg ""
|
|
msg "`cat ~/.ssh/id_dsa.pub`"
|
|
else
|
|
msg ""
|
|
msg "No key has been generated yet. One will be generated now."
|
|
msg "If other people are using your computer, it is recommended"
|
|
msg "to specify a passphrase. Otherwise you can simply hit ENTER"
|
|
msg "when asked for a passphrase."
|
|
msg ""
|
|
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
|
|
msg ""
|
|
msg "To get access, your key has to be approved first. For that, visit"
|
|
msg "$gitsite_url, then log in, enter the"
|
|
msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
|
|
msg "to apply for access and paste the following output into the issue:"
|
|
msg ""
|
|
msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
|
|
msg "and paste the following output:"
|
|
msg ""
|
|
msg "`cat ~/.ssh/id_rsa.pub`"
|
|
fi
|
|
msg ""
|
|
msg "Note that you will only have write access to branches that start"
|
|
msg "with your user name."
|
|
msg
|
|
msg "Once you have gotten access, run ./all update -p"
|
|
;;
|
|
update|pull)
|
|
allow_pull=true
|
|
need_bestmirror=false
|
|
|
|
newprotocol=
|
|
newpushprotocol=
|
|
newlocation=
|
|
|
|
case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
|
|
done)
|
|
;;
|
|
try_same)
|
|
need_bestmirror=true
|
|
;;
|
|
try_all)
|
|
newprotocol="git http"
|
|
newlocation="any"
|
|
need_bestmirror=true
|
|
;;
|
|
*)
|
|
newprotocol= # same protocol
|
|
newlocation="any"
|
|
need_bestmirror=true
|
|
;;
|
|
esac
|
|
|
|
if $need_bestmirror; then
|
|
found=false
|
|
identifymirror_()
|
|
{
|
|
if [ x"$base" = x"$3" ]; then
|
|
found=true
|
|
fi
|
|
}
|
|
allmirrors identifymirror_
|
|
if ! $found; then
|
|
msg ""
|
|
msg "Current mirror not found = $base"
|
|
msg "but the last pull attempt failed."
|
|
msg ""
|
|
msg "Use ./all update -l any to switch to the best mirror."
|
|
msg ""
|
|
need_bestmirror=false
|
|
fi
|
|
fi
|
|
|
|
while :; do
|
|
if [ x"$1" = x"-N" ]; then
|
|
allow_pull=false
|
|
elif [ x"$1" = x"-p" ]; then
|
|
newpushprotocol=ssh
|
|
need_bestmirror=true
|
|
elif [ x"$1" = x"-s" ]; then
|
|
newprotocol=ssh
|
|
need_bestmirror=true
|
|
elif [ x"$1" = x"-g" ]; then
|
|
newprotocol=git
|
|
need_bestmirror=true
|
|
elif [ x"$1" = x"-h" ]; then
|
|
newprotocol=http
|
|
need_bestmirror=true
|
|
elif [ x"$1" = x"-l" ]; then
|
|
newlocation=$2
|
|
need_bestmirror=true
|
|
shift
|
|
else
|
|
break
|
|
fi
|
|
shift
|
|
done
|
|
|
|
if $need_bestmirror; then
|
|
newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
|
|
if [ -z "$newbase" ]; then
|
|
msg "Could not find any good mirror. Maybe try again later."
|
|
git config xonotic.all.mirrorselection try_all
|
|
exit 1
|
|
fi
|
|
if [ -n "$newpushprotocol" ]; then
|
|
if [ -n "$pushbase" ]; then
|
|
newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
|
|
else
|
|
newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
|
|
fi
|
|
else
|
|
newpushbase=$pushbase
|
|
fi
|
|
|
|
if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
|
|
base=$newbase
|
|
pushbase=$newpushbase
|
|
seturl_()
|
|
{
|
|
setrepovars "$@"
|
|
if [ x"$d" = x"." ]; then
|
|
fix_git_config "$url" "$pushurl"
|
|
fi
|
|
}
|
|
allrepos ifrepoenabled 0 seturl_
|
|
fi
|
|
git config xonotic.all.mirrorselection done
|
|
fi
|
|
|
|
"$SELF" fix_config
|
|
|
|
pull_()
|
|
{
|
|
setrepovars "$@"
|
|
if [ -f "$d0/$d/.git/config" ]; then
|
|
# if we have .no file, skip
|
|
if [ -f "$d0/$d.no" ]; then
|
|
msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
|
|
return
|
|
fi
|
|
if $allow_pull; then
|
|
enter "$d0/$d" verbose
|
|
r=`git symbolic-ref HEAD`
|
|
r=${r#refs/heads/}
|
|
if git config branch.$r.remote >/dev/null 2>&1; then
|
|
o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
|
|
( cd "$d0" && git config xonotic.all.mirrorselection try_same )
|
|
if ! verbose git pull; then
|
|
if fix_upstream_rebase_mergefail; then
|
|
check_mergeconflict "$d"
|
|
$ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
|
|
read -r DUMMY
|
|
fi
|
|
else
|
|
( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
|
|
fix_upstream_rebase_mergeok || true
|
|
fi
|
|
fi
|
|
|
|
cd "$d00"
|
|
checkself "$cmd" "$@"
|
|
cd "$d0/$d"
|
|
verbose git remote prune origin
|
|
cd "$d0"
|
|
fi
|
|
else
|
|
if [ -d "$d0/$d" ]; then
|
|
if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
|
|
verbose rm -rf "$d0/$d"
|
|
else
|
|
echo "Note: $d0/$d will stay broken."
|
|
return
|
|
fi
|
|
fi
|
|
o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
|
|
git config xonotic.all.mirrorselection try_same
|
|
verbose git clone --branch "$branch" "$url" "$d0/$d"
|
|
git config xonotic.all.mirrorselection "$o"
|
|
enter "$d0/$d" verbose
|
|
fix_git_config "$url" "$pushurl"
|
|
cd "$d0"
|
|
fi
|
|
}
|
|
allrepos ifrepoenabled 0 pull_
|
|
;;
|
|
checkout|switch)
|
|
checkoutflags=
|
|
if [ x"$1" = x"-f" ]; then
|
|
checkoutflags=-f
|
|
shift
|
|
fi
|
|
remote=$1
|
|
branch=$2
|
|
if [ -z "$branch" ]; then
|
|
case "$remote" in
|
|
origin/*)
|
|
askbranch=${remote#origin/}
|
|
remote=origin
|
|
;;
|
|
*)
|
|
askbranch=$remote
|
|
remote=origin
|
|
;;
|
|
esac
|
|
fi
|
|
if [ -n "$checkoutflags" ]; then
|
|
set -- -f "$@" # to make checkself work again
|
|
fi
|
|
exists=false
|
|
checkout_()
|
|
{
|
|
setrepovars "$@"
|
|
enter "$d0/$d" verbose
|
|
b=$askbranch
|
|
if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
|
|
exists=true
|
|
verbose git checkout $checkoutflags "$b"
|
|
elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
|
|
exists=true
|
|
verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
|
|
else
|
|
b=$branch
|
|
if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
|
|
[ -n "$b" ] || exists=true
|
|
verbose git checkout $checkoutflags "$b"
|
|
elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
|
|
[ -n "$b" ] || exists=true
|
|
verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
|
|
else
|
|
$ECHO "WTF? Not even branch $b doesn't exist in $d"
|
|
exit 1
|
|
fi
|
|
fi
|
|
cd "$d00"
|
|
checkself "$cmd" "$@"
|
|
cd "$d0"
|
|
}
|
|
allrepos ifrepoenabled 0 checkout_
|
|
if ! $exists; then
|
|
$ECHO "The requested branch was not found in any repository."
|
|
fi
|
|
exec "$SELF" branch
|
|
;;
|
|
branch)
|
|
remote=$1
|
|
askbranch=$2
|
|
srcbranch=$3
|
|
if [ -z "$askbranch" ]; then
|
|
askbranch=$remote
|
|
remote=origin
|
|
fi
|
|
branch_show_()
|
|
{
|
|
setrepovars "$@"
|
|
enter "$d0/$d"
|
|
r=`git symbolic-ref HEAD`
|
|
r=${r#refs/heads/}
|
|
dv=`visible_repo_name "$d"`
|
|
$ECHO "$dv is at $r"
|
|
cd "$d0"
|
|
}
|
|
if [ -n "$askbranch" ]; then
|
|
branch_()
|
|
{
|
|
setrepovars "$@"
|
|
dv=`visible_repo_name "$d"`
|
|
enter "$d0/$d" verbose
|
|
if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
|
|
$ECHO "Already having this branch in $dv."
|
|
else
|
|
if yesno "Branch in $dv?"; then
|
|
if [ -n "$srcbranch" ]; then
|
|
b=$srcbranch
|
|
else
|
|
b=$branch
|
|
verbose git fetch origin || true
|
|
fi
|
|
verbose git checkout -b "$askbranch" "$b"
|
|
verbose git config "branch.$askbranch.remote" "$remote"
|
|
verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
|
|
fi
|
|
fi
|
|
cd "$d0"
|
|
}
|
|
allrepos ifrepoenabled 0 branch_
|
|
fi
|
|
allrepos ifrepoenabled 0 branch_show_
|
|
;;
|
|
push|commit)
|
|
submit=$1
|
|
push_()
|
|
{
|
|
setrepovars "$@"
|
|
dv=`visible_repo_name "$d"`
|
|
enter "$d0/$d" verbose
|
|
r=`git symbolic-ref HEAD`
|
|
r=${r#refs/heads/}
|
|
diffdata=`git diff --color HEAD`
|
|
if [ -n "$diffdata" ]; then
|
|
# we have uncommitted changes
|
|
if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
|
|
verbose git commit -a
|
|
fi
|
|
fi
|
|
rem=`git config "branch.$r.remote" || $ECHO origin`
|
|
bra=`git config "branch.$r.merge" || $ECHO "$r"`
|
|
upstream="$rem/${bra#refs/heads/}"
|
|
if ! git rev-parse "$upstream" >/dev/null 2>&1; then
|
|
upstream="origin/$branch"
|
|
fi
|
|
logdata=`git log --color "$upstream".."$r"`
|
|
if [ -n "$logdata" ]; then
|
|
if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
|
|
verbose git push "$rem" HEAD
|
|
fi
|
|
fi
|
|
if [ x"$submit" = x"-s" ]; then
|
|
case "$r" in
|
|
*/*)
|
|
verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
|
|
;;
|
|
esac
|
|
fi
|
|
cd "$d0"
|
|
}
|
|
allrepos ifrepoenabled 0 push_
|
|
;;
|
|
each|foreach)
|
|
keep_going=false
|
|
if [ x"$1" = x"-k" ]; then
|
|
keep_going=true
|
|
shift
|
|
fi
|
|
for d in $repos; do
|
|
if verbose cd "$d0/$d"; then
|
|
if $keep_going; then
|
|
verbose "$@" || true
|
|
else
|
|
verbose "$@"
|
|
fi
|
|
cd "$d0"
|
|
fi
|
|
done
|
|
;;
|
|
clean)
|
|
"$SELF" fix_config
|
|
"$SELF" update -N
|
|
force=false
|
|
gotoupstream=false
|
|
fetchupstream=false
|
|
gotomaster=false
|
|
rmuntracked=false
|
|
killbranches=false
|
|
# usage:
|
|
# ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
|
|
# ./all clean --reclone
|
|
found=false
|
|
for X in "$@"; do
|
|
if [ x"$X" = x"--reclone" ]; then
|
|
force=true
|
|
fetchupstream=true
|
|
gotoupstream=true
|
|
gotomaster=true
|
|
rmuntracked=true
|
|
killbranches=true
|
|
elif [ x"$X" = x"-f" ]; then
|
|
force=true
|
|
elif [ x"$X" = x"-u" ]; then
|
|
gotoupstream=true
|
|
elif [ x"$X" = x"-U" ]; then
|
|
gotoupstream=true
|
|
fetchupstream=true
|
|
elif [ x"$X" = x"-fu" ]; then
|
|
force=true
|
|
gotoupstream=true
|
|
elif [ x"$X" = x"-fU" ]; then
|
|
force=true
|
|
gotoupstream=true
|
|
fetchupstream=true
|
|
elif [ x"$X" = x"-m" ]; then
|
|
gotomaster=true
|
|
elif [ x"$X" = x"-r" ]; then
|
|
rmuntracked=true
|
|
elif [ x"$X" = x"-D" ]; then
|
|
killbranches=true
|
|
elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
|
|
msg ''
|
|
msg " _____"
|
|
msg " ,--'-\\P/\`\\ FFFFFFF"
|
|
msg " __/_ B/,-.\\ FFFFFFF"
|
|
msg " / _\\ (// O\\\\ FFFFFF"
|
|
msg "| (O \`) _\\._ _)\\ FFFUU"
|
|
msg "| |___/.^d0~~\"\\ \\ UUUU"
|
|
msg "| |\`~' \\ | UUUU"
|
|
msg "| | __,C>|| UUUU"
|
|
msg "\\ /_ ,-/,-' | UUUU"
|
|
msg " \\\\_ \\_>~' / UUUU-"
|
|
msg ''
|
|
else
|
|
msg "Unknown arg: $X"
|
|
fi
|
|
found=true
|
|
done
|
|
if ! $found; then
|
|
rmuntracked=true
|
|
fi
|
|
clean_()
|
|
{
|
|
setrepovars "$@"
|
|
verbose cd "$d0/$d"
|
|
if $gotoupstream; then
|
|
if ! $force; then
|
|
msg "Must also use -f (delete local changes) when using -u"
|
|
exit 1
|
|
fi
|
|
if $gotomaster; then
|
|
if $fetchupstream; then
|
|
verbose git fetch origin
|
|
verbose git remote prune origin
|
|
fi
|
|
verbose git checkout -f "$branch"
|
|
verbose git reset --hard origin/"$branch"
|
|
else
|
|
r=`git symbolic-ref HEAD`
|
|
r=${r#refs/heads/}
|
|
rem=`git config "branch.$r.remote" || $ECHO origin`
|
|
bra=`git config "branch.$r.merge" || $ECHO "$r"`
|
|
upstream="$rem/${bra#refs/heads/}"
|
|
if $fetchupstream; then
|
|
for t in `git tag -l "xonotic-v"*`; do
|
|
verbose git tag -d "$t"
|
|
done
|
|
verbose git fetch "$rem"
|
|
verbose git remote prune "$rem"
|
|
fi
|
|
if ! git rev-parse "$upstream" >/dev/null 2>&1; then
|
|
upstream="origin/$branch"
|
|
fi
|
|
verbose git reset --hard "$upstream"
|
|
fi
|
|
elif $gotomaster; then
|
|
if $force; then
|
|
verbose git checkout -f "$branch"
|
|
verbose git reset --hard
|
|
else
|
|
verbose git checkout "$branch"
|
|
fi
|
|
elif $force; then
|
|
verbose git reset --hard
|
|
fi
|
|
if $rmuntracked; then
|
|
case "$d" in
|
|
.)
|
|
verbose git clean -df || true
|
|
;;
|
|
*)
|
|
verbose git clean -xdf || true
|
|
;;
|
|
esac
|
|
fi
|
|
if $killbranches; then
|
|
git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
|
|
if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
|
|
verbose git branch -D "${B#refs/heads/}"
|
|
fi
|
|
done
|
|
git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
|
|
git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
|
|
fi
|
|
checkself "$cmd" "$@"
|
|
}
|
|
allrepos ifrepoenabled 0 clean_
|
|
;;
|
|
help)
|
|
$ECHO " $SELF branch <branch>"
|
|
$ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
|
|
$ECHO " $SELF checkout|switch <branch>"
|
|
$ECHO " $SELF checkout|switch <remote>/<branch>"
|
|
$ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
|
|
$ECHO " $SELF clean --reclone"
|
|
$ECHO " $SELF each|foreach [-k] command..."
|
|
$ECHO " $SELF fix_upstream_rebase"
|
|
$ECHO " $SELF keygen"
|
|
$ECHO " $SELF push|commit [-s]"
|
|
$ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
|
|
$ECHO " $SELF grep \"<regex>\""
|
|
handled=false
|
|
;;
|
|
grep)
|
|
for d in $repos; do
|
|
if verbose cd "$d0/$d"; then
|
|
git grep -In "$@" || true
|
|
cd "$d0"
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
handled=false
|
|
;;
|
|
esac
|