Skip to content

Commit fb99dde

Browse files
pks-tgitster
authored andcommitted
refs: fix ref storage format for submodule ref stores
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' The same issue occurs when adding a repository contained in the working tree with a different ref storage format via `git submodule add`. Fix the bug by using the submodule repository's ref storage format instead and add some tests. Note that the test for `git submodule status` was included as a precaution, only. The command worked alright even without the bugfix. Reported-by: Jeppe Øland <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6981484 commit fb99dde

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2011,7 +2011,7 @@ struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
20112011
free(subrepo);
20122012
goto done;
20132013
}
2014-
refs = ref_store_init(subrepo, the_repository->ref_storage_format,
2014+
refs = ref_store_init(subrepo, subrepo->ref_storage_format,
20152015
submodule_sb.buf,
20162016
REF_STORE_READ | REF_STORE_ODB);
20172017
register_ref_store_map(&repo->submodule_ref_stores, "submodule",

t/t7424-submodule-mixed-ref-formats.sh

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,23 @@ do
1818
fi
1919

2020
test_expect_success 'setup' '
21-
git config set --global protocol.file.allow always
21+
git config set --global protocol.file.allow always &&
22+
# Some tests migrate the ref storage format, which does not work with
23+
# reflogs at the time of writing these tests.
24+
git config set --global core.logAllRefUpdates false
25+
'
26+
27+
test_expect_success 'add existing repository with different ref storage format' '
28+
test_when_finished "rm -rf parent" &&
29+
30+
git init parent &&
31+
(
32+
cd parent &&
33+
test_commit parent &&
34+
git init --ref-format=$OTHER_FORMAT submodule &&
35+
test_commit -C submodule submodule &&
36+
git submodule add ./submodule
37+
)
2238
'
2339

2440
test_expect_success 'recursive clone propagates ref storage format' '
@@ -59,6 +75,58 @@ test_expect_success 'clone submodules with different ref storage format' '
5975
test_ref_format downstream/submodule "$OTHER_FORMAT"
6076
'
6177

78+
test_expect_success 'status with mixed submodule ref storages' '
79+
test_when_finished "rm -rf submodule main" &&
80+
81+
git init submodule &&
82+
test_commit -C submodule submodule-initial &&
83+
git init main &&
84+
git -C main submodule add "file://$(pwd)/submodule" &&
85+
git -C main commit -m "add submodule" &&
86+
git -C main/submodule refs migrate --ref-format=$OTHER_FORMAT &&
87+
88+
# The main repository should use the default ref format now, whereas
89+
# the submodule should use the other format.
90+
test_ref_format main "$GIT_DEFAULT_REF_FORMAT" &&
91+
test_ref_format main/submodule "$OTHER_FORMAT" &&
92+
93+
cat >expect <<-EOF &&
94+
$(git -C main/submodule rev-parse HEAD) submodule (submodule-initial)
95+
EOF
96+
git -C main submodule status >actual &&
97+
test_cmp expect actual
98+
'
99+
100+
test_expect_success 'recursive pull with mixed formats' '
101+
test_when_finished "rm -rf submodule upstream downstream" &&
102+
103+
# Set up the initial structure with an upstream repository that has a
104+
# submodule, as well as a downstream clone of the upstream repository.
105+
git init submodule &&
106+
test_commit -C submodule submodule-initial &&
107+
git init upstream &&
108+
git -C upstream submodule add "file://$(pwd)/submodule" &&
109+
git -C upstream commit -m "upstream submodule" &&
110+
111+
# Clone the upstream repository such that the main repo and its
112+
# submodules have different formats.
113+
git clone --no-recurse-submodules "file://$(pwd)/upstream" downstream &&
114+
git -C downstream submodule update --init --ref-format=$OTHER_FORMAT &&
115+
test_ref_format downstream "$GIT_DEFAULT_REF_FORMAT" &&
116+
test_ref_format downstream/submodule "$OTHER_FORMAT" &&
117+
118+
# Update the upstream submodule as well as the owning repository such
119+
# that we can do a recursive pull.
120+
test_commit -C submodule submodule-update &&
121+
git -C upstream/submodule pull &&
122+
git -C upstream commit -am "update the submodule" &&
123+
124+
git -C downstream pull --recurse-submodules &&
125+
git -C upstream/submodule rev-parse HEAD >expect &&
126+
git -C downstream/submodule rev-parse HEAD >actual &&
127+
test_cmp expect actual
128+
'
129+
62130
done
63131

64132
test_done

0 commit comments

Comments
 (0)