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 <sbeller@xxxxxxxxxx> --- 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