Merge branch 'sb/submodule-recursive-checkout-detach-head'
authorJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:23:35 +0000 (09:23 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:23:35 +0000 (09:23 -0800)
"git checkout --recursive" may overwrite and rewind the history of
the branch that happens to be checked out in submodule
repositories, which might not be desirable. Detach the HEAD but
still allow the recursive checkout to succeed in such a case.

* sb/submodule-recursive-checkout-detach-head:
Documentation/checkout: clarify submodule HEADs to be detached
recursive submodules: detach HEAD from new state

Documentation/git-checkout.txt
submodule.c
t/lib-submodule-update.sh
index e108b0f74bb6dc4d9f3fc27e7c3fe571b19a9d2f..bfa64ca5c98c54b9b9465d45669f45ab887605cf 100644 (file)
@@ -264,6 +264,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
        local modifications in a submodule would be overwritten the checkout
        will fail unless `-f` is used. If nothing (or --no-recurse-submodules)
        is used, the work trees of submodules will not be updated.
+       Just like linkgit:git-submodule[1], this will detach the
+       submodules HEAD.
 
 <branch>::
        Branch to checkout; if it refers to a branch (i.e., a name that,
index bb531e0e59ce7f8fa5cde622101b7ef1b324a603..95e6aff2bb74e1374d22997d1918ed190c6edafc 100644 (file)
@@ -1670,7 +1670,8 @@ int submodule_move_head(const char *path,
                        cp.dir = path;
 
                        prepare_submodule_repo_env(&cp.env_array);
-                       argv_array_pushl(&cp.args, "update-ref", "HEAD", new, NULL);
+                       argv_array_pushl(&cp.args, "update-ref", "HEAD",
+                                        "--no-deref", new, NULL);
 
                        if (run_command(&cp)) {
                                ret = -1;
index bb94c2320958eb1d1a319899697ecefc881e3043..9058bf978a005bbe24f9e5948ca5bf4f36eeb2a8 100755 (executable)
@@ -689,6 +689,23 @@ test_submodule_switch_recursing_with_args () {
                        test_submodule_content sub1 origin/add_sub1
                )
        '
+       test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
+               prolog &&
+               reset_work_tree_to_interested add_sub1 &&
+               (
+                       cd submodule_update &&
+                       git -C sub1 checkout -b keep_branch &&
+                       git -C sub1 rev-parse HEAD >expect &&
+                       git branch -t check-keep origin/modify_sub1 &&
+                       $command check-keep &&
+                       test_superproject_content origin/modify_sub1 &&
+                       test_submodule_content sub1 origin/modify_sub1 &&
+                       git -C sub1 rev-parse keep_branch >actual &&
+                       test_cmp expect actual &&
+                       test_must_fail git -C sub1 symbolic-ref HEAD
+               )
+       '
+
        # Replacing a tracked file with a submodule produces a checked out submodule
        test_expect_success "$command: replace tracked file with submodule checks out submodule" '
                prolog &&