From 2de26ae1dc89236ff5d0d0657b0eb884b6c331b5 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 28 Jul 2016 17:44:06 -0700 Subject: submodule--helper: fix usage string for relative-path Internally we call the underscore version of relative_path, but externally we present an API with no underscores. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- builtin/submodule--helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/submodule--helper.c') diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b22352b6e1..fb90c64832 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -892,7 +892,7 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix { struct strbuf sb = STRBUF_INIT; if (argc != 3) - die("submodule--helper relative_path takes exactly 2 arguments, got %d", argc); + die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); printf("%s", relative_path(argv[1], argv[2], &sb)); strbuf_release(&sb); -- cgit 1.2.3-korg From 92bbe7ccf1fedac825f2c6ab4c8de91dc5370fd2 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 3 Aug 2016 13:44:03 -0700 Subject: submodule--helper: add remote-branch helper In a later patch we want to enhance the logic for the branch selection. Rewrite the current logic to be in C, so we can directly use C when we enhance the logic. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- builtin/submodule--helper.c | 36 +++++++++++++++++++++++++++++++++++- git-submodule.sh | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'builtin/submodule--helper.c') diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index fb90c64832..9be2c75e0e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -899,6 +899,39 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix return 0; } +static const char *remote_submodule_branch(const char *path) +{ + const struct submodule *sub; + gitmodules_config(); + git_config(submodule_config, NULL); + + sub = submodule_from_path(null_sha1, path); + if (!sub) + return NULL; + + if (!sub->branch) + return "master"; + + return sub->branch; +} + +static int resolve_remote_submodule_branch(int argc, const char **argv, + const char *prefix) +{ + const char *ret; + struct strbuf sb = STRBUF_INIT; + if (argc != 2) + die("submodule--helper remote-branch takes exactly one arguments, got %d", argc); + + ret = remote_submodule_branch(argv[1]); + if (!ret) + die("submodule %s doesn't exist", argv[1]); + + printf("%s", ret); + strbuf_release(&sb); + return 0; +} + struct cmd_struct { const char *cmd; int (*fn)(int, const char **, const char *); @@ -912,7 +945,8 @@ static struct cmd_struct commands[] = { {"relative-path", resolve_relative_path}, {"resolve-relative-url", resolve_relative_url}, {"resolve-relative-url-test", resolve_relative_url_test}, - {"init", module_init} + {"init", module_init}, + {"remote-branch", resolve_remote_submodule_branch} }; int cmd_submodule__helper(int argc, const char **argv, const char *prefix) diff --git a/git-submodule.sh b/git-submodule.sh index 41aff65fac..8c5e8982ab 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -614,7 +614,7 @@ cmd_update() if test -n "$remote" then - branch=$(get_submodule_config "$name" branch master) + branch=$(git submodule--helper remote-branch "$sm_path") if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 -- cgit 1.2.3-korg From 4d7bc52b178bffe9e484c4dcd92d5353e2ce716f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 3 Aug 2016 13:44:04 -0700 Subject: 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 submodule update --remote --force git -C commit -a -m "Update submodules" git -C push done for each branch in the superproject. To ease the configuration in Gerrit a special value of "." has been introduced for the submodule..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 Signed-off-by: Junio C Hamano --- builtin/submodule--helper.c | 18 ++++++++++++++++++ t/t7406-submodule-update.sh | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'builtin/submodule--helper.c') diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9be2c75e0e..f1acc4dc96 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -912,6 +912,24 @@ static const char *remote_submodule_branch(const char *path) if (!sub->branch) return "master"; + if (!strcmp(sub->branch, ".")) { + unsigned char sha1[20]; + const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); + + if (!refname) + die(_("No such ref: %s"), "HEAD"); + + /* detached HEAD */ + if (!strcmp(refname, "HEAD")) + die(_("Submodule (%s) branch configured to inherit " + "branch from superproject, but the superproject " + "is not on any branch"), sub->name); + + if (!skip_prefix(refname, "refs/heads/", &refname)) + die(_("Expecting a full ref name, got %s"), refname); + return refname; + } + return sub->branch; } diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 1bb1f43824..d7983cf09f 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -209,9 +209,42 @@ test_expect_success 'submodule update --remote should fetch upstream changes' ' ) ' +test_expect_success 'submodule update --remote should fetch upstream changes with .' ' + ( + cd super && + git config -f .gitmodules submodule."submodule".branch "." && + git add .gitmodules && + git commit -m "submodules: update from the respective superproject branch" + ) && + ( + cd submodule && + echo line4a >> file && + git add file && + test_tick && + git commit -m "upstream line4a" && + git checkout -b test-branch && + test_commit on-test-branch + ) && + ( + cd super && + git submodule update --remote --force submodule && + git -C submodule log -1 --oneline >actual + git -C ../submodule log -1 --oneline master >expect + test_cmp expect actual && + git checkout -b test-branch && + git submodule update --remote --force submodule && + git -C submodule log -1 --oneline >actual + git -C ../submodule log -1 --oneline test-branch >expect + test_cmp expect actual && + git checkout master && + git branch -d test-branch && + git reset --hard HEAD^ + ) +' + test_expect_success 'local config should override .gitmodules branch' ' (cd submodule && - git checkout -b test-branch && + git checkout test-branch && echo line5 >> file && git add file && test_tick && -- cgit 1.2.3-korg