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

[PATCH 3/6] refs: fix ref storage format for submodule ref stores

From
Patrick Steinhardt <ps@pks.im>
Date
Aug 7, 2024, 12:43 UTC
Message-ID
<aaff9134ed849bcad08382168424d4aa92b153c8.1723032100.git.ps@pks.im>
In-Reply-To
<cover.1723032100.git.ps@pks.im>

When opening a submodule ref storage we accidentally use the ref storage format of the owning repository, not of the submodule repository. As submodules may have a different storage format than their parent repo this can lead to bugs when trying to access the submodule ref storage from the parent repository.

One such bug was reported when performing a recursive pull with mixed ref stores, which fails with:

    $ git pull --recursive
    fatal: Unable to find current revision in submodule path 'path/to/sub'

Fix the bug by using the submodule repository's ref storage format instead.

Note that only the second added test fails without this fix. The other one is included regardless as it exercises other parts where we might end up accessing submodule ref stores.

Reported-by: Jeppe Øland <joland@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 refs.c                                 |  2 +-
 t/t7424-submodule-mixed-ref-formats.sh | 57 +++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/refs.c b/refs.c
index 915aeb4d1d..e4b1f4f8b1 100644
--- a/refs.c
+++ b/refs.c
@@ -2011,7 +2011,7 @@ struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
 		free(subrepo);
 		goto done;
 	}
