3 if [ x"$3" != x"." ]; then
21 allrepos initrepo_ "`git config remote.origin.url`" "`git config remote.origin.pushurl`"
22 if [ -z "$base" ]; then
23 msg "The main repo is not xonotic.git, what have you done?"
26 msg "Found main repo = $base"
27 if [ -n "$pushbase" ]; then
28 msg "Found push repo = $pushbase"
44 [ x"$1" = x"$3" ] || return
45 if matchrepoflag "$6" "$2"; then
51 allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
56 # first result is to be ignored, but we use it to check status
57 git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
58 # if we can't time, we only check availability
59 if ! { time -p true; } >/dev/null 2>&1; then
63 # now actually time it
66 { time -p git ls-remote "$1" refs/heads/master; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,' | grep . || echo 0
67 # unit: clock ticks (depends on what "time" returns
78 bestmirror_firstrepo()
80 if [ -z "$testrepo" ]; then
84 allrepos bestmirror_firstrepo
87 if [ x"$oldurl" = x"$3" ]; then
92 allmirrors bestmirror_findold
94 if [ -z "$newprotocol" ]; then
95 newprotocol=$oldprotocol
97 if [ -z "$newlocation" ]; then
98 newlocation=$oldlocation
105 bestmirror_benchmark()
113 if [ -z "$bmb_loc" ]; then
114 # empty location is not allowed
117 case " $newprotocol " in
119 # no protocol requested? all match
128 # prefer location match
129 case " $newlocation " in
131 # bmb_curloc is true in first run, false in second
132 # so first run gets all matching locations
133 # so second run gets all non-matching locations
134 if ! $bmb_curloc; then
142 case " $newlocation " in
151 case " $newlocation " in
156 case " $newlocation " in
164 msg "Testing speed of $bmb_url..."
166 # only working mirrors
167 if ! thistime=`mirrorspeed "$bmb_url$testrepo"`; then
171 thistime=$(($thistime $bmb_fudge))
174 # anything is better than nothing
175 if [ -z "$besttime" ]; then
177 bestlocation=$bmb_loc
183 # prefer location match
184 case " $newlocation " in
186 case " $newlocation " in
193 bestlocation=$bmb_loc
201 # if newlocation matches bestlocation, then we already discarded it above
205 # if we get here, we must compare mirror speed as we have more than one match
206 if [ $thistime -gt $besttime ]; then
208 elif [ $thistime -lt $besttime ]; then
210 bestlocation=$bmb_loc
215 # both location and time match. Random decision.
216 bestcount=$(($bestcount + 1))
217 if [ $((($RANDOM + 0) % $bestcount)) -eq 0 ]; then
219 bestlocation=$bmb_loc
222 allmirrors bestmirror_benchmark true
223 allmirrors bestmirror_benchmark false
229 [ x"$1" = x"$3" ] || return
240 allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
247 # if we have .no file, skip
248 if [ -f "$d.no" ]; then
249 msg "Repository $d disabled by a .no file, delete $d.no to enable"
252 # if .yes file exists, always keep it
253 if [ -f "$d.yes" ]; then
254 msg "Repository $d enabled by a .yes file"
258 # remove broken clones so they don't mess up stuff
259 if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
260 msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
264 # if we have the dir, always keep it
266 msg "Repository $d enabled because it already exists"
270 # if we have matching pk3, skip
271 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
272 msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
275 # if "no" flag is set, skip
276 if matchrepoflag "$f" no; then
277 msg "Repository $d disabled by default, create $d.yes to enable"
281 msg "Repository $d enabled by default"
287 $ECHO `allrepos listrepos_`
294 eval ire_test=\$$(($1 + 3))
302 check_mergeconflict() # overrides the one in ./all
304 if git ls-files -u | grep ' 1 '; then
306 $ECHO "MERGE CONFLICT."
307 $ECHO "change into the \"$1\" project directory, and then:"
308 $ECHO "- edit the files mentioned above with your favorite editor,"
309 $ECHO " and fix the conflicts (marked with <<<<<<< blocks)"
310 $ECHO "- for binary files, you can select the files using"
311 $ECHO " git checkout --ours or git checkout --theirs"
312 $ECHO "- when done with a file, 'git add' the file"
313 $ECHO "- when done, 'git commit'"
323 $ECHO "the root directory"
331 fix_upstream_rebase()
333 if [ -z "$r_me" ] || [ -z "$r_other" ]; then
337 # one of the two sides of the merge should be remote upstream, or all is fine
338 r_r=`git symbolic-ref HEAD`
339 r_r=${r_r#refs/heads/}
340 r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
341 r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
342 r_bra=${r_bra#refs/heads/}
343 if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
344 if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
349 r_base=`git merge-base "$r_me" "$r_other"`
351 # no merge-base? upstream did filter-branch
352 if [ -n "$r_base" ]; then
353 # otherwise, check if the two histories are "similar"
354 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
355 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
357 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
358 r_lc_me=`$ECHO "$r_l_me" | wc -l`
359 r_lc_other=`$ECHO "$r_l_other" | wc -l`
360 r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
361 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
363 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
364 if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
365 git reset --hard "$r_me"
375 fix_upstream_rebase_mergeok()
377 r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
378 r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
382 fix_upstream_rebase_mergefail()
384 r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
385 r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
391 if ! [ -f ".git/config" ]; then
392 $ECHO "Not a git repository. Bailing out to not cause damage."
395 verbose git config remote.origin.url "$1"
397 verbose git config remote.origin.pushurl "$2"
399 verbose git config --unset remote.origin.pushurl || true
401 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
402 if testrepoflag "$d" noautocrlf; then
403 verbose git config --unset core.autocrlf || true
405 verbose git config core.autocrlf input
407 if [ -z "`git config push.default || true`" ]; then
408 verbose git config push.default current # or is tracking better?
410 verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
411 verbose git config filter.mapclean.smudge "cat"
416 while [ $# -gt 4 ]; do
421 if [ -n "$pushbase" ]; then
422 pushurl="$pushbase$2"
433 fix_upstream_rebase_()
436 enter "$d0/$d" verbose
437 verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
439 allrepos ifrepoenabled 0 fix_upstream_rebase_
445 if [ -f "$d0/$d/.git/config" ]; then
447 fix_git_config "$url" "$pushurl"
451 allrepos ifrepoenabled 0 fix_config_
454 if [ -f ~/.ssh/id_rsa.pub ]; then
456 msg "A key already exists and no new one will be generated. If you"
457 msg "already have done the procedure for getting your key approved, you"
458 msg "can skip the following paragraph and already use the repository."
460 msg "To get access, your key has to be approved first. For that, visit"
461 msg "$devsite_url, then log in, create a \"New Issue\" on"
462 msg "the \"Support\" tracker in the \"Repository\" category where you"
463 msg "apply for access and paste the following output into the issue:"
465 msg "`cat ~/.ssh/id_rsa.pub`"
466 elif [ -f ~/.ssh/id_dsa.pub ]; then
468 msg "A key already exists and no new one will be generated. If you"
469 msg "already have done the procedure for getting your key approved, you"
470 msg "can skip the following paragraph and already use the repository."
472 msg "To get access, your key has to be approved first. For that, visit"
473 msg "$devsite_url, then log in, create a \"New Issue\" on"
474 msg "the \"Support\" tracker in the \"Repository\" category where you"
475 msg "apply for access and paste the following output into the issue:"
477 msg "`cat ~/.ssh/id_dsa.pub`"
480 msg "No key has been generated yet. One will be generated now."
481 msg "If other people are using your computer, it is recommended"
482 msg "to specify a passphrase. Otherwise you can simply hit ENTER"
483 msg "when asked for a passphrase."
485 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
487 msg "To get access, your key has to be approved first. For that, visit"
488 msg "$devsite_url, then log in, create a \"New Issue\" on"
489 msg "the \"Support\" tracker in the \"Repository\" category where you"
490 msg "apply for access and paste the following output into the issue:"
492 msg "`cat ~/.ssh/id_rsa.pub`"
495 msg "Note that you will only have write access to branches that start"
496 msg "with your user name."
498 msg "Once you have gotten access, run ./all update -p"
502 need_bestmirror=false
508 case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
515 newprotocol="git http"
520 newprotocol= # same protocol
526 if $need_bestmirror; then
530 if [ x"$base" = x"$3" ]; then
534 allmirrors identifymirror_
537 msg "Current mirror not found = $base"
538 msg "but the last pull attempt failed."
540 msg "Use ./all update -l any to switch to the best mirror."
542 need_bestmirror=false
547 if [ x"$1" = x"-N" ]; then
549 elif [ x"$1" = x"-p" ]; then
552 elif [ x"$1" = x"-s" ]; then
555 elif [ x"$1" = x"-g" ]; then
558 elif [ x"$1" = x"-h" ]; then
561 elif [ x"$1" = x"-l" ]; then
571 if $need_bestmirror; then
572 newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
573 if [ -z "$newbase" ]; then
574 msg "Could not find any good mirror. Maybe try again later."
575 git config xonotic.all.mirrorselection try_all
578 if [ -n "$newpushprotocol" ]; then
579 if [ -n "$pushbase" ]; then
580 newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
582 newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
585 newpushbase=$pushbase
588 if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
590 pushbase=$newpushbase
594 if [ x"$d" = x"." ]; then
595 fix_git_config "$url" "$pushurl"
598 allrepos ifrepoenabled 0 seturl_
600 git config xonotic.all.mirrorselection done
608 if [ -f "$d0/$d/.git/config" ]; then
609 # if we have .no file, skip
610 if [ -f "$d0/$d.no" ]; then
611 msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
615 enter "$d0/$d" verbose
616 r=`git symbolic-ref HEAD`
618 if git config branch.$r.remote >/dev/null 2>&1; then
619 o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
620 ( cd "$d0" && git config xonotic.all.mirrorselection try_same )
621 if ! verbose git pull; then
622 fix_upstream_rebase_mergefail || true
623 check_mergeconflict "$d"
624 $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
627 ( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
628 fix_upstream_rebase_mergeok || true
633 checkself "$cmd" "$@"
635 verbose git remote prune origin
639 if [ -d "$d0/$d" ]; then
640 if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
641 verbose rm -rf "$d0/$d"
643 echo "Note: $d0/$d will stay broken."
647 o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
648 git config xonotic.all.mirrorselection try_same
649 verbose git clone "$url" "$d0/$d"
650 git config xonotic.all.mirrorselection "$o"
651 enter "$d0/$d" verbose
652 fix_git_config "$url" "$pushurl"
653 if [ "$branch" != "master" ]; then
654 verbose git checkout --track -b "$branch" origin/"$branch"
659 allrepos ifrepoenabled 0 pull_
663 if [ x"$1" = x"-f" ]; then
669 if [ -z "$branch" ]; then
672 askbranch=${remote#origin/}
681 if [ -n "$checkoutflags" ]; then
682 set -- -f "$@" # to make checkself work again
688 enter "$d0/$d" verbose
690 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
692 verbose git checkout $checkoutflags "$b"
693 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
695 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
698 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
699 verbose git checkout $checkoutflags "$b"
700 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
701 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
703 $ECHO "WTF? Not even branch $b doesn't exist in $d"
708 checkself "$cmd" "$@"
711 allrepos ifrepoenabled 0 checkout_
713 $ECHO "The requested branch was not found in any repository."
721 if [ -z "$askbranch" ]; then
729 r=`git symbolic-ref HEAD`
731 dv=`visible_repo_name "$d"`
735 if [ -n "$askbranch" ]; then
739 dv=`visible_repo_name "$d"`
740 enter "$d0/$d" verbose
741 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
742 $ECHO "Already having this branch in $dv."
744 if yesno "Branch in $dv?"; then
745 if [ -n "$srcbranch" ]; then
749 verbose git fetch origin || true
751 verbose git checkout -b "$askbranch" "$b"
752 verbose git config "branch.$askbranch.remote" "$remote"
753 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
758 allrepos ifrepoenabled 0 branch_
760 allrepos ifrepoenabled 0 branch_show_
767 dv=`visible_repo_name "$d"`
768 enter "$d0/$d" verbose
769 r=`git symbolic-ref HEAD`
771 diffdata=`git diff --color HEAD`
772 if [ -n "$diffdata" ]; then
773 # we have uncommitted changes
774 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
775 verbose git commit -a
778 rem=`git config "branch.$r.remote" || $ECHO origin`
779 bra=`git config "branch.$r.merge" || $ECHO "$r"`
780 upstream="$rem/${bra#refs/heads/}"
781 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
782 upstream="origin/$branch"
784 logdata=`git log --color "$upstream".."$r"`
785 if [ -n "$logdata" ]; then
786 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
787 verbose git push "$rem" HEAD
790 if [ x"$submit" = x"-s" ]; then
793 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
799 allrepos ifrepoenabled 0 push_
803 if [ x"$1" = x"-k" ]; then
808 if verbose cd "$d0/$d"; then
828 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
829 # ./all clean --reclone
832 if [ x"$X" = x"--reclone" ]; then
839 elif [ x"$X" = x"-f" ]; then
841 elif [ x"$X" = x"-u" ]; then
843 elif [ x"$X" = x"-U" ]; then
846 elif [ x"$X" = x"-fu" ]; then
849 elif [ x"$X" = x"-fU" ]; then
853 elif [ x"$X" = x"-m" ]; then
855 elif [ x"$X" = x"-r" ]; then
857 elif [ x"$X" = x"-D" ]; then
859 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
862 msg " ,--'-\\P/\`\\ FFFFFFF"
863 msg " __/_ B/,-.\\ FFFFFFF"
864 msg " / _\\ (// O\\\\ FFFFFF"
865 msg "| (O \`) _\\._ _)\\ FFFUU"
866 msg "| |___/.^d0~~\"\\ \\ UUUU"
867 msg "| |\`~' \\ | UUUU"
868 msg "| | __,C>|| UUUU"
869 msg "\\ /_ ,-/,-' | UUUU"
870 msg " \\\\_ \\_>~' / UUUU-"
873 msg "Unknown arg: $X"
884 if $gotoupstream; then
886 msg "Must also use -f (delete local changes) when using -u"
890 if $fetchupstream; then
891 verbose git fetch origin
892 verbose git remote prune origin
894 verbose git checkout -f "$branch"
895 verbose git reset --hard origin/"$branch"
897 r=`git symbolic-ref HEAD`
899 rem=`git config "branch.$r.remote" || $ECHO origin`
900 bra=`git config "branch.$r.merge" || $ECHO "$r"`
901 upstream="$rem/${bra#refs/heads/}"
902 if $fetchupstream; then
903 for t in `git tag -l "xonotic-v"*`; do
904 verbose git tag -d "$t"
906 verbose git fetch "$rem"
907 verbose git remote prune "$rem"
909 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
910 upstream="origin/$branch"
912 verbose git reset --hard "$upstream"
914 elif $gotomaster; then
916 verbose git checkout -f "$branch"
917 verbose git reset --hard
919 verbose git checkout "$branch"
922 verbose git reset --hard
924 if $rmuntracked; then
927 verbose git clean -df || true
930 verbose git clean -xdf || true
934 if $killbranches; then
935 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
936 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
937 verbose git branch -D "${B#refs/heads/}"
940 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
941 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
943 checkself "$cmd" "$@"
945 allrepos ifrepoenabled 0 clean_
948 $ECHO " $SELF branch <branch>"
949 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
950 $ECHO " $SELF checkout|switch <branch>"
951 $ECHO " $SELF checkout|switch <remote>/<branch>"
952 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
953 $ECHO " $SELF clean --reclone"
954 $ECHO " $SELF each|foreach [-k] command..."
955 $ECHO " $SELF fix_upstream_rebase"
956 $ECHO " $SELF keygen"
957 $ECHO " $SELF push|commit [-s]"
958 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"