From: Junio C Hamano Date: Thu, 27 Feb 2014 22:01:31 +0000 (-0800) Subject: Merge branch 'wk/submodule-on-branch' X-Git-Tag: v2.0.0-rc0~157 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/06c27689ddba0235ef4544cd4b2763c2572f9715?hp=-c Merge branch 'wk/submodule-on-branch' Make sure 'submodule update' modes that do not detach HEADs can be used more pleasantly by checking out a concrete branch when cloning them to prime the well. * wk/submodule-on-branch: Documentation: describe 'submodule update --remote' use case submodule: explicit local branch creation in module_clone submodule: document module_clone arguments in comments submodule: make 'checkout' update_module mode more explicit --- 06c27689ddba0235ef4544cd4b2763c2572f9715 diff --combined Documentation/gitmodules.txt index 347a9f76ee,385f35da59..f539e3f66a --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@@ -35,8 -35,6 +35,8 @@@ submodule..url: linkgit:git-clone[1] or (if it begins with ./ or ../) a location relative to the superproject's origin repository. +In addition, there are a number of optional keys: + submodule..update:: Defines what to do when the submodule is updated by the superproject. If 'checkout' (the default), the new commit specified in the @@@ -55,6 -53,10 +55,10 @@@ submodule..branch: A remote branch name for tracking updates in the upstream submodule. If the option is not specified, it defaults to 'master'. See the `--remote` documentation in linkgit:git-submodule[1] for details. + + + This branch name is also used for the local branch created by + non-checkout cloning updates. See the `update` documentation in + linkgit:git-submodule[1] for details. submodule..fetchRecurseSubmodules:: This option can be used to control recursive fetching of this diff --combined git-submodule.sh index 4a30087768,626a746f7c..a33f68d27c --- a/git-submodule.sh +++ b/git-submodule.sh @@@ -156,7 -156,7 +156,7 @@@ module_list( git ls-files -z --error-unmatch --stage -- "$@" || echo "unmatched pathspec exists" ) | - perl -e ' + @@PERL@@ -e ' my %unmerged = (); my ($null_sha1) = ("0" x 40); my @out = (); @@@ -241,6 -241,15 +241,15 @@@ module_name( # # Clone a submodule # + # $1 = submodule path + # $2 = submodule name + # $3 = URL to clone + # $4 = reference repository to reuse (empty for independent) + # $5 = depth argument for shallow clones (empty for deep) + # $6 = (remote-tracking) starting point for the local branch (empty for HEAD) + # $7 = local branch to create (empty for a detached HEAD, unless $6 is + # also empty, in which case the local branch is left unchanged) + # # Prior to calling, cmd_update checks that a possibly existing # path is not a git repository. # Likewise, cmd_add checks that path does not exist at all, @@@ -253,6 -262,8 +262,8 @@@ module_clone( url=$3 reference="$4" depth="$5" + start_point="$6" + local_branch="$7" quiet= if test -n "$GIT_QUIET" then @@@ -306,7 -317,16 +317,16 @@@ echo "gitdir: $rel/$a" >"$sm_path/.git" rel=$(echo $a | sed -e 's|[^/][^/]*|..|g') - (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b") + ( + clear_local_git_env + cd "$sm_path" && + GIT_WORK_TREE=. git config core.worktree "$rel/$b" && + # ash fails to wordsplit ${local_branch:+-B "$local_branch"...} + case "$local_branch" in + '') git checkout -f -q ${start_point:+"$start_point"} ;; + ?*) git checkout -f -q -B "$local_branch" ${start_point:+"$start_point"} ;; + esac + ) || die "$(eval_gettext "Unable to setup cloned submodule '\$sm_path'")" } isnumber() @@@ -469,16 -489,15 +489,15 @@@ Use -f if you really want to add it." > echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" fi fi - module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" || exit - ( - clear_local_git_env - cd "$sm_path" && - # ash fails to wordsplit ${branch:+-b "$branch"...} - case "$branch" in - '') git checkout -f -q ;; - ?*) git checkout -f -q -B "$branch" "origin/$branch" ;; - esac - ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")" + if test -n "$branch" + then + start_point="origin/$branch" + local_branch="$branch" + else + start_point="" + local_branch="" + fi + module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" "$start_point" "$local_branch" || exit fi git config submodule."$sm_name".url "$realrepo" @@@ -545,12 -564,7 +564,12 @@@ cmd_foreach( sm_path=$(relative_path "$sm_path") && # we make $path available to scripts ... path=$sm_path && - eval "$@" && + if test $# -eq 1 + then + eval "$1" + else + "$@" + fi && if test -n "$recursive" then cmd_foreach "--recursive" "$@" @@@ -721,6 -735,7 +740,6 @@@ cmd_deinit( cmd_update() { # parse $args after "submodule ... update". - orig_flags= while test $# -ne 0 do case "$1" in @@@ -745,6 -760,7 +764,6 @@@ --reference) case "$2" in '') usage ;; esac reference="--reference=$2" - orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" shift ;; --reference=*) @@@ -778,6 -794,7 +797,6 @@@ break ;; esac - orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" shift done @@@ -799,32 -816,35 +818,35 @@@ fi name=$(module_name "$sm_path") || exit url=$(git config submodule."$name".url) - branch=$(get_submodule_config "$name" branch master) + config_branch=$(get_submodule_config "$name" branch) + branch="${config_branch:-master}" + local_branch="$branch" if ! test -z "$update" then update_module=$update else update_module=$(git config submodule."$name".update) - case "$update_module" in - '') - ;; # Unset update mode - checkout | rebase | merge | none) - ;; # Known update modes - !*) - ;; # Custom update command - *) - die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" - ;; - esac + if test -z "$update_module" + then + update_module="checkout" + fi fi displaypath=$(relative_path "$prefix$sm_path") - if test "$update_module" = "none" - then + case "$update_module" in + none) echo "Skipping submodule '$displaypath'" continue - fi + ;; + checkout) + local_branch="" + ;; + rebase | merge | !*) + ;; + *) + die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" + esac if test -z "$url" then @@@ -838,7 -858,8 +860,8 @@@ Maybe you want to use 'update --init'?" if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git then - module_clone "$sm_path" "$name" "$url" "$reference" "$depth" || exit + start_point="origin/${branch}" + module_clone "$sm_path" "$name" "$url" "$reference" "$depth" "$start_point" "$local_branch" || exit cloned_modules="$cloned_modules;$name" subsha1= else @@@ -884,11 -905,16 +907,16 @@@ case ";$cloned_modules;" in *";$name;"*) # then there is no local change to integrate - update_module= ;; + update_module='!git reset --hard -q' esac must_die_on_failure= case "$update_module" in + checkout) + command="git checkout $subforce -q" + die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" + say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")" + ;; rebase) command="git rebase" die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")" @@@ -908,10 -934,7 +936,7 @@@ must_die_on_failure=yes ;; *) - command="git checkout $subforce -q" - die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" - say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")" - ;; + die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" esac if (clear_local_git_env; cd "$sm_path" && $command "$sha1") @@@ -932,7 -955,7 +957,7 @@@ prefix="$prefix$sm_path/" clear_local_git_env cd "$sm_path" && - eval cmd_update "$orig_flags" + eval cmd_update ) res=$? if test $res -gt 0 diff --combined t/t7406-submodule-update.sh index 0246e80b1a,f056c01ba0..28ca76384f --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@@ -63,6 -63,9 +63,9 @@@ test_expect_success 'setup a submodule git submodule add ../none none && test_tick && git commit -m "none" + ) && + (cd super && + git tag initial-setup ) ' @@@ -703,7 -706,7 +706,7 @@@ test_expect_success 'submodule update p git clone super_update_r super_update_r2 && (cd super_update_r2 && git submodule update --init --recursive >actual && - test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual && + test_i18ngrep "Submodule path .submodule/subsubmodule.: .git reset --hard -q" actual && (cd submodule/subsubmodule && git log > ../../expected ) && @@@ -762,17 -765,40 +765,50 @@@ test_expect_success 'submodule update c (cd submodule && test 1 = $(git log --oneline | wc -l) ) +) +' + +test_expect_success 'submodule update --recursive drops module name before recursing' ' + (cd super2 && + (cd deeper/submodule/subsubmodule && + git checkout HEAD^ + ) && + git submodule update --recursive deeper/submodule >actual && + test_i18ngrep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual ) ' + test_expect_success 'submodule update --checkout clones detached HEAD' ' + git clone super super4 && + echo "detached HEAD" >expected && + (cd super4 && + git reset --hard initial-setup && + git submodule init submodule && + git submodule update >> /tmp/log 2>&1 && + (cd submodule && + git symbolic-ref HEAD > ../../actual || + echo "detached HEAD" > ../../actual + ) + ) && + test_cmp actual expected && + rm -rf super4 + ' + + test_expect_success 'submodule update --merge clones attached HEAD' ' + git clone super super4 && + echo "refs/heads/master" >expected && + (cd super4 && + git reset --hard initial-setup && + git submodule init submodule && + git config submodule.submodule.update merge && + git submodule update --merge && + (cd submodule && + git symbolic-ref HEAD > ../../actual || + echo "detached HEAD" > ../../actual + ) + ) && + test_cmp actual expected && + rm -rf super4 + ' + test_done