From: Junio C Hamano Date: Tue, 16 Aug 2011 18:23:26 +0000 (-0700) Subject: Merge branch 'bc/submodule-foreach-stdin-fix-1.7.4' into maint X-Git-Tag: v1.7.6.1~30 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d5c756e99ed7aa07427295b1011edf4718ea80b0?ds=inline;hp=-c Merge branch 'bc/submodule-foreach-stdin-fix-1.7.4' into maint * bc/submodule-foreach-stdin-fix-1.7.4: git-submodule.sh: preserve stdin for the command spawned by foreach t/t7407: demonstrate that the command called by 'submodule foreach' loses stdin --- d5c756e99ed7aa07427295b1011edf4718ea80b0 diff --combined git-submodule.sh index d189a24c71,07dc675cef..9c6dca5a15 --- a/git-submodule.sh +++ b/git-submodule.sh @@@ -8,7 -8,7 +8,7 @@@ dashless=$(basename "$0" | sed -e 's/- USAGE="[--quiet] add [-b branch] [-f|--force] [--reference ] [--] [] or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] or: $dashless [--quiet] init [--] [...] - or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] + or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] or: $dashless [--quiet] foreach [--recursive] or: $dashless [--quiet] sync [--] [...]" @@@ -37,24 -37,12 +37,24 @@@ resolve_relative_url ( die "remote ($remote) does not have a url defined in .git/config" url="$1" remoteurl=${remoteurl%/} + sep=/ while test -n "$url" do case "$url" in ../*) url="${url#../}" - remoteurl="${remoteurl%/*}" + case "$remoteurl" in + */*) + remoteurl="${remoteurl%/*}" + ;; + *:*) + remoteurl="${remoteurl%:*}" + sep=: + ;; + *) + die "cannot strip one component off url '$remoteurl'" + ;; + esac ;; ./*) url="${url#./}" @@@ -63,7 -51,7 +63,7 @@@ break;; esac done - echo "$remoteurl/${url%/}" + echo "$remoteurl$sep${url%/}" } # @@@ -72,24 -60,7 +72,24 @@@ # module_list() { - git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 ' + git ls-files --error-unmatch --stage -- "$@" | + perl -e ' + my %unmerged = (); + my ($null_sha1) = ("0" x 40); + while () { + chomp; + my ($mode, $sha1, $stage, $path) = + /^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/; + next unless $mode eq "160000"; + if ($stage ne "0") { + if (!$unmerged{$path}++) { + print "$mode $null_sha1 U\t$path\n"; + } + next; + } + print "$_\n"; + } + ' } # @@@ -122,6 -93,20 +122,6 @@@ module_clone( url=$2 reference="$3" - # If there already is a directory at the submodule path, - # expect it to be empty (since that is the default checkout - # action) and try to remove it. - # Note: if $path is a symlink to a directory the test will - # succeed but the rmdir will fail. We might want to fix this. - if test -d "$path" - then - rmdir "$path" 2>/dev/null || - die "Directory '$path' exists, but is neither empty nor a git repository" - fi - - test -e "$path" && - die "A file already exist at path '$path'" - if test -n "$reference" then git-clone "$reference" -n "$url" "$path" @@@ -256,7 -241,7 +256,7 @@@ cmd_add( # ash fails to wordsplit ${branch:+-b "$branch"...} case "$branch" in '') git checkout -f -q ;; - ?*) git checkout -f -q -b "$branch" "origin/$branch" ;; + ?*) git checkout -f -q -B "$branch" "origin/$branch" ;; esac ) || die "Unable to checkout submodule '$path'" fi @@@ -300,6 -285,10 +300,10 @@@ cmd_foreach( toplevel=$(pwd) + # dup stdin so that it can be restored when running the external + # command in the subshell (and a recursive call to this function) + exec 3<&0 + module_list | while read mode sha1 stage path do @@@ -316,7 -305,7 +320,7 @@@ then cmd_foreach "--recursive" "$@" fi - ) || + ) <&3 3<&- || die "Stopping at '$path'; script returned non-zero status." fi done @@@ -402,9 -391,6 +406,9 @@@ cmd_update( -N|--no-fetch) nofetch=1 ;; + -f|--force) + force=$1 + ;; -r|--rebase) update="rebase" ;; @@@ -443,15 -429,9 +447,15 @@@ cmd_init "--" "$@" || return fi + cloned_modules= module_list "$@" | while read mode sha1 stage path do + if test "$stage" = U + then + echo >&2 "Skipping unmerged submodule $path" + continue + fi name=$(module_name "$path") || exit url=$(git config submodule."$name".url) update_module=$(git config submodule."$name".update) @@@ -468,7 -448,6 +472,7 @@@ if ! test -d "$path"/.git -o -f "$path"/.git then module_clone "$path" "$url" "$reference"|| exit + cloned_modules="$cloned_modules;$name" subsha1= else subsha1=$(clear_local_git_env; cd "$path" && @@@ -483,30 -462,19 +487,30 @@@ if test "$subsha1" != "$sha1" then - force= - if test -z "$subsha1" + subforce=$force + # If we don't already have a -f flag and the submodule has never been checked out + if test -z "$subsha1" -a -z "$force" then - force="-f" + subforce="-f" fi if test -z "$nofetch" then + # Run fetch only if $sha1 isn't present or it + # is not reachable from a ref. (clear_local_git_env; cd "$path" && - git-fetch) || + ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) && + test -z "$rev") || git-fetch)) || die "Unable to fetch in submodule path '$path'" fi + # Is this something we just cloned? + case ";$cloned_modules;" in + *";$name;"*) + # then there is no local change to integrate + update_module= ;; + esac + case "$update_module" in rebase) command="git rebase" @@@ -519,7 -487,7 +523,7 @@@ msg="merged in" ;; *) - command="git checkout $force -q" + command="git checkout $subforce -q" action="checkout" msg="checked out" ;; @@@ -799,11 -767,6 +803,11 @@@ cmd_status( name=$(module_name "$path") || exit url=$(git config submodule."$name".url) displaypath="$prefix$path" + if test "$stage" = U + then + say "U$sha1 $displaypath" + continue + fi if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git then say "-$sha1 $displaypath" @@@ -874,12 -837,11 +878,12 @@@ cmd_sync( ;; esac + say "Synchronizing submodule url for '$name'" + git config submodule."$name".url "$url" + if test -e "$path"/.git then ( - say "Synchronizing submodule url for '$name'" - git config submodule."$name".url "$url" clear_local_git_env cd "$path" remote=$(get_default_remote) diff --combined t/t7407-submodule-foreach.sh index e5be13c271,8a74ccac5f..835a506241 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@@ -238,10 -238,6 +238,10 @@@ test_expect_success 'ensure "status --c ) && git submodule status --cached --recursive -- nested1 > ../actual ) && + if test_have_prereq MINGW + then + dos2unix actual + fi && test_cmp expect actual ' @@@ -292,4 -288,22 +292,22 @@@ test_expect_success 'use "update --recu ) ' + test_expect_success 'command passed to foreach retains notion of stdin' ' + ( + cd super && + git submodule foreach echo success >../expected && + yes | git submodule foreach "read y && test \"x\$y\" = xy && echo success" >../actual + ) && + test_cmp expected actual + ' + + test_expect_success 'command passed to foreach --recursive retains notion of stdin' ' + ( + cd clone2 && + git submodule foreach --recursive echo success >../expected && + yes | git submodule foreach --recursive "read y && test \"x\$y\" = xy && echo success" >../actual + ) && + test_cmp expected actual + ' + test_done