-	refs = ref_store_init(subrepo, the_repository->ref_storage_format,
+	refs = ref_store_init(subrepo, subrepo->ref_storage_format,
 			      submodule_sb.buf,
 			      REF_STORE_READ | REF_STORE_ODB);
 	register_ref_store_map(&repo->submodule_ref_stores, "submodule",
diff --git a/t/t7424-submodule-mixed-ref-formats.sh b/t/t7424-submodule-mixed-ref-formats.sh
index 4e4991d04c..998a5d82e9 100755
--- a/t/t7424-submodule-mixed-ref-formats.sh
+++ b/t/t7424-submodule-mixed-ref-formats.sh
@@ -18,7 +18,10 @@ do
 	fi
 
 test_expect_success 'setup' '
-	git config set --global protocol.file.allow always
+	git config set --global protocol.file.allow always &&
+	# Some tests migrate the ref storage format, which does not work with
+	# reflogs at the time of writing these tests.
+	git config set --global core.logAllRefUpdates false
 '
 
 test_expect_success 'recursive clone propagates ref storage format' '
@@ -59,6 +62,58 @@ test_expect_success 'clone submodules with different ref storage format' '
 	test_ref_format downstream/submodule "$OTHER_FORMAT"
 '
 
+test_expect_success 'status with mixed submodule ref storages' '
+	test_when_finished "rm -rf submodule main" &&
+
+	git init submodule &&
+	test_commit -C submodule submodule-initial &&
+	git init main &&
+	git -C main submodule add "file://$(pwd)/submodule" &&
+	git -C main commit -m "add submodule" &&
+	git -C main/submodule refs migrate --ref-format=$OTHER_FORMAT &&
+
+	# The main repository should use the default ref format now, whereas
+	# the submodule should use the other format.
+	test_ref_format main "$GIT_DEFAULT_REF_FORMAT" &&
+	test_ref_format main/submodule "$OTHER_FORMAT" &&
+
+	cat >expect <<-EOF &&
+	 $(git -C main/submodule rev-parse HEAD) submodule (submodule-initial)
+	EOF
+	git -C main submodule status >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'recursive pull with mixed formats' '
+	test_when_finished "rm -rf submodule upstream downstream" &&
+
+	# Set up the initial structure with an upstream repository that has a
+	# submodule, as well as a downstream clone of the upstream repository.
+	git init submodule &&
+	test_commit -C submodule submodule-initial &&
+	git init upstream &&
+	git -C upstream submodule add "file://$(pwd)/submodule" &&
+	git -C upstream commit -m "upstream submodule" &&
+
+	# Clone the upstream repository such that the main repo and its
+	# submodules have different formats.
+	git clone --no-recurse-submodules "file://$(pwd)/upstream" downstream &&
+	git -C downstream submodule update --init --ref-format=$OTHER_FORMAT &&
+	test_ref_format downstream "$GIT_DEFAULT_REF_FORMAT" &&
+	test_ref_format downstream/submodule "$OTHER_FORMAT" &&
+
+	# Update the upstream submodule as well as the owning repository such
+	# that we can do a recursive pull.
+	test_commit -C submodule submodule-update &&
+	git -C upstream/submodule pull &&
+	git -C upstream commit -am "update the submodule" &&
+
+	git -C downstream pull --recurse-submodules &&
+	git -C upstream/submodule rev-parse HEAD >expect &&
+	git -C downstream/submodule rev-parse HEAD >actual &&
+	test_cmp expect actual
+'
+
 done
 
 test_done
-- 
2.46.0.dirty
Previous: Junio C HamanoNext: Patrick Steinhardt
Message 17 of 35 in “2.46 submodule breakage”
  1. Jeppe ØlandAug 5, 2024
  2. Jeppe ØlandAug 6, 2024
  3. Eric SunshineAug 6, 2024
  4. Patrick SteinhardtAug 7, 2024
  5. Patrick SteinhardtAug 7, 2024
  6. Junio C HamanoAug 7, 2024
  7. 0/6 Improvements for ref storage formats with submodulesPatrick Steinhardt, Aug 7, 2024
  8. 1/6 builtin/submodule: allow cloning with different ref storage formatPatrick Steinhardt, Aug 7, 2024
  9. Jeppe ØlandAug 7, 2024
  10. Junio C HamanoAug 7, 2024
  11. Patrick SteinhardtAug 8, 2024
  12. Junio C HamanoAug 8, 2024
  13. Patrick SteinhardtAug 8, 2024
  14. Junio C HamanoAug 8, 2024
  15. 2/6 builtin/clone: propagate ref storage format to submodulesPatrick Steinhardt, Aug 7, 2024
  16. Junio C HamanoAug 7, 2024
  17. 3/6 refs: fix ref storage format for submodule ref storesPatrick Steinhardt, Aug 7, 2024
  18. 4/6 submodule: fix leaking fetch tasksPatrick Steinhardt, Aug 7, 2024
  19. 5/6 submodule: fix leaking seen submodule namesPatrick Steinhardt, Aug 7, 2024
  20. 6/6 object: fix leaking packfiles when closing object storePatrick Steinhardt, Aug 7, 2024
  21. Patrick SteinhardtAug 7, 2024
  22. Junio C HamanoAug 8, 2024
  23. Patrick SteinhardtAug 8, 2024
  24. 0/8 Improvements for ref storage formats with submodulesPatrick Steinhardt, Aug 8, 2024
  25. 1/8 git-submodule.sh: break overly long command linesPatrick Steinhardt, Aug 8, 2024
  26. 2/8 builtin/submodule: allow cloning with different ref storage formatPatrick Steinhardt, Aug 8, 2024
  27. 3/8 builtin/clone: propagate ref storage format to submodulesPatrick Steinhardt, Aug 8, 2024
  28. Kristoffer HaugsbakkAug 8, 2024
  29. Patrick SteinhardtAug 8, 2024
  30. 4/8 refs: fix ref storage format for submodule ref storesPatrick Steinhardt, Aug 8, 2024
  31. 5/8 builtin/submodule: allow "add" to use different ref storage formatPatrick Steinhardt, Aug 8, 2024
  32. 6/8 submodule: fix leaking fetch tasksPatrick Steinhardt, Aug 8, 2024
  33. 7/8 submodule: fix leaking seen submodule namesPatrick Steinhardt, Aug 8, 2024
  34. 8/8 object: fix leaking packfiles when closing object storePatrick Steinhardt, Aug 8, 2024
  35. Junio C HamanoAug 8, 2024

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.