]> git.ipfire.org Git - thirdparty/git.git/commitdiff
branch: support more tracking modes when recursing
authorGlen Choo <chooglen@google.com>
Tue, 29 Mar 2022 20:01:16 +0000 (20:01 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Mar 2022 20:40:00 +0000 (13:40 -0700)
"git branch --recurse-submodules" does not propagate "--track=inherit"
or "--no-track" to submodules, which causes submodule branches to use
the wrong tracking mode [1]. To fix this, pass the correct options to
the "submodule--helper create-branch" child process and test for it.

While we are refactoring the same code, replace "--track" with the
synonymous, but more consistent-looking "--track=direct" option
(introduced at the same time as "--track=inherit", d3115660b4 (branch:
add flags and config to inherit tracking, 2021-12-20)).

[1] This bug is partially a timing issue: "branch --recurse-submodules"
 was introduced around the same time as "--track=inherit", and even
 though I rebased "branch --recurse-submodules" on top of that, I had
 neglected to support the new tracking mode. Omitting "--no-track"
 was just a plain old mistake, though.

Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
builtin/submodule--helper.c
t/t3207-branch-submodule.sh

index 47251669e1414e99d5b49debe18e3fe6a21cd902..608db0fc91afe69b09ccb5db95bed2ff7bcb63d1 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -233,6 +233,9 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
        struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
        int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
 
+       if (!track)
+               BUG("asked to set up tracking, but tracking is disallowed");
+
        memset(&tracking, 0, sizeof(tracking));
        tracking.spec.dst = (char *)orig_ref;
        tracking.srcs = &tracking_srcs;
@@ -529,8 +532,27 @@ static int submodule_create_branch(struct repository *r,
                strvec_push(&child.args, "--quiet");
        if (reflog)
                strvec_push(&child.args, "--create-reflog");
-       if (track == BRANCH_TRACK_ALWAYS || track == BRANCH_TRACK_EXPLICIT)
-               strvec_push(&child.args, "--track");
+
+       switch (track) {
+       case BRANCH_TRACK_NEVER:
+               strvec_push(&child.args, "--no-track");
+               break;
+       case BRANCH_TRACK_ALWAYS:
+       case BRANCH_TRACK_EXPLICIT:
+               strvec_push(&child.args, "--track=direct");
+               break;
+       case BRANCH_TRACK_OVERRIDE:
+               BUG("BRANCH_TRACK_OVERRIDE cannot be used when creating a branch.");
+               break;
+       case BRANCH_TRACK_INHERIT:
+               strvec_push(&child.args, "--track=inherit");
+               break;
+       case BRANCH_TRACK_UNSPECIFIED:
+               /* Default for "git checkout". No need to pass --track. */
+       case BRANCH_TRACK_REMOTE:
+               /* Default for "git branch". No need to pass --track. */
+               break;
+       }
 
        strvec_pushl(&child.args, name, start_oid, tracking_name, NULL);
 
@@ -609,7 +631,8 @@ void create_branches_recursively(struct repository *r, const char *name,
         * tedious to determine whether or not tracking was set up in the
         * superproject.
         */
-       setup_tracking(name, tracking_name, track, quiet);
+       if (track)
+               setup_tracking(name, tracking_name, track, quiet);
 
        for (i = 0; i < submodule_entry_list.entry_nr; i++) {
                if (submodule_create_branch(
index 44b6283c08ffd043d27219611186d564485a5657..09fef496a7faddc61832dc9c10ba5aa62edfb22a 100644 (file)
@@ -2994,9 +2994,10 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)
                OPT__FORCE(&force, N_("force creation"), 0),
                OPT_BOOL(0, "create-reflog", &reflog,
                         N_("create the branch's reflog")),
-               OPT_SET_INT('t', "track", &track,
-                           N_("set up tracking mode (see git-pull(1))"),
-                           BRANCH_TRACK_EXPLICIT),
+               OPT_CALLBACK_F('t', "track",  &track, "(direct|inherit)",
+                       N_("set branch tracking configuration"),
+                       PARSE_OPT_OPTARG,
+                       parse_opt_tracking_mode),
                OPT__DRY_RUN(&dry_run,
                             N_("show whether the branch would be created")),
                OPT_END()
index 6ef2733396627bd8d30b021a0d329e209f7ca3eb..cce5711b05fe1c8b3aa6d65a657610fa4feaf0b3 100755 (executable)
@@ -260,7 +260,7 @@ test_expect_success 'should get fatal error upon branch creation when submodule
        )
 '
 
-test_expect_success 'should set up tracking of remote-tracking branches' '
+test_expect_success 'should set up tracking of remote-tracking branches by default' '
        test_when_finished "reset_remote_test" &&
        (
                cd super-clone &&
@@ -289,4 +289,40 @@ test_expect_success 'should not fail when unable to set up tracking in submodule
        )
 '
 
+test_expect_success '--track=inherit should set up tracking correctly' '
+       test_when_finished "reset_remote_test" &&
+       (
+               cd super-clone &&
+               git branch --recurse-submodules branch-a origin/branch-a &&
+               # Set this manually instead of using branch --set-upstream-to
+               # to circumvent the "nonexistent upstream" check.
+               git -C sub config branch.branch-a.remote origin &&
+               git -C sub config branch.branch-a.merge refs/heads/sub-branch-a &&
+               git -C sub/sub-sub config branch.branch-a.remote other &&
+               git -C sub/sub-sub config branch.branch-a.merge refs/heads/sub-sub-branch-a &&
+
+               git branch --recurse-submodules --track=inherit branch-b branch-a &&
+               test_cmp_config origin branch.branch-b.remote &&
+               test_cmp_config refs/heads/branch-a branch.branch-b.merge &&
+               test_cmp_config -C sub origin branch.branch-b.remote &&
+               test_cmp_config -C sub refs/heads/sub-branch-a branch.branch-b.merge &&
+               test_cmp_config -C sub/sub-sub other branch.branch-b.remote &&
+               test_cmp_config -C sub/sub-sub refs/heads/sub-sub-branch-a branch.branch-b.merge
+       )
+'
+
+test_expect_success '--no-track should not set up tracking' '
+       test_when_finished "reset_remote_test" &&
+       (
+               cd super-clone &&
+               git branch --recurse-submodules --no-track branch-a origin/branch-a &&
+               test_cmp_config "" --default "" branch.branch-a.remote &&
+               test_cmp_config "" --default "" branch.branch-a.merge &&
+               test_cmp_config -C sub "" --default "" branch.branch-a.remote &&
+               test_cmp_config -C sub "" --default "" branch.branch-a.merge &&
+               test_cmp_config -C sub/sub-sub "" --default "" branch.branch-a.remote &&
+               test_cmp_config -C sub/sub-sub "" --default "" branch.branch-a.merge
+       )
+'
+
 test_done