When a submodule is on a branch and in its superproject you run a recursive
checkout, the branch of the submodule is updated to what the superproject
checks out. This is very unexpected. Instead detach the HEAD when updating
it.

Signed-off-by: Stefan Beller <sbel...@google.com>
---
 submodule.c               |  3 ++-
 t/lib-submodule-update.sh | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index da0b805493..719e8bd7a2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1604,7 +1604,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;
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d26f86800..fc406b95d7 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -848,6 +848,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 &&
-- 
2.13.0.31.g9b732c453e

Reply via email to