From: Junio C Hamano Date: Tue, 16 Aug 2011 18:41:26 +0000 (-0700) Subject: Merge branch 'jc/submodule-sync-no-auto-vivify' into maint X-Git-Tag: v1.7.6.1~27 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/4a5a8008fde47a4c999657515b396d53153bec3d?ds=inline;hp=-c Merge branch 'jc/submodule-sync-no-auto-vivify' into maint * jc/submodule-sync-no-auto-vivify: submodule add: always initialize .git/config entry submodule sync: do not auto-vivify uninteresting submodule --- 4a5a8008fde47a4c999657515b396d53153bec3d diff --combined Documentation/git-submodule.txt index 5e7a4130ee,710633f965..2b31d5f1f2 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@@ -101,10 -101,9 +101,10 @@@ status: currently checked out commit for each submodule, along with the submodule path and the output of 'git describe' for the SHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not - initialized and `+` if the currently checked out submodule commit + initialized, `+` if the currently checked out submodule commit does not match the SHA-1 found in the index of the containing - repository. This command is the default command for 'git submodule'. + repository and `U` if the submodule has merge conflicts. + This command is the default command for 'git submodule'. + If '--recursive' is specified, this command will recurse into nested submodules, and show their status as well. @@@ -167,7 -166,9 +167,9 @@@ commit for each submodule sync:: Synchronizes submodules' remote URL configuration setting - to the value specified in .gitmodules. This is useful when + to the value specified in .gitmodules. It will only affect those + submodules which already have an url entry in .git/config (that is the + case when they are initialized or freshly added). This is useful when submodule URLs change upstream and you need to update your local repositories accordingly. + @@@ -186,10 -187,8 +188,10 @@@ OPTION -f:: --force:: - This option is only valid for the add command. - Allow adding an otherwise ignored submodule path. + This option is only valid for add and update commands. + When running add, allow adding an otherwise ignored submodule path. + When running update, throw away local changes in submodules when + switching to a different commit. --cached:: This option is only valid for status and summary commands. These @@@ -260,6 -259,11 +262,6 @@@ This file should be formatted in the sa to each submodule url is "submodule.$name.url". See linkgit:gitmodules[5] for details. - -AUTHOR ------- -Written by Lars Hjemli - GIT --- Part of the linkgit:git[1] suite diff --combined git-submodule.sh index 9c6dca5a15,ec6178ee99..20c9bec970 --- 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" @@@ -246,7 -231,6 +246,6 @@@ cmd_add( url="$repo" ;; esac - git config submodule."$path".url "$url" else module_clone "$path" "$realrepo" "$reference" || exit @@@ -256,10 -240,11 +255,11 @@@ # 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 + git config submodule."$path".url "$url" git add $force "$path" || die "Failed to add submodule '$path'" @@@ -300,10 -285,6 +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 @@@ -320,7 -301,7 +320,7 @@@ then cmd_foreach "--recursive" "$@" fi - ) || + ) <&3 3<&- || die "Stopping at '$path'; script returned non-zero status." fi done @@@ -359,25 -340,26 +359,26 @@@ cmd_init( do # Skip already registered paths name=$(module_name "$path") || exit - url=$(git config submodule."$name".url) - test -z "$url" || continue - - url=$(git config -f .gitmodules submodule."$name".url) - test -z "$url" && - die "No url found for submodule path '$path' in .gitmodules" - - # Possibly a url relative to parent - case "$url" in - ./*|../*) - url=$(resolve_relative_url "$url") || exit - ;; - esac - - git config submodule."$name".url "$url" || - die "Failed to register url for submodule path '$path'" + if test -z "$(git config "submodule.$name.url")" + then + url=$(git config -f .gitmodules submodule."$name".url) + test -z "$url" && + die "No url found for submodule path '$path' in .gitmodules" + + # Possibly a url relative to parent + case "$url" in + ./*|../*) + url=$(resolve_relative_url "$url") || exit + ;; + esac + git config submodule."$name".url "$url" || + die "Failed to register url for submodule path '$path'" + fi + # Copy "update" setting when it is not set yet upd="$(git config -f .gitmodules submodule."$name".update)" test -z "$upd" || + test -n "$(git config submodule."$name".update)" || git config submodule."$name".update "$upd" || die "Failed to register update mode for submodule path '$path'" @@@ -393,38 -375,41 +394,38 @@@ cmd_update() { # parse $args after "submodule ... update". - orig_args="$@" + orig_flags= while test $# -ne 0 do case "$1" in -q|--quiet) - shift GIT_QUIET=1 ;; -i|--init) init=1 - shift ;; -N|--no-fetch) - shift nofetch=1 ;; + -f|--force) + force=$1 + ;; -r|--rebase) - shift update="rebase" ;; --reference) case "$2" in '') usage ;; esac reference="--reference=$2" - shift 2 + orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" + shift ;; --reference=*) reference="$1" - shift ;; -m|--merge) - shift update="merge" ;; --recursive) - shift recursive=1 ;; --) @@@ -438,8 -423,6 +439,8 @@@ break ;; esac + orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" + shift done if test -n "$init" @@@ -447,15 -430,9 +448,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) @@@ -472,7 -449,6 +473,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" && @@@ -487,30 -463,19 +488,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" @@@ -523,7 -488,7 +524,7 @@@ msg="merged in" ;; *) - command="git checkout $force -q" + command="git checkout $subforce -q" action="checkout" msg="checked out" ;; @@@ -536,7 -501,7 +537,7 @@@ if test -n "$recursive" then - (clear_local_git_env; cd "$path" && cmd_update $orig_args) || + (clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags") || die "Failed to recurse into submodule path '$path'" fi done @@@ -769,7 -734,7 +770,7 @@@ cmd_summary() cmd_status() { # parse $args after "submodule ... status". - orig_args="$@" + orig_flags= while test $# -ne 0 do case "$1" in @@@ -793,7 -758,6 +794,7 @@@ break ;; esac + orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" shift done @@@ -803,11 -767,6 +804,11 @@@ 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" @@@ -832,7 -791,7 +833,7 @@@ prefix="$displaypath/" clear_local_git_env cd "$path" && - cmd_status $orig_args + eval cmd_status "$orig_args" ) || die "Failed to recurse into submodule path '$path'" fi @@@ -878,17 -837,20 +879,20 @@@ cmd_sync( ;; esac - say "Synchronizing submodule url for '$name'" - git config submodule."$name".url "$url" - - if test -e "$path"/.git + if git config "submodule.$name.url" >/dev/null 2>/dev/null then - ( - clear_local_git_env - cd "$path" - remote=$(get_default_remote) - git config remote."$remote".url "$url" - ) + say "Synchronizing submodule url for '$name'" + git config submodule."$name".url "$url" + + if test -e "$path"/.git + then + ( + clear_local_git_env + cd "$path" + remote=$(get_default_remote) + git config remote."$remote".url "$url" + ) + fi fi done } diff --combined t/t7403-submodule-sync.sh index d600583cef,fb21b87683..95ffe349a7 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@@ -25,7 -25,8 +25,8 @@@ test_expect_success setup git clone super super-clone && (cd super-clone && git submodule update --init) && git clone super empty-clone && - (cd empty-clone && git submodule init) + (cd empty-clone && git submodule init) && + git clone super top-only-clone ' test_expect_success 'change submodule' ' @@@ -52,7 -53,7 +53,7 @@@ test_expect_success 'change submodule u test_expect_success '"git submodule sync" should update submodule URLs' ' (cd super-clone && - git pull && + git pull --no-recurse-submodules && git submodule sync ) && test -d "$(git config -f super-clone/submodule/.git/config \ @@@ -66,7 -67,7 +67,7 @@@ ) ' - test_expect_success '"git submodule sync" should update submodule URLs if not yet cloned' ' + test_expect_success '"git submodule sync" should update known submodule URLs' ' (cd empty-clone && git pull && git submodule sync && @@@ -74,4 -75,14 +75,14 @@@ ) ' + test_expect_success '"git submodule sync" should not vivify uninteresting submodule' ' + (cd top-only-clone && + git pull && + git submodule sync && + test -z "$(git config submodule.submodule.url)" && + git submodule sync submodule && + test -z "$(git config submodule.submodule.url)" + ) + ' + test_done