3 if [ x"$3" != x"." ]; then
21 allrepos initrepo_ "`git config remote.origin.url`" "`git config remote.origin.pushurl`"
22 msg "Found main repo = $base"
23 if [ -n "$pushbase" ]; then
24 msg "Found push repo = $pushbase"
40 [ x"$1" = x"$3" ] || return
41 if matchrepoflag "$6" "$2"; then
47 allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
52 # first result is to be ignored, but we use it to check status
53 git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
54 # if we can't time, we only check availability
59 # now actually time it
62 export REPO=$1 # so that the sh -c subshell can use it
63 { 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
64 # unit: clock ticks (depends on what "time" returns
75 bestmirror_firstrepo()
77 if [ -z "$testrepo" ]; then
81 allrepos bestmirror_firstrepo
84 if [ x"$oldurl" = x"$3" ]; then
89 allmirrors bestmirror_findold
91 if [ -z "$newprotocol" ]; then
92 newprotocol=$oldprotocol
94 if [ -z "$newlocation" ]; then
95 newlocation=$oldlocation
102 bestmirror_benchmark()
110 if [ -z "$bmb_loc" ]; then
111 # empty location is not allowed
114 case " $newprotocol " in
116 # no protocol requested? all match
125 # prefer location match
126 case " $newlocation " in
128 # bmb_curloc is true in first run, false in second
129 # so first run gets all matching locations
130 # so second run gets all non-matching locations
131 if ! $bmb_curloc; then
139 case " $newlocation " in
148 case " $newlocation " in
153 case " $newlocation " in
161 msg "Testing speed of $bmb_url..."
163 # only working mirrors
164 if ! thistime=`mirrorspeed "$bmb_url$testrepo"`; then
168 thistime=$(($thistime $bmb_fudge))
171 # anything is better than nothing
172 if [ -z "$besttime" ]; then
174 bestlocation=$bmb_loc
180 # prefer location match
181 case " $newlocation " in
183 case " $newlocation " in
190 bestlocation=$bmb_loc
198 # if newlocation matches bestlocation, then we already discarded it above
202 # if we get here, we must compare mirror speed as we have more than one match
203 if [ $thistime -gt $besttime ]; then
205 elif [ $thistime -lt $besttime ]; then
207 bestlocation=$bmb_loc
212 # both location and time match. Random decision.
213 bestcount=$(($bestcount + 1))
214 if [ $((($RANDOM + 0) % $bestcount)) -eq 0 ]; then
216 bestlocation=$bmb_loc
219 allmirrors bestmirror_benchmark true
220 allmirrors bestmirror_benchmark false
226 [ x"$1" = x"$3" ] || return
237 allrepos testrepoflag_ "$1" "$2" | grep ^0 >/dev/null
244 # if we have .no file, skip
245 if [ -f "$d.no" ]; then
246 msg "Repository $d disabled by a .no file, delete $d.no to enable"
249 # if .yes file exists, always keep it
250 if [ -f "$d.yes" ]; then
251 msg "Repository $d enabled by a .yes file"
255 # remove broken clones so they don't mess up stuff
256 if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
257 msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
261 # if we have the dir, always keep it
263 msg "Repository $d enabled because it already exists"
267 # if we have matching pk3, skip
268 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
269 msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
272 # if "no" flag is set, skip
273 if matchrepoflag "$f" no; then
274 msg "Repository $d disabled by default, create $d.yes to enable"
278 msg "Repository $d enabled by default"
284 $ECHO `allrepos listrepos_`
291 eval ire_test=\$$(($1 + 3))
299 check_mergeconflict() # overrides the one in ./all
301 if git ls-files -u | grep ' 1 '; then
303 $ECHO "MERGE CONFLICT."
304 $ECHO "change into the \"$1\" project directory, and then:"
305 $ECHO "- edit the files mentioned above with your favorite editor,"
306 $ECHO " and fix the conflicts (marked with <<<<<<< blocks)"
307 $ECHO "- for binary files, you can select the files using"
308 $ECHO " git checkout --ours or git checkout --theirs"
309 $ECHO "- when done with a file, 'git add' the file"
310 $ECHO "- when done, 'git commit'"
320 $ECHO "the root directory"
328 fix_upstream_rebase()
330 if [ -z "$r_me" ] || [ -z "$r_other" ]; then
334 # one of the two sides of the merge should be remote upstream, or all is fine
335 r_r=`git symbolic-ref HEAD`
336 r_r=${r_r#refs/heads/}
337 r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
338 r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
339 r_bra=${r_bra#refs/heads/}
340 if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
341 if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
346 r_base=`git merge-base "$r_me" "$r_other"`
348 # no merge-base? upstream did filter-branch
349 if [ -n "$r_base" ]; then
350 # otherwise, check if the two histories are "similar"
351 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
352 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
354 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
355 r_lc_me=`$ECHO "$r_l_me" | wc -l`
356 r_lc_other=`$ECHO "$r_l_other" | wc -l`
357 r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
358 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
360 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
361 if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
362 git reset --hard "$r_me"
372 fix_upstream_rebase_mergeok()
374 r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
375 r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
379 fix_upstream_rebase_mergefail()
381 r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
382 r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
388 if ! [ -f ".git/config" ]; then
389 $ECHO "Not a git repository. Bailing out to not cause damage."
392 verbose git config remote.origin.url "$1"
394 verbose git config remote.origin.pushurl "$2"
396 verbose git config --unset remote.origin.pushurl || true
398 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
399 if testrepoflag "$d" noautocrlf; then
400 verbose git config --unset core.autocrlf || true
402 verbose git config core.autocrlf input
404 if [ -z "`git config push.default || true`" ]; then
405 verbose git config push.default current # or is tracking better?
407 verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
408 verbose git config filter.mapclean.smudge "cat"
413 while [ $# -gt 4 ]; do
418 if [ -n "$pushbase" ]; then
419 pushurl="$pushbase$2"
430 fix_upstream_rebase_()
433 enter "$d0/$d" verbose
434 verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
436 allrepos ifrepoenabled 0 fix_upstream_rebase_
442 if [ -f "$d0/$d/.git/config" ]; then
444 fix_git_config "$url" "$pushurl"
448 allrepos ifrepoenabled 0 fix_config_
451 if [ -f ~/.ssh/id_rsa.pub ]; then
453 msg "A key already exists and no new one will be generated. If you"
454 msg "already have done the procedure for getting your key approved, you"
455 msg "can skip the following paragraph and already use the repository."
457 msg "To get access, your key has to be approved first. For that, visit"
458 msg "$gitsite_url, then log in, enter the"
459 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
460 msg "to apply for access and paste the following output into the issue:"
462 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
463 msg "and paste the following output:"
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 "$gitsite_url, then log in, enter the"
474 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
475 msg "to apply for access and paste the following output into the issue:"
477 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
478 msg "and paste the following output:"
480 msg "`cat ~/.ssh/id_dsa.pub`"
483 msg "No key has been generated yet. One will be generated now."
484 msg "If other people are using your computer, it is recommended"
485 msg "to specify a passphrase. Otherwise you can simply hit ENTER"
486 msg "when asked for a passphrase."
488 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
490 msg "To get access, your key has to be approved first. For that, visit"
491 msg "$gitsite_url, then log in, enter the"
492 msg "\"xonotic\" project, create an \"Issue\" tagged \"Repository Access\""
493 msg "to apply for access and paste the following output into the issue:"
495 msg "After that, go to your profile settings, \"SSH Keys\", \"Add SSH Key\""
496 msg "and paste the following output:"
498 msg "`cat ~/.ssh/id_rsa.pub`"
501 msg "Note that you will only have write access to branches that start"
502 msg "with your user name."
504 msg "Once you have gotten access, run ./all update -p"
508 need_bestmirror=false
514 case "`git config xonotic.all.mirrorselection 2>/dev/null || true`" in
521 newprotocol="git http"
526 newprotocol= # same protocol
532 if $need_bestmirror; then
536 if [ x"$base" = x"$3" ]; then
540 allmirrors identifymirror_
543 msg "Current mirror not found = $base"
544 msg "but the last pull attempt failed."
546 msg "Use ./all update -l any to switch to the best mirror."
548 need_bestmirror=false
553 if [ x"$1" = x"-N" ]; then
555 elif [ x"$1" = x"-p" ]; then
558 elif [ x"$1" = x"-s" ]; then
561 elif [ x"$1" = x"-g" ]; then
564 elif [ x"$1" = x"-h" ]; then
567 elif [ x"$1" = x"-l" ]; then
577 if $need_bestmirror; then
578 newbase=`bestmirror "$base" "$newprotocol" "$newlocation"`
579 if [ -z "$newbase" ]; then
580 msg "Could not find any good mirror. Maybe try again later."
581 git config xonotic.all.mirrorselection try_all
584 if [ -n "$newpushprotocol" ]; then
585 if [ -n "$pushbase" ]; then
586 newpushbase=`bestmirror "$pushbase" "$newpushprotocol" "$newlocation"`
588 newpushbase=`bestmirror "$base" "$newpushprotocol" "$newlocation"`
591 newpushbase=$pushbase
594 if [ x"$base" != x"$newbase" ] || [ x"$pushbase" != x"$newpushbase" ]; then
596 pushbase=$newpushbase
600 if [ x"$d" = x"." ]; then
601 fix_git_config "$url" "$pushurl"
604 allrepos ifrepoenabled 0 seturl_
606 git config xonotic.all.mirrorselection done
614 if [ -f "$d0/$d/.git/config" ]; then
615 # if we have .no file, skip
616 if [ -f "$d0/$d.no" ]; then
617 msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
621 enter "$d0/$d" verbose
622 r=`git symbolic-ref HEAD`
624 if git config branch.$r.remote >/dev/null 2>&1; then
625 o=`( cd "$d0" && git config xonotic.all.mirrorselection 2>/dev/null || true )`
626 ( cd "$d0" && git config xonotic.all.mirrorselection try_same )
627 if ! verbose git pull; then
628 if fix_upstream_rebase_mergefail; then
629 check_mergeconflict "$d"
630 $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
634 ( cd "$d0" && git config xonotic.all.mirrorselection "$o" )
635 fix_upstream_rebase_mergeok || true
640 checkself "$cmd" "$@"
642 verbose git remote prune origin
646 if [ -d "$d0/$d" ]; then
647 if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
648 verbose rm -rf "$d0/$d"
650 echo "Note: $d0/$d will stay broken."
654 o=`git config xonotic.all.mirrorselection 2>/dev/null || true`
655 git config xonotic.all.mirrorselection try_same
656 verbose git clone --branch "$branch" "$url" "$d0/$d"
657 git config xonotic.all.mirrorselection "$o"
658 enter "$d0/$d" verbose
659 fix_git_config "$url" "$pushurl"
663 allrepos ifrepoenabled 0 pull_
667 if [ x"$1" = x"-f" ]; then
673 if [ -z "$branch" ]; then
676 askbranch=${remote#origin/}
685 if [ -n "$checkoutflags" ]; then
686 set -- -f "$@" # to make checkself work again
692 enter "$d0/$d" verbose
694 if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
696 verbose git checkout $checkoutflags "$b"
697 elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
699 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
702 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
703 [ -n "$b" ] || exists=true
704 verbose git checkout $checkoutflags "$b"
705 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
706 [ -n "$b" ] || exists=true
707 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
709 $ECHO "WTF? Not even branch $b doesn't exist in $d"
714 checkself "$cmd" "$@"
717 allrepos ifrepoenabled 0 checkout_
719 $ECHO "The requested branch was not found in any repository."
727 if [ -z "$askbranch" ]; then
735 r=`git symbolic-ref HEAD`
737 dv=`visible_repo_name "$d"`
741 if [ -n "$askbranch" ]; then
745 dv=`visible_repo_name "$d"`
746 enter "$d0/$d" verbose
747 if git rev-parse "refs/heads/$askbranch" >/dev/null 2>&1; then
748 $ECHO "Already having this branch in $dv."
750 if yesno "Branch in $dv?"; then
751 if [ -n "$srcbranch" ]; then
755 verbose git fetch origin || true
757 verbose git checkout -b "$askbranch" "$b"
758 verbose git config "branch.$askbranch.remote" "$remote"
759 verbose git config "branch.$askbranch.merge" "refs/heads/$askbranch"
764 allrepos ifrepoenabled 0 branch_
766 allrepos ifrepoenabled 0 branch_show_
773 dv=`visible_repo_name "$d"`
774 enter "$d0/$d" verbose
775 r=`git symbolic-ref HEAD`
777 diffdata=`git diff --color HEAD`
778 if [ -n "$diffdata" ]; then
779 # we have uncommitted changes
780 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
781 verbose git commit -a
784 rem=`git config "branch.$r.remote" || $ECHO origin`
785 bra=`git config "branch.$r.merge" || $ECHO "$r"`
786 upstream="$rem/${bra#refs/heads/}"
787 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
788 upstream="origin/$branch"
790 logdata=`git log --color "$upstream".."$r"`
791 if [ -n "$logdata" ]; then
792 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
793 verbose git push "$rem" HEAD
796 if [ x"$submit" = x"-s" ]; then
799 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
805 allrepos ifrepoenabled 0 push_
809 if [ x"$1" = x"-k" ]; then
814 if verbose cd "$d0/$d"; then
834 # ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
835 # ./all clean --reclone
838 if [ x"$X" = x"--reclone" ]; then
845 elif [ x"$X" = x"-f" ]; then
847 elif [ x"$X" = x"-u" ]; then
849 elif [ x"$X" = x"-U" ]; then
852 elif [ x"$X" = x"-fu" ]; then
855 elif [ x"$X" = x"-fU" ]; then
859 elif [ x"$X" = x"-m" ]; then
861 elif [ x"$X" = x"-r" ]; then
863 elif [ x"$X" = x"-D" ]; then
865 elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
868 msg " ,--'-\\P/\`\\ FFFFFFF"
869 msg " __/_ B/,-.\\ FFFFFFF"
870 msg " / _\\ (// O\\\\ FFFFFF"
871 msg "| (O \`) _\\._ _)\\ FFFUU"
872 msg "| |___/.^d0~~\"\\ \\ UUUU"
873 msg "| |\`~' \\ | UUUU"
874 msg "| | __,C>|| UUUU"
875 msg "\\ /_ ,-/,-' | UUUU"
876 msg " \\\\_ \\_>~' / UUUU-"
879 msg "Unknown arg: $X"
890 if $gotoupstream; then
892 msg "Must also use -f (delete local changes) when using -u"
896 if $fetchupstream; then
897 verbose git fetch origin
898 verbose git remote prune origin
900 verbose git checkout -f "$branch"
901 verbose git reset --hard origin/"$branch"
903 r=`git symbolic-ref HEAD`
905 rem=`git config "branch.$r.remote" || $ECHO origin`
906 bra=`git config "branch.$r.merge" || $ECHO "$r"`
907 upstream="$rem/${bra#refs/heads/}"
908 if $fetchupstream; then
909 for t in `git tag -l "xonotic-v"*`; do
910 verbose git tag -d "$t"
912 verbose git fetch "$rem"
913 verbose git remote prune "$rem"
915 if ! git rev-parse "$upstream" >/dev/null 2>&1; then
916 upstream="origin/$branch"
918 verbose git reset --hard "$upstream"
920 elif $gotomaster; then
922 verbose git checkout -f "$branch"
923 verbose git reset --hard
925 verbose git checkout "$branch"
928 verbose git reset --hard
930 if $rmuntracked; then
933 verbose git clean -df || true
936 verbose git clean -xdf || true
940 if $killbranches; then
941 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
942 if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
943 verbose git branch -D "${B#refs/heads/}"
946 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
947 git rev-parse "refs/heads/$branch" >/dev/null 2>&1 || verbose git branch --track "$branch" origin/"$branch" || true
949 checkself "$cmd" "$@"
951 allrepos ifrepoenabled 0 clean_
954 $ECHO " $SELF branch <branch>"
955 $ECHO " $SELF branch <remote> <branch> [<srcbranch>]"
956 $ECHO " $SELF checkout|switch <branch>"
957 $ECHO " $SELF checkout|switch <remote>/<branch>"
958 $ECHO " $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
959 $ECHO " $SELF clean --reclone"
960 $ECHO " $SELF each|foreach [-k] command..."
961 $ECHO " $SELF fix_upstream_rebase"
962 $ECHO " $SELF keygen"
963 $ECHO " $SELF push|commit [-s]"
964 $ECHO " $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
965 $ECHO " $SELF grep \"<regex>\""
970 if verbose cd "$d0/$d"; then
971 git grep -In "$@" || true