From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Ramsay Jones <ramsay@ramsayjones.plus.com>,
"D. Ben Knoble" <ben.knoble@gmail.com>,
Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
Marc Branchaud <marcnarc@gmail.com>,
Phillip Wood <phillip.wood123@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v13 0/2] checkout: --track=fetch
Date: Sat, 23 May 2026 19:48:32 +0000 [thread overview]
Message-ID: <pull.2281.v13.git.git.1779565714.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2281.v12.git.git.1779358803652.gitgitgadget@gmail.com>
* Create a preparatory commit that exposes find_tracking_remote_for_ref()
and advise_ambiguous_fetch_refspec() from branch.c, so checkout can reuse
the same lookup git branch --track uses.
* Use advise_ambiguous_fetch_refspec() for the "multiple remotes match"
case, so the wording matches git branch --track.
Harald Nordgren (2):
branch: expose helpers for finding the remote owning a tracking ref
checkout: extend --track with a "fetch" mode to refresh start-point
Documentation/git-checkout.adoc | 17 +-
Documentation/git-switch.adoc | 5 +-
branch.c | 96 ++++++-----
branch.h | 16 ++
builtin/checkout.c | 139 +++++++++++++++-
t/t7201-co.sh | 276 ++++++++++++++++++++++++++++++++
6 files changed, 498 insertions(+), 51 deletions(-)
base-commit: aec3f587505a472db67e9462d0702e7d463a449d
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2281%2FHaraldNordgren%2Fcheckout-fetch-start-point-v13
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2281/HaraldNordgren/checkout-fetch-start-point-v13
Pull-Request: https://github.com/git/git/pull/2281
Range-diff vs v12:
-: ---------- > 1: 2369afad24 branch: expose helpers for finding the remote owning a tracking ref
1: bcd034dbed ! 2: 60adf0e67d checkout: extend --track with a "fetch" mode to refresh start-point
@@ Commit message
git checkout -b new_branch --track origin/some-branch
Identify the remote whose configured fetch refspec maps to
- <start-point>, then run "git fetch <remote> <src-ref>" for just that
- ref so other remote-tracking branches are left untouched. When
- <start-point> is a bare <remote> (e.g. "origin"), follow
+ <start-point> using find_tracking_remote_for_ref() (the same lookup
+ "--track" uses to pick which remote to record in
+ branch.<name>.remote), then run "git fetch <remote> <src-ref>" for
+ just that ref so other remote-tracking branches are left untouched.
+ When <start-point> is a bare <remote> (e.g. "origin"), follow
refs/remotes/<remote>/HEAD to learn which branch to refresh. If
"git fetch" fails but the remote-tracking ref already exists locally,
warn and proceed from the existing tip; otherwise abort.
@@ builtin/checkout.c: struct branch_info {
char *checkout;
};
-+struct fetch_target_cb {
-+ char *dst;
-+ struct string_list matches;
-+};
-+
-+static int match_fetch_target(struct remote *remote, void *priv)
-+{
-+ struct fetch_target_cb *cb = priv;
-+ struct refspec_item q = { .dst = cb->dst };
-+
-+ if (!remote_find_tracking(remote, &q) && q.src)
-+ string_list_append(&cb->matches, remote->name)->util = q.src;
-+ return 0;
-+}
-+
+static void fetch_remote_for_start_point(const char *arg, int quiet)
+{
+ struct strbuf dst = STRBUF_INIT;
-+ struct fetch_target_cb cb = { .matches = STRING_LIST_INIT_NODUP };
++ struct tracking tracking;
++ struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
++ struct string_list ambiguous_remotes = STRING_LIST_INIT_DUP;
+ struct child_process cmd = CHILD_PROCESS_INIT;
+ struct object_id oid;
+ struct remote *named_remote;
+ int bare_ns;
-+ size_t i;
+
+ strbuf_addf(&dst, "refs/remotes/%s", arg);
+ if (check_refname_format(dst.buf, 0))
@@ builtin/checkout.c: struct branch_info {
+ free(head_path);
+ }
+
-+ cb.dst = dst.buf;
-+ for_each_remote(match_fetch_target, &cb);
-+
-+ if (cb.matches.nr > 1) {
-+ struct strbuf msg = STRBUF_INIT;
-+
-+ strbuf_addf(&msg,
-+ _("cannot fetch start-point '%s': fetch refspecs "
-+ "of multiple remotes map to the same destination:"),
-+ arg);
-+ for (i = 0; i < cb.matches.nr; i++)
-+ strbuf_addf(&msg, "\n %s", cb.matches.items[i].string);
-+ strbuf_addstr(&msg,
-+ _("\nadjust 'remote.<name>.fetch' so only one "
-+ "remote maps there, or omit '=fetch'"));
-+ die("%s", msg.buf);
++ memset(&tracking, 0, sizeof(tracking));
++ tracking.spec.dst = dst.buf;
++ tracking.srcs = &tracking_srcs;
++ find_tracking_remote_for_ref(&tracking, &ambiguous_remotes);
++
++ if (tracking.matches > 1) {
++ int status = die_message(_("cannot fetch start-point '%s': "
++ "fetch refspecs of multiple remotes "
++ "map to '%s'"), arg, dst.buf);
++ advise_ambiguous_fetch_refspec(dst.buf, &ambiguous_remotes);
++ exit(status);
+ }
+
-+ if (!cb.matches.nr) {
++ if (!tracking.matches) {
+ if (bare_ns && named_remote &&
+ remote_is_configured(named_remote, 1))
+ die(_("cannot fetch start-point '%s': "
@@ builtin/checkout.c: struct branch_info {
+ strvec_push(&cmd.args, "fetch");
+ if (quiet)
+ strvec_push(&cmd.args, "--quiet");
-+ strvec_pushl(&cmd.args, cb.matches.items[0].string,
-+ (char *)cb.matches.items[0].util, NULL);
++ strvec_pushl(&cmd.args, tracking.remote,
++ tracking_srcs.items[0].string, NULL);
+ cmd.git_cmd = 1;
+ if (run_command(&cmd)) {
+ if (!refs_read_ref(get_main_ref_store(the_repository),
@@ builtin/checkout.c: struct branch_info {
+ die(_("failed to fetch start-point '%s'"), arg);
+ }
+
-+ for (i = 0; i < cb.matches.nr; i++)
-+ free(cb.matches.items[i].util);
-+ string_list_clear(&cb.matches, 0);
++ string_list_clear(&tracking_srcs, 0);
++ string_list_clear(&ambiguous_remotes, 0);
+ strbuf_release(&dst);
+}
+
@@ t/t7201-co.sh: test_expect_success 'tracking info copied with autoSetupMerge=inh
+ test_must_fail git checkout --track=fetch -b local_ambig ambig_ns/fetch_ambig 2>err &&
+ test_grep "fetch_ambig_a" err &&
+ test_grep "fetch_ambig_b" err &&
-+ test_grep "remote.<name>.fetch" err &&
++ test_grep "tracking namespaces" err &&
+ test_must_fail git rev-parse --verify refs/heads/local_ambig
+'
+
--
gitgitgadget
next prev parent reply other threads:[~2026-05-23 19:48 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 10:03 [PATCH] checkout: add --fetch to fetch remote before resolving start-point Harald Nordgren via GitGitGadget
2026-04-24 13:48 ` Ramsay Jones
2026-04-24 17:12 ` D. Ben Knoble
2026-04-25 17:24 ` Comments on Phillip's review Harald Nordgren
2026-04-25 17:44 ` Wrong subject line Harald Nordgren
2026-04-24 17:38 ` [PATCH] checkout: add --fetch to fetch remote before resolving start-point Kristoffer Haugsbakk
2026-04-25 17:41 ` Comments on Phillip's review Harald Nordgren
2026-04-25 17:44 ` Wrong subject line Harald Nordgren
2026-04-26 7:07 ` Kristoffer Haugsbakk
2026-04-26 15:15 ` [PATCH] remote: add --set-head option to 'git remote add' Harald Nordgren
2026-04-24 17:42 ` [PATCH] checkout: add --fetch to fetch remote before resolving start-point Marc Branchaud
2026-04-25 17:48 ` Wrong subject line Harald Nordgren
2026-04-24 22:21 ` [PATCH] checkout: add --fetch to fetch remote before resolving start-point Junio C Hamano
2026-04-25 2:54 ` Junio C Hamano
2026-04-25 17:58 ` Multiple remotes Harald Nordgren
2026-04-25 21:57 ` Ben Knoble
2026-04-25 22:54 ` gh Harald Nordgren
2026-04-25 18:12 ` [PATCH v2] checkout: add --fetch to fetch remote before resolving start-point Harald Nordgren via GitGitGadget
2026-04-26 7:24 ` [PATCH v3] " Harald Nordgren via GitGitGadget
2026-04-26 15:54 ` Ramsay Jones
2026-04-26 18:32 ` [PATCH v4] " Harald Nordgren via GitGitGadget
2026-04-28 1:47 ` Junio C Hamano
2026-04-28 8:44 ` [PATCH] " Harald Nordgren
2026-04-28 9:03 ` [PATCH v5] checkout: extend --track with a "fetch" mode to refresh start-point Harald Nordgren via GitGitGadget
2026-05-03 20:59 ` Junio C Hamano
2026-05-03 22:32 ` [PATCH] checkout: add --autostash option for branch switching Harald Nordgren
2026-05-03 22:31 ` [PATCH v6] checkout: extend --track with a "fetch" mode to refresh start-point Harald Nordgren via GitGitGadget
2026-05-07 20:12 ` Harald Nordgren
2026-05-08 13:15 ` Phillip Wood
2026-05-08 22:40 ` [PATCH] checkout: add --fetch to fetch remote before resolving start-point Harald Nordgren
2026-05-08 22:52 ` [PATCH v7] checkout: extend --track with a "fetch" mode to refresh start-point Harald Nordgren via GitGitGadget
2026-05-11 13:16 ` Phillip Wood
2026-05-11 13:47 ` [PATCH v8] " Harald Nordgren via GitGitGadget
2026-05-12 0:32 ` Junio C Hamano
2026-05-18 8:06 ` Harald Nordgren
2026-05-12 10:55 ` [PATCH v9] " Harald Nordgren via GitGitGadget
2026-05-18 8:04 ` [PATCH v10] " Harald Nordgren via GitGitGadget
2026-05-19 6:16 ` Junio C Hamano
2026-05-19 7:52 ` Harald Nordgren
2026-05-19 8:16 ` Junio C Hamano
2026-05-19 8:32 ` Harald Nordgren
2026-05-19 8:38 ` Harald Nordgren
2026-05-19 7:58 ` [PATCH v11] " Harald Nordgren via GitGitGadget
2026-05-19 10:34 ` Junio C Hamano
2026-05-21 9:49 ` Phillip Wood
2026-05-21 10:24 ` Harald Nordgren
2026-05-21 12:58 ` Junio C Hamano
2026-05-21 14:06 ` Phillip Wood
2026-05-21 23:53 ` Junio C Hamano
2026-05-21 10:20 ` [PATCH v12] " Harald Nordgren via GitGitGadget
2026-05-23 19:48 ` Harald Nordgren via GitGitGadget [this message]
2026-05-23 19:48 ` [PATCH v13 1/2] branch: expose helpers for finding the remote owning a tracking ref Harald Nordgren via GitGitGadget
2026-05-23 19:48 ` [PATCH v13 2/2] checkout: extend --track with a "fetch" mode to refresh start-point Harald Nordgren via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.2281.v13.git.git.1779565714.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=ben.knoble@gmail.com \
--cc=git@vger.kernel.org \
--cc=haraldnordgren@gmail.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=marcnarc@gmail.com \
--cc=phillip.wood123@gmail.com \
--cc=ramsay@ramsayjones.plus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox