git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] recursive submodules: detach HEAD from new state

From
Stefan Beller <sbeller@google.com>
Date
Jul 24, 2017, 17:36 UTC
Message-ID
<20170724173601.19921-1-sbeller@google.com>

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 in the current model of Git as e.g. 'submodule update' always detaches the submodule HEAD.

Despite having plans to have submodule HEADS not detached in the future, the current behavior is really bad as it doesn't match user expectations and it is not checking for loss of commits (only to be recovered via the reflog).

Detach the HEAD unconditionally in the submodule when updating it.
Signed-off-by: Stefan Beller <sbeller@google.com>
---

This is a resend of [1], which did not receive any attention. I improved the commit message laying out the current state of affairs, arguing that any future plan should not weigh in as much as the current possible data loss.

[1] https://public-inbox.org/git/20170630003851.17288-1-sbeller@google.com/

Thanks, Stefan

 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 ef83c2a9ee..4b7c0a4c82 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1653,7 +1653,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.14.0.rc0.3.g6c2e499285
Next: Jonathan Nieder
Message 1 of 13 in “recursive submodules: detach HEAD from new state”
  1. recursive submodules: detach HEAD from new stateStefan Beller, Jul 24, 2017
  2. Jonathan NiederJul 24, 2017
  3. Stefan BellerJul 24, 2017
  4. Junio C HamanoJul 24, 2017
  5. Junio C HamanoJul 24, 2017
  6. Junio C HamanoJul 24, 2017
  7. Stefan BellerJul 25, 2017
  8. Junio C HamanoJul 26, 2017
  9. Jonathan NiederNov 21, 2017
  10. Stefan BellerNov 21, 2017
  11. Jonathan NiederNov 21, 2017
  12. Stefan BellerNov 21, 2017
  13. Junio C HamanoNov 22, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.