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 "$gitsite_url, then log in, enter the"
463 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
464 msg "to apply for access and paste the following output into the issue:"
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_rsa.pub`"
470 elif [ -f ~/.ssh/id_dsa.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 and paste the following output into the issue:"
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_dsa.pub`"
487 msg "No key has been generated yet. One will be generated now."
488 msg "If other people are using your computer, it is recommended"
489 msg "to specify a passphrase. Otherwise you can simply hit ENTER"
490 msg "when asked for a passphrase."
492 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
494 msg "To get access, your key has to be approved first. For that, visit"
495 msg "$gitsite_url, then log in, enter the"
496 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
497 msg "to apply for access and paste the following output into the issue:"
499 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
500 msg "and paste the following output:"
502 msg "`cat ~/.ssh/id_rsa.pub`"
505 msg "Note that you will only have write access to branches that start"
506 msg "with your user name."
508 msg "Once you have gotten access, run ./all update -p"
512 need_bestmirror=false
518 case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
525 newprotocol="git http"
530 newprotocol= # same protocol
536 if $need_bestmirror; then
540 if [ x"$base" = x"$3" ]; then
544 allmirrors identifymirror_
547 msg "Current mirror not found = $base"
548 msg "but the last pull attempt failed."
550 msg "Use ./all update -l any to switch to the best mirror."
552 need_bestmirror=false
557 if [ x"$1" = x"-N" ]; then
559 elif [ x"$1" = x"-p" ]; then
562 elif [ x"$1" = x"-s" ]; then
565 elif [ x"$1" = x"-g" ]; then
568 elif [ x"$1" = x"-h" ]; then
571 elif [ x"$1" = x"-l" ]; then
581 if $need_bestmirror; then
582 newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
583 if [ -z "$newbase" ]; then
584 msg "Could not find any good mirror. Maybe try again later."
585 git config xonotic.all.mirrorselection try_all
588 if [ -n "$newpushprotocol" ]; then
589 if [ -n "$pushbase" ]; then
590 newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
592 newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
595 newpushbase=$pushbase
598 if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
600 pushbase=$newpushbase
604 if [ x"$d" = x"." ]; then
605 fix_git_config "$url" "$pushurl"
608 allrepos ifrepoenabled 0 seturl_
610 git config xonotic.all.mirrorselection done
618 if [ -f "$d0/$d/.git/config" ]; then
619 # if we have .no file, skip
620 if [ -f "$d0/$d.no" ]; then
621 msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
625 enter "$d0/$d" verbose
626 r=`git symbolic-ref HEAD`
628 if git config branch.$r.remote >/dev/null 2>&1; then
629 o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
630 ( cd "$d0" && git config xonotic.all.mirrorselection try_same )
631 if ! verbose git pull; then
632 if fix_upstream_rebase_mergefail; then
633 check_mergeconflict "$d"
634 $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
638 ( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
639 fix_upstream_rebase_mergeok || true
644 checkself "$cmd" "$@"
646 verbose git remote prune origin
650 if [ -d "$d0/$d" ]; then
651 if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
652 verbose rm -rf "$d0/$d"
654 echo "Note: $d0/$d will stay broken."
658 o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
659 git config xonotic.all.mirrorselection try_same
660 verbose git clone --branch "$branch" "$url" "$d0/$d"
661 git config xonotic.all.mirrorselection "$o"
662 enter "$d0/$d" verbose
663 fix_git_config "$url" "$pushurl"
667 allrepos ifrepoenabled 0 pull_
671 if [ x"$1" = x"-f" ]; then
677 if [ -z "$branch" ]; then
680 askbranch=${remote#origin/}
689 if [ -n "$checkoutflags" ]; then
690 set -- -f "$@" # to make checkself work again
696 enter "$d0/$d" verbose
698 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
700 verbose git checkout $checkoutflags "$b"
701 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
703 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
706 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
707 [ -n "$b" ] || exists=true
708 verbose git checkout $checkoutflags "$b"
709 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
710 [ -n "$b" ] || exists=true
711 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
713 $ECHO "WTF? Not even branch $b doesn't exist in $d"
718 checkself "$cmd" "$@"
721 allrepos ifrepoenabled 0 checkout_
723 $ECHO "The requested branch was not found in any repository."
731 if [ -z "$askbranch" ]; then
739 r=`git symbolic-ref HEAD`
741 dv=`visible_repo_name "$d"`
745 if [ -n "$askbranch" ]; then
749 dv=`visible_repo_name "$d"`
750 enter "$d0/$d" verbose
751 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
752 $ECHO "Already having this branch in $dv."
754 if yesno "Branch in $dv?"; then
755 if [ -n "$srcbranch" ]; then
759 verbose git fetch origin || true
761 verbose git checkout -b "$askbranch" "$b"
762 verbose git config "branch.$askbranch.remote" "$remote"
763 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
768 allrepos ifrepoenabled 0 branch_
770 allrepos ifrepoenabled 0 branch_show_
777 dv=`visible_repo_name "$d"`
778 enter "$d0/$d" verbose
779 r=`git symbolic-ref HEAD`
781 diffdata=`git diff --color HEAD`
782 if [ -n "$diffdata" ]; then
783 # we have uncommitted changes
784 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
785 verbose git commit -a
788 rem=`git config "branch.$r.remote" || $ECHO origin`
789 bra=`git config "branch.$r.merge" || $ECHO "$r"`
790 upstream="$rem/${bra#refs/heads/}"
791 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
792 upstream="origin/$branch"
794 logdata=`git log --color "$upstream".."$r"`
795 if [ -n "$logdata" ]; then
796 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
797 verbose git push "$rem" HEAD
800 if [ x"$submit" = x"-s" ]; then
803 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
809 allrepos ifrepoenabled 0 push_
813 if [ x"$1" = x"-k" ]; then
818 if verbose cd "$d0/$d"; then
838 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
839 # ./all clean --reclone
842 if [ x"$X" = x"--reclone" ]; then
849 elif [ x"$X" = x"-f" ]; then
851 elif [ x"$X" = x"-u" ]; then
853 elif [ x"$X" = x"-U" ]; then
856 elif [ x"$X" = x"-fu" ]; then
859 elif [ x"$X" = x"-fU" ]; then
863 elif [ x"$X" = x"-m" ]; then
865 elif [ x"$X" = x"-r" ]; then
867 elif [ x"$X" = x"-D" ]; then
869 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
872 msg " ,--'-\\P/\`\\ FFFFFFF"
873 msg " __/_ B/,-.\\ FFFFFFF"
874 msg " / _\\ (// O\\\\ FFFFFF"
875 msg "| (O \`) _\\._ _)\\ FFFUU"
876 msg "| |___/.^d0~~\"\\ \\ UUUU"
877 msg "| |\`~' \\ | UUUU"
878 msg "| | __,C>|| UUUU"
879 msg "\\ /_ ,-/,-' | UUUU"
880 msg " \\\\_ \\_>~' / UUUU-"
883 msg "Unknown arg: $X"
894 if $gotoupstream; then
896 msg "Must also use -f (delete local changes) when using -u"
900 if $fetchupstream; then
901 verbose git fetch origin
902 verbose git remote prune origin
904 verbose git checkout -f "$branch"
905 verbose git reset --hard origin/"$branch"
907 r=`git symbolic-ref HEAD`
909 rem=`git config "branch.$r.remote" || $ECHO origin`
910 bra=`git config "branch.$r.merge" || $ECHO "$r"`
911 upstream="$rem/${bra#refs/heads/}"
912 if $fetchupstream; then
913 for t in `git tag -l "xonotic-v"*`; do
914 verbose git tag -d "$t"
916 verbose git fetch "$rem"
917 verbose git remote prune "$rem"
919 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
920 upstream="origin/$branch"
922 verbose git reset --hard "$upstream"
924 elif $gotomaster; then
926 verbose git checkout -f "$branch"
927 verbose git reset --hard
929 verbose git checkout "$branch"
932 verbose git reset --hard
934 if $rmuntracked; then
937 verbose git clean -df || true
940 verbose git clean -xdf || true
944 if $killbranches; then
945 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
946 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
947 verbose git branch -D "${B#refs/heads/}"
950 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
951 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
953 checkself "$cmd" "$@"
955 allrepos ifrepoenabled 0 clean_
958 $ECHO " $SELF branch <branch>"
959 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
960 $ECHO " $SELF checkout|switch <branch>"
961 $ECHO " $SELF checkout|switch <remote>/<branch>"
962 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
963 $ECHO " $SELF clean --reclone"
964 $ECHO " $SELF each|foreach [-k] command..."
965 $ECHO " $SELF fix_upstream_rebase"
966 $ECHO " $SELF keygen"
967 $ECHO " $SELF push|commit [-s]"
968 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
969 $ECHO " $SELF grep \"<regex>\""
974 if verbose cd "$d0/$d"; then
975 git grep -In "$@" || true