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_rsa.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 "$devsite_url, then log in, create a \"New Issue\" on"
463 msg "the \"Support\" tracker in the \"Repository\" category where you"
464 msg "apply for access and paste the following output into the issue:"
466 msg "`cat ~/.ssh/id_rsa.pub`"
467 elif [ -f ~/.ssh/id_dsa.pub ]; then
469 msg "A key already exists and no new one will be generated. If you"
470 msg "already have done the procedure for getting your key approved, you"
471 msg "can skip the following paragraph and already use the repository."
473 msg "To get access, your key has to be approved first. For that, visit"
474 msg "$devsite_url, then log in, create a \"New Issue\" on"
475 msg "the \"Support\" tracker in the \"Repository\" category where you"
476 msg "apply for access and paste the following output into the issue:"
478 msg "`cat ~/.ssh/id_dsa.pub`"
481 msg "No key has been generated yet. One will be generated now."
482 msg "If other people are using your computer, it is recommended"
483 msg "to specify a passphrase. Otherwise you can simply hit ENTER"
484 msg "when asked for a passphrase."
486 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
488 msg "To get access, your key has to be approved first. For that, visit"
489 msg "$devsite_url, then log in, create a \"New Issue\" on"
490 msg "the \"Support\" tracker in the \"Repository\" category where you"
491 msg "apply for access and paste the following output into the issue:"
493 msg "`cat ~/.ssh/id_rsa.pub`"
496 msg "Note that you will only have write access to branches that start"
497 msg "with your user name."
499 msg "Once you have gotten access, run ./all update -p"
503 need_bestmirror=false
509 case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
516 newprotocol="git http"
521 newprotocol= # same protocol
527 if $need_bestmirror; then
531 if [ x"$base" = x"$3" ]; then
535 allmirrors identifymirror_
538 msg "Current mirror not found = $base"
539 msg "but the last pull attempt failed."
541 msg "Use ./all update -l any to switch to the best mirror."
543 need_bestmirror=false
548 if [ x"$1" = x"-N" ]; then
550 elif [ x"$1" = x"-p" ]; then
553 elif [ x"$1" = x"-s" ]; then
556 elif [ x"$1" = x"-g" ]; then
559 elif [ x"$1" = x"-h" ]; then
562 elif [ x"$1" = x"-l" ]; then
572 if $need_bestmirror; then
573 newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
574 if [ -z "$newbase" ]; then
575 msg "Could not find any good mirror. Maybe try again later."
576 git config xonotic.all.mirrorselection try_all
579 if [ -n "$newpushprotocol" ]; then
580 if [ -n "$pushbase" ]; then
581 newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
583 newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
586 newpushbase=$pushbase
589 if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
591 pushbase=$newpushbase
595 if [ x"$d" = x"." ]; then
596 fix_git_config "$url" "$pushurl"
599 allrepos ifrepoenabled 0 seturl_
601 git config xonotic.all.mirrorselection done
609 if [ -f "$d0/$d/.git/config" ]; then
610 # if we have .no file, skip
611 if [ -f "$d0/$d.no" ]; then
612 msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
616 enter "$d0/$d" verbose
617 r=`git symbolic-ref HEAD`
619 if git config branch.$r.remote >/dev/null 2>&1; then
620 o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
621 ( cd "$d0" && git config xonotic.all.mirrorselection try_same )
622 if ! verbose git pull; then
623 if fix_upstream_rebase_mergefail; then
624 check_mergeconflict "$d"
625 $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
629 ( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
630 fix_upstream_rebase_mergeok || true
635 checkself "$cmd" "$@"
637 verbose git remote prune origin
641 if [ -d "$d0/$d" ]; then
642 if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
643 verbose rm -rf "$d0/$d"
645 echo "Note: $d0/$d will stay broken."
649 o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
650 git config xonotic.all.mirrorselection try_same
651 verbose git clone --branch "$branch" "$url" "$d0/$d"
652 git config xonotic.all.mirrorselection "$o"
653 enter "$d0/$d" verbose
654 fix_git_config "$url" "$pushurl"
658 allrepos ifrepoenabled 0 pull_
662 if [ x"$1" = x"-f" ]; then
668 if [ -z "$branch" ]; then
671 askbranch=${remote#origin/}
680 if [ -n "$checkoutflags" ]; then
681 set -- -f "$@" # to make checkself work again
687 enter "$d0/$d" verbose
689 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
691 verbose git checkout $checkoutflags "$b"
692 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
694 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
697 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
698 [ -n "$b" ] || exists=true
699 verbose git checkout $checkoutflags "$b"
700 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
701 [ -n "$b" ] || exists=true
702 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
704 $ECHO "WTF? Not even branch $b doesn't exist in $d"
709 checkself "$cmd" "$@"
712 allrepos ifrepoenabled 0 checkout_
714 $ECHO "The requested branch was not found in any repository."
722 if [ -z "$askbranch" ]; then
730 r=`git symbolic-ref HEAD`
732 dv=`visible_repo_name "$d"`
736 if [ -n "$askbranch" ]; then
740 dv=`visible_repo_name "$d"`
741 enter "$d0/$d" verbose
742 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
743 $ECHO "Already having this branch in $dv."
745 if yesno "Branch in $dv?"; then
746 if [ -n "$srcbranch" ]; then
750 verbose git fetch origin || true
752 verbose git checkout -b "$askbranch" "$b"
753 verbose git config "branch.$askbranch.remote" "$remote"
754 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
759 allrepos ifrepoenabled 0 branch_
761 allrepos ifrepoenabled 0 branch_show_
768 dv=`visible_repo_name "$d"`
769 enter "$d0/$d" verbose
770 r=`git symbolic-ref HEAD`
772 diffdata=`git diff --color HEAD`
773 if [ -n "$diffdata" ]; then
774 # we have uncommitted changes
775 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
776 verbose git commit -a
779 rem=`git config "branch.$r.remote" || $ECHO origin`
780 bra=`git config "branch.$r.merge" || $ECHO "$r"`
781 upstream="$rem/${bra#refs/heads/}"
782 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
783 upstream="origin/$branch"
785 logdata=`git log --color "$upstream".."$r"`
786 if [ -n "$logdata" ]; then
787 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
788 verbose git push "$rem" HEAD
791 if [ x"$submit" = x"-s" ]; then
794 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
800 allrepos ifrepoenabled 0 push_
804 if [ x"$1" = x"-k" ]; then
809 if verbose cd "$d0/$d"; then
829 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
830 # ./all clean --reclone
833 if [ x"$X" = x"--reclone" ]; then
840 elif [ x"$X" = x"-f" ]; then
842 elif [ x"$X" = x"-u" ]; then
844 elif [ x"$X" = x"-U" ]; then
847 elif [ x"$X" = x"-fu" ]; then
850 elif [ x"$X" = x"-fU" ]; then
854 elif [ x"$X" = x"-m" ]; then
856 elif [ x"$X" = x"-r" ]; then
858 elif [ x"$X" = x"-D" ]; then
860 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
863 msg " ,--'-\\P/\`\\ FFFFFFF"
864 msg " __/_ B/,-.\\ FFFFFFF"
865 msg " / _\\ (// O\\\\ FFFFFF"
866 msg "| (O \`) _\\._ _)\\ FFFUU"
867 msg "| |___/.^d0~~\"\\ \\ UUUU"
868 msg "| |\`~' \\ | UUUU"
869 msg "| | __,C>|| UUUU"
870 msg "\\ /_ ,-/,-' | UUUU"
871 msg " \\\\_ \\_>~' / UUUU-"
874 msg "Unknown arg: $X"
885 if $gotoupstream; then
887 msg "Must also use -f (delete local changes) when using -u"
891 if $fetchupstream; then
892 verbose git fetch origin
893 verbose git remote prune origin
895 verbose git checkout -f "$branch"
896 verbose git reset --hard origin/"$branch"
898 r=`git symbolic-ref HEAD`
900 rem=`git config "branch.$r.remote" || $ECHO origin`
901 bra=`git config "branch.$r.merge" || $ECHO "$r"`
902 upstream="$rem/${bra#refs/heads/}"
903 if $fetchupstream; then
904 for t in `git tag -l "xonotic-v"*`; do
905 verbose git tag -d "$t"
907 verbose git fetch "$rem"
908 verbose git remote prune "$rem"
910 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
911 upstream="origin/$branch"
913 verbose git reset --hard "$upstream"
915 elif $gotomaster; then
917 verbose git checkout -f "$branch"
918 verbose git reset --hard
920 verbose git checkout "$branch"
923 verbose git reset --hard
925 if $rmuntracked; then
928 verbose git clean -df || true
931 verbose git clean -xdf || true
935 if $killbranches; then
936 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
937 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
938 verbose git branch -D "${B#refs/heads/}"
941 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
942 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
944 checkself "$cmd" "$@"
946 allrepos ifrepoenabled 0 clean_
949 $ECHO " $SELF branch <branch>"
950 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
951 $ECHO " $SELF checkout|switch <branch>"
952 $ECHO " $SELF checkout|switch <remote>/<branch>"
953 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
954 $ECHO " $SELF clean --reclone"
955 $ECHO " $SELF each|foreach [-k] command..."
956 $ECHO " $SELF fix_upstream_rebase"
957 $ECHO " $SELF keygen"
958 $ECHO " $SELF push|commit [-s]"
959 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
960 $ECHO " $SELF grep \"<regex>\""
965 if verbose cd "$d0/$d"; then
966 git grep -In "$@" || true