Skip to content

Commit 4d7bc52

Browse files
stefanbellergitster
authored andcommitted
submodule update: allow '.' for branch value
Gerrit has a "superproject subscription" feature[1], that triggers a commit in a superproject that is subscribed to its submodules. Conceptually this Gerrit feature can be done on the client side with Git via (except for raciness, error handling etc): while [ true ]; do git -C <superproject> submodule update --remote --force git -C <superproject> commit -a -m "Update submodules" git -C <superproject> push done for each branch in the superproject. To ease the configuration in Gerrit a special value of "." has been introduced for the submodule.<name>.branch to mean the same branch as the superproject[2], such that you can create a new branch on both superproject and the submodule and this feature continues to work on that new branch. Now we find projects in the wild with such a .gitmodules file. The .gitmodules used in these Gerrit projects do not conform to Gits understanding of how .gitmodules should look like. This teaches Git to deal gracefully with this syntax as well. The redefinition of "." does no harm to existing projects unaware of this change, as "." is an invalid branch name in Git, so we do not expect such projects to exist. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 92bbe7c commit 4d7bc52

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

builtin/submodule--helper.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,24 @@ static const char *remote_submodule_branch(const char *path)
912912
if (!sub->branch)
913913
return "master";
914914

915+
if (!strcmp(sub->branch, ".")) {
916+
unsigned char sha1[20];
917+
const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
918+
919+
if (!refname)
920+
die(_("No such ref: %s"), "HEAD");
921+
922+
/* detached HEAD */
923+
if (!strcmp(refname, "HEAD"))
924+
die(_("Submodule (%s) branch configured to inherit "
925+
"branch from superproject, but the superproject "
926+
"is not on any branch"), sub->name);
927+
928+
if (!skip_prefix(refname, "refs/heads/", &refname))
929+
die(_("Expecting a full ref name, got %s"), refname);
930+
return refname;
931+
}
932+
915933
return sub->branch;
916934
}
917935

t/t7406-submodule-update.sh

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,42 @@ test_expect_success 'submodule update --remote should fetch upstream changes' '
209209
)
210210
'
211211

212+
test_expect_success 'submodule update --remote should fetch upstream changes with .' '
213+
(
214+
cd super &&
215+
git config -f .gitmodules submodule."submodule".branch "." &&
216+
git add .gitmodules &&
217+
git commit -m "submodules: update from the respective superproject branch"
218+
) &&
219+
(
220+
cd submodule &&
221+
echo line4a >> file &&
222+
git add file &&
223+
test_tick &&
224+
git commit -m "upstream line4a" &&
225+
git checkout -b test-branch &&
226+
test_commit on-test-branch
227+
) &&
228+
(
229+
cd super &&
230+
git submodule update --remote --force submodule &&
231+
git -C submodule log -1 --oneline >actual
232+
git -C ../submodule log -1 --oneline master >expect
233+
test_cmp expect actual &&
234+
git checkout -b test-branch &&
235+
git submodule update --remote --force submodule &&
236+
git -C submodule log -1 --oneline >actual
237+
git -C ../submodule log -1 --oneline test-branch >expect
238+
test_cmp expect actual &&
239+
git checkout master &&
240+
git branch -d test-branch &&
241+
git reset --hard HEAD^
242+
)
243+
'
244+
212245
test_expect_success 'local config should override .gitmodules branch' '
213246
(cd submodule &&
214-
git checkout -b test-branch &&
247+
git checkout test-branch &&
215248
echo line5 >> file &&
216249
git add file &&
217250
test_tick &&

0 commit comments

Comments
 (0)