branch: support more tracking modes when recursing
"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>
Glen Choo committedMar 29, 2022 at 20:01 UTC75388bf5b47678c95f24b58007d2b37d744bf0f7
3 files changed+67-7
branch.c
+26-3
index 47251669e1..608db0fc91 100644--- 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(
builtin/submodule--helper.c
+4-3
index 44b6283c08..09fef496a7 100644--- a/builtin/submodule--helper.c+++ b/builtin/submodule--helper.c@@ -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()
t/t3207-branch-submodule.sh
+37-1
index 6ef2733396..cce5711b05 100755--- a/t/t3207-branch-submodule.sh+++ b/t/t3207-branch-submodule.sh@@ -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