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 sh -c 'true'; } >/dev/null 2>&1; then
63 # now actually time it
66 export REPO=$1 # so that the sh -c subshell can use it
67 { time -p 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 "$url" "$d0/$d"
652 git config xonotic.all.mirrorselection "$o"
653 enter "$d0/$d" verbose
654 fix_git_config "$url" "$pushurl"
655 if [ "$branch" != "master" ]; then
656 verbose git checkout --track -b "$branch" origin/"$branch"
661 allrepos ifrepoenabled 0 pull_
665 if [ x"$1" = x"-f" ]; then
671 if [ -z "$branch" ]; then
674 askbranch=${remote#origin/}
683 if [ -n "$checkoutflags" ]; then
684 set -- -f "$@" # to make checkself work again
690 enter "$d0/$d" verbose
692 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
694 verbose git checkout $checkoutflags "$b"
695 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
697 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
700 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
701 [ -n "$b" ] || exists=true
702 verbose git checkout $checkoutflags "$b"
703 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
704 [ -n "$b" ] || exists=true
705 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
707 $ECHO "WTF? Not even branch $b doesn't exist in $d"
712 checkself "$cmd" "$@"
715 allrepos ifrepoenabled 0 checkout_
717 $ECHO "The requested branch was not found in any repository."
725 if [ -z "$askbranch" ]; then
733 r=`git symbolic-ref HEAD`
735 dv=`visible_repo_name "$d"`
739 if [ -n "$askbranch" ]; then
743 dv=`visible_repo_name "$d"`
744 enter "$d0/$d" verbose
745 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
746 $ECHO "Already having this branch in $dv."
748 if yesno "Branch in $dv?"; then
749 if [ -n "$srcbranch" ]; then
753 verbose git fetch origin || true
755 verbose git checkout -b "$askbranch" "$b"
756 verbose git config "branch.$askbranch.remote" "$remote"
757 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
762 allrepos ifrepoenabled 0 branch_
764 allrepos ifrepoenabled 0 branch_show_
771 dv=`visible_repo_name "$d"`
772 enter "$d0/$d" verbose
773 r=`git symbolic-ref HEAD`
775 diffdata=`git diff --color HEAD`
776 if [ -n "$diffdata" ]; then
777 # we have uncommitted changes
778 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
779 verbose git commit -a
782 rem=`git config "branch.$r.remote" || $ECHO origin`
783 bra=`git config "branch.$r.merge" || $ECHO "$r"`
784 upstream="$rem/${bra#refs/heads/}"
785 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
786 upstream="origin/$branch"
788 logdata=`git log --color "$upstream".."$r"`
789 if [ -n "$logdata" ]; then
790 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
791 verbose git push "$rem" HEAD
794 if [ x"$submit" = x"-s" ]; then
797 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
803 allrepos ifrepoenabled 0 push_
807 if [ x"$1" = x"-k" ]; then
812 if verbose cd "$d0/$d"; then
832 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
833 # ./all clean --reclone
836 if [ x"$X" = x"--reclone" ]; then
843 elif [ x"$X" = x"-f" ]; then
845 elif [ x"$X" = x"-u" ]; then
847 elif [ x"$X" = x"-U" ]; then
850 elif [ x"$X" = x"-fu" ]; then
853 elif [ x"$X" = x"-fU" ]; then
857 elif [ x"$X" = x"-m" ]; then
859 elif [ x"$X" = x"-r" ]; then
861 elif [ x"$X" = x"-D" ]; then
863 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
866 msg " ,--'-\\P/\`\\ FFFFFFF"
867 msg " __/_ B/,-.\\ FFFFFFF"
868 msg " / _\\ (// O\\\\ FFFFFF"
869 msg "| (O \`) _\\._ _)\\ FFFUU"
870 msg "| |___/.^d0~~\"\\ \\ UUUU"
871 msg "| |\`~' \\ | UUUU"
872 msg "| | __,C>|| UUUU"
873 msg "\\ /_ ,-/,-' | UUUU"
874 msg " \\\\_ \\_>~' / UUUU-"
877 msg "Unknown arg: $X"
888 if $gotoupstream; then
890 msg "Must also use -f (delete local changes) when using -u"
894 if $fetchupstream; then
895 verbose git fetch origin
896 verbose git remote prune origin
898 verbose git checkout -f "$branch"
899 verbose git reset --hard origin/"$branch"
901 r=`git symbolic-ref HEAD`
903 rem=`git config "branch.$r.remote" || $ECHO origin`
904 bra=`git config "branch.$r.merge" || $ECHO "$r"`
905 upstream="$rem/${bra#refs/heads/}"
906 if $fetchupstream; then
907 for t in `git tag -l "xonotic-v"*`; do
908 verbose git tag -d "$t"
910 verbose git fetch "$rem"
911 verbose git remote prune "$rem"
913 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
914 upstream="origin/$branch"
916 verbose git reset --hard "$upstream"
918 elif $gotomaster; then
920 verbose git checkout -f "$branch"
921 verbose git reset --hard
923 verbose git checkout "$branch"
926 verbose git reset --hard
928 if $rmuntracked; then
931 verbose git clean -df || true
934 verbose git clean -xdf || true
938 if $killbranches; then
939 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
940 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
941 verbose git branch -D "${B#refs/heads/}"
944 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
945 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
947 checkself "$cmd" "$@"
949 allrepos ifrepoenabled 0 clean_
952 $ECHO " $SELF branch <branch>"
953 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
954 $ECHO " $SELF checkout|switch <branch>"
955 $ECHO " $SELF checkout|switch <remote>/<branch>"
956 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
957 $ECHO " $SELF clean --reclone"
958 $ECHO " $SELF each|foreach [-k] command..."
959 $ECHO " $SELF fix_upstream_rebase"
960 $ECHO " $SELF keygen"
961 $ECHO " $SELF push|commit [-s]"
962 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
963 $ECHO " $SELF grep \"<regex>\""
968 if verbose cd "$d0/$d"; then
969 git grep -In "$@" || true