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
63 # now actually time it
66 export REPO="$1" # so that the sh -c subshell can use it
67 { 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
68 # unit: clock ticks (depends on what "time" returns
79 bestmirror_firstrepo()
81 if [ -z "$testrepo" ]; then
85 allrepos bestmirror_firstrepo
88 if [ x"$oldurl" = x"$3" ]; then
93 allmirrors bestmirror_findold
95 if [ -z "$newprotocol" ]; then
96 newprotocol=$oldprotocol
98 if [ -z "$newlocation" ]; then
99 newlocation=$oldlocation
106 bestmirror_benchmark()
114 if [ -z "$bmb_loc" ]; then
115 # empty location is not allowed
118 case " $newprotocol " in
120 # no protocol requested? all match
129 # prefer location match
130 case " $newlocation " in
132 # bmb_curloc is true in first run, false in second
133 # so first run gets all matching locations
134 # so second run gets all non-matching locations
135 if ! $bmb_curloc; then
143 case " $newlocation " in
152 case " $newlocation " in
157 case " $newlocation " in
165 msg "Testing speed of $bmb_url..."
167 # only working mirrors
168 if ! thistime=`mirrorspeed "$bmb_url$testrepo"`; then
172 thistime=$(($thistime $bmb_fudge))
175 # anything is better than nothing
176 if [ -z "$besttime" ]; then
178 bestlocation=$bmb_loc
184 # prefer location match
185 case " $newlocation " in
187 case " $newlocation " in
194 bestlocation=$bmb_loc
202 # if newlocation matches bestlocation, then we already discarded it above
206 # if we get here, we must compare mirror speed as we have more than one match
207 if [ $thistime -gt $besttime ]; then
209 elif [ $thistime -lt $besttime ]; then
211 bestlocation=$bmb_loc
216 # both location and time match. Random decision.
217 bestcount=$(($bestcount + 1))
218 if [ $((($RANDOM + 0) % $bestcount)) -eq 0 ]; then
220 bestlocation=$bmb_loc
223 allmirrors bestmirror_benchmark true
224 allmirrors bestmirror_benchmark false
230 [ x"$1" = x"$3" ] || return
241 allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
248 # if we have .no file, skip
249 if [ -f "$d.no" ]; then
250 msg "Repository $d disabled by a .no file, delete $d.no to enable"
253 # if .yes file exists, always keep it
254 if [ -f "$d.yes" ]; then
255 msg "Repository $d enabled by a .yes file"
259 # remove broken clones so they don't mess up stuff
260 if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
261 msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
265 # if we have the dir, always keep it
267 msg "Repository $d enabled because it already exists"
271 # if we have matching pk3, skip
272 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
273 msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
276 # if "no" flag is set, skip
277 if matchrepoflag "$f" no; then
278 msg "Repository $d disabled by default, create $d.yes to enable"
282 msg "Repository $d enabled by default"
288 $ECHO `allrepos listrepos_`
295 eval ire_test=\$$(($1 + 3))
303 check_mergeconflict() # overrides the one in ./all
305 if git ls-files -u | grep ' 1 '; then
307 $ECHO "MERGE CONFLICT."
308 $ECHO "change into the \"$1\" project directory, and then:"
309 $ECHO "- edit the files mentioned above with your favorite editor,"
310 $ECHO " and fix the conflicts (marked with <<<<<<< blocks)"
311 $ECHO "- for binary files, you can select the files using"
312 $ECHO " git checkout --ours or git checkout --theirs"
313 $ECHO "- when done with a file, 'git add' the file"
314 $ECHO "- when done, 'git commit'"
324 $ECHO "the root directory"
332 fix_upstream_rebase()
334 if [ -z "$r_me" ] || [ -z "$r_other" ]; then
338 # one of the two sides of the merge should be remote upstream, or all is fine
339 r_r=`git symbolic-ref HEAD`
340 r_r=${r_r#refs/heads/}
341 r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
342 r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
343 r_bra=${r_bra#refs/heads/}
344 if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
345 if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
350 r_base=`git merge-base "$r_me" "$r_other"`
352 # no merge-base? upstream did filter-branch
353 if [ -n "$r_base" ]; then
354 # otherwise, check if the two histories are "similar"
355 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
356 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
358 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
359 r_lc_me=`$ECHO "$r_l_me" | wc -l`
360 r_lc_other=`$ECHO "$r_l_other" | wc -l`
361 r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
362 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
364 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
365 if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
366 git reset --hard "$r_me"
376 fix_upstream_rebase_mergeok()
378 r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
379 r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
383 fix_upstream_rebase_mergefail()
385 r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
386 r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
392 if ! [ -f ".git/config" ]; then
393 $ECHO "Not a git repository. Bailing out to not cause damage."
396 verbose git config remote.origin.url "$1"
398 verbose git config remote.origin.pushurl "$2"
400 verbose git config --unset remote.origin.pushurl || true
402 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
403 if testrepoflag "$d" noautocrlf; then
404 verbose git config --unset core.autocrlf || true
406 verbose git config core.autocrlf input
408 if [ -z "`git config push.default || true`" ]; then
409 verbose git config push.default current # or is tracking better?
411 verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
412 verbose git config filter.mapclean.smudge "cat"
417 while [ $# -gt 4 ]; do
422 if [ -n "$pushbase" ]; then
423 pushurl="$pushbase$2"
434 fix_upstream_rebase_()
437 enter "$d0/$d" verbose
438 verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
440 allrepos ifrepoenabled 0 fix_upstream_rebase_
446 if [ -f "$d0/$d/.git/config" ]; then
448 fix_git_config "$url" "$pushurl"
452 allrepos ifrepoenabled 0 fix_config_
455 if [ -f ~/.ssh/id_ef25519.pub ]; then
457 msg "A key already exists and no new one will be generated. If you"
458 msg "already have done the procedure for getting your key approved, you"
459 msg "can skip the following paragraph and already use the repository."
461 msg "To get access, your key has to be approved first. For that, visit"
462 msg "$gitsite_url, then log in, enter the"
463 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
464 msg "to apply for access."
466 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
467 msg "and paste the following output:"
469 msg "`cat ~/.ssh/id_ef25519.pub`"
470 elif [ -f ~/.ssh/id_rsa.pub ]; then
472 msg "A key already exists and no new one will be generated. If you"
473 msg "already have done the procedure for getting your key approved, you"
474 msg "can skip the following paragraph and already use the repository."
476 msg "To get access, your key has to be approved first. For that, visit"
477 msg "$gitsite_url, then log in, enter the"
478 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
479 msg "to apply for access."
481 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
482 msg "and paste the following output:"
484 msg "`cat ~/.ssh/id_rsa.pub`"
485 elif [ -f ~/.ssh/id_dsa.pub ]; then
487 msg "A key already exists and no new one will be generated. If you"
488 msg "already have done the procedure for getting your key approved, you"
489 msg "can skip the following paragraph and already use the repository."
491 msg "To get access, your key has to be approved first. For that, visit"
492 msg "$gitsite_url, then log in, enter the"
493 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
494 msg "to apply for access."
496 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
497 msg "and paste the following output:"
499 msg "`cat ~/.ssh/id_dsa.pub`"
502 msg "No key has been generated yet. One will be generated now."
503 msg "If other people are using your computer, it is recommended"
504 msg "to specify a passphrase. Otherwise you can simply hit ENTER"
505 msg "when asked for a passphrase."
507 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
509 msg "To get access, your key has to be approved first. For that, visit"
510 msg "$gitsite_url, then log in, enter the"
511 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
512 msg "to apply for access."
514 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
515 msg "and paste the following output:"
517 msg "`cat ~/.ssh/id_rsa.pub`"
520 msg "Note that you will only have write access to branches that start"
521 msg "with your user name."
523 msg "Once you have gotten access, run ./all update -p"
527 need_bestmirror=false
533 case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
540 newprotocol="git http"
545 newprotocol= # same protocol
551 if $need_bestmirror; then
555 if [ x"$base" = x"$3" ]; then
559 allmirrors identifymirror_
562 msg "Current mirror not found = $base"
563 msg "but the last pull attempt failed."
565 msg "Use ./all update -l any to switch to the best mirror."
567 need_bestmirror=false
572 if [ x"$1" = x"-N" ]; then
574 elif [ x"$1" = x"-p" ]; then
577 elif [ x"$1" = x"-s" ]; then
580 elif [ x"$1" = x"-g" ]; then
583 elif [ x"$1" = x"-h" ]; then
586 elif [ x"$1" = x"-l" ]; then
596 if $need_bestmirror; then
597 newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
598 if [ -z "$newbase" ]; then
599 msg "Could not find any good mirror. Maybe try again later."
600 git config xonotic.all.mirrorselection try_all
603 if [ -n "$newpushprotocol" ]; then
604 if [ -n "$pushbase" ]; then
605 newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
607 newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
610 newpushbase=$pushbase
613 if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
615 pushbase=$newpushbase
619 if [ x"$d" = x"." ]; then
620 fix_git_config "$url" "$pushurl"
623 allrepos ifrepoenabled 0 seturl_
625 git config xonotic.all.mirrorselection done
633 if [ -f "$d0/$d/.git/config" ]; then
634 # if we have .no file, skip
635 if [ -f "$d0/$d.no" ]; then
636 msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
640 enter "$d0/$d" verbose
641 r=`git symbolic-ref HEAD`
643 if git config branch.$r.remote >/dev/null 2>&1; then
644 o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
645 ( cd "$d0" && git config xonotic.all.mirrorselection try_same )
646 if ! verbose git pull; then
647 if fix_upstream_rebase_mergefail; then
648 check_mergeconflict "$d"
649 $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
653 ( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
654 fix_upstream_rebase_mergeok || true
659 checkself "$cmd" "$@"
661 verbose git remote prune origin
665 if [ -d "$d0/$d" ]; then
666 if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
667 verbose rm -rf "$d0/$d"
669 echo "Note: $d0/$d will stay broken."
673 o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
674 git config xonotic.all.mirrorselection try_same
675 verbose git clone --branch "$branch" "$url" "$d0/$d"
676 git config xonotic.all.mirrorselection "$o"
677 enter "$d0/$d" verbose
678 fix_git_config "$url" "$pushurl"
682 allrepos ifrepoenabled 0 pull_
686 if [ x"$1" = x"-f" ]; then
692 if [ -z "$branch" ]; then
695 askbranch=${remote#origin/}
704 if [ -n "$checkoutflags" ]; then
705 set -- -f "$@" # to make checkself work again
711 enter "$d0/$d" verbose
713 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
715 verbose git checkout $checkoutflags "$b"
716 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
718 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
721 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
722 [ -n "$b" ] || exists=true
723 verbose git checkout $checkoutflags "$b"
724 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
725 [ -n "$b" ] || exists=true
726 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
728 $ECHO "WTF? Not even branch $b doesn't exist in $d"
733 checkself "$cmd" "$@"
736 allrepos ifrepoenabled 0 checkout_
738 $ECHO "The requested branch was not found in any repository."
746 if [ -z "$askbranch" ]; then
754 r=`git symbolic-ref HEAD`
756 dv=`visible_repo_name "$d"`
760 if [ -n "$askbranch" ]; then
764 dv=`visible_repo_name "$d"`
765 enter "$d0/$d" verbose
766 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
767 $ECHO "Already having this branch in $dv."
769 if yesno "Branch in $dv?"; then
770 if [ -n "$srcbranch" ]; then
774 verbose git fetch origin || true
776 verbose git checkout -b "$askbranch" "$b"
777 verbose git config "branch.$askbranch.remote" "$remote"
778 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
783 allrepos ifrepoenabled 0 branch_
785 allrepos ifrepoenabled 0 branch_show_
792 dv=`visible_repo_name "$d"`
793 enter "$d0/$d" verbose
794 r=`git symbolic-ref HEAD`
796 diffdata=`git diff --color HEAD`
797 if [ -n "$diffdata" ]; then
798 # we have uncommitted changes
799 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
800 verbose git commit -a
803 rem=`git config "branch.$r.remote" || $ECHO origin`
804 bra=`git config "branch.$r.merge" || $ECHO "$r"`
805 upstream="$rem/${bra#refs/heads/}"
806 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
807 upstream="origin/$branch"
809 logdata=`git log --color "$upstream".."$r"`
810 if [ -n "$logdata" ]; then
811 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
812 verbose git push "$rem" HEAD
815 if [ x"$submit" = x"-s" ]; then
818 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
824 allrepos ifrepoenabled 0 push_
828 if [ x"$1" = x"-k" ]; then
833 if verbose cd "$d0/$d"; then
853 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
854 # ./all clean --reclone
857 if [ x"$X" = x"--reclone" ]; then
864 elif [ x"$X" = x"-f" ]; then
866 elif [ x"$X" = x"-u" ]; then
868 elif [ x"$X" = x"-U" ]; then
871 elif [ x"$X" = x"-fu" ]; then
874 elif [ x"$X" = x"-fU" ]; then
878 elif [ x"$X" = x"-m" ]; then
880 elif [ x"$X" = x"-r" ]; then
882 elif [ x"$X" = x"-D" ]; then
884 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
887 msg " ,--'-\\P/\`\\ FFFFFFF"
888 msg " __/_ B/,-.\\ FFFFFFF"
889 msg " / _\\ (// O\\\\ FFFFFF"
890 msg "| (O \`) _\\._ _)\\ FFFUU"
891 msg "| |___/.^d0~~\"\\ \\ UUUU"
892 msg "| |\`~' \\ | UUUU"
893 msg "| | __,C>|| UUUU"
894 msg "\\ /_ ,-/,-' | UUUU"
895 msg " \\\\_ \\_>~' / UUUU-"
898 msg "Unknown arg: $X"
909 if $gotoupstream; then
911 msg "Must also use -f (delete local changes) when using -u"
915 if $fetchupstream; then
916 verbose git fetch origin
917 verbose git remote prune origin
919 verbose git checkout -f "$branch"
920 verbose git reset --hard origin/"$branch"
922 r=`git symbolic-ref HEAD`
924 rem=`git config "branch.$r.remote" || $ECHO origin`
925 bra=`git config "branch.$r.merge" || $ECHO "$r"`
926 upstream="$rem/${bra#refs/heads/}"
927 if $fetchupstream; then
928 for t in `git tag -l "xonotic-v"*`; do
929 verbose git tag -d "$t"
931 verbose git fetch "$rem"
932 verbose git remote prune "$rem"
934 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
935 upstream="origin/$branch"
937 verbose git reset --hard "$upstream"
939 elif $gotomaster; then
941 verbose git checkout -f "$branch"
942 verbose git reset --hard
944 verbose git checkout "$branch"
947 verbose git reset --hard
949 if $rmuntracked; then
952 verbose git clean -df || true
955 verbose git clean -xdf || true
959 if $killbranches; then
960 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
961 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
962 verbose git branch -D "${B#refs/heads/}"
965 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
966 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
968 checkself "$cmd" "$@"
970 allrepos ifrepoenabled 0 clean_
973 $ECHO " $SELF branch <branch>"
974 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
975 $ECHO " $SELF checkout|switch <branch>"
976 $ECHO " $SELF checkout|switch <remote>/<branch>"
977 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
978 $ECHO " $SELF clean --reclone"
979 $ECHO " $SELF each|foreach [-k] command..."
980 $ECHO " $SELF fix_upstream_rebase"
981 $ECHO " $SELF keygen"
982 $ECHO " $SELF push|commit [-s]"
983 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
984 $ECHO " $SELF grep \"<regex>\""
989 if verbose cd "$d0/$d"; then
990 git grep -In "$@" || true