git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 18:00 UTC

[PATCH v13 0/2] checkout: --track=fetch

From
Harald Nordgren via GitGitGadget <gitgitgadget@gmail.com>
Date
May 23, 2026, 19:48 UTC
Message-ID
<pull.2281.v13.git.git.1779565714.gitgitgadget@gmail.com>
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
Previous: Junio C HamanoNext: Harald Nordgren via GitGitGadget
Message 51 of 73 in “checkout: add --fetch to fetch remote before resolving start-point”
  1. checkout: add --fetch to fetch remote before resolving start-pointHarald Nordgren via GitGitGadget, Apr 24, 2026
  2. Ramsay JonesApr 24, 2026
  3. D. Ben KnobleApr 24, 2026
  4. Kristoffer HaugsbakkApr 24, 2026
  5. Marc BranchaudApr 24, 2026
  6. Junio C HamanoApr 24, 2026
  7. Junio C HamanoApr 25, 2026
  8. Comments on Phillip's reviewHarald Nordgren, Apr 25, 2026
  9. Comments on Phillip's reviewHarald Nordgren, Apr 25, 2026
  10. Wrong subject lineHarald Nordgren, Apr 25, 2026
  11. Wrong subject lineHarald Nordgren, Apr 25, 2026
  12. Wrong subject lineHarald Nordgren, Apr 25, 2026
  13. Multiple remotesHarald Nordgren, Apr 25, 2026
  14. checkout: add --fetch to fetch remote before resolving start-pointHarald Nordgren via GitGitGadget, Apr 25, 2026
  15. Ben KnobleApr 25, 2026
  16. ghHarald Nordgren, Apr 25, 2026
  17. Kristoffer HaugsbakkApr 26, 2026
  18. checkout: add --fetch to fetch remote before resolving start-pointHarald Nordgren via GitGitGadget, Apr 26, 2026
  19. Harald NordgrenApr 26, 2026
  20. Ramsay JonesApr 26, 2026
  21. checkout: add --fetch to fetch remote before resolving start-pointHarald Nordgren via GitGitGadget, Apr 26, 2026
  22. Junio C HamanoApr 28, 2026
  23. Harald NordgrenApr 28, 2026
  24. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, Apr 28, 2026
  25. Junio C HamanoMay 3, 2026
  26. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 3, 2026
  27. checkout: add --autostash option for branch switchingHarald Nordgren, May 3, 2026
  28. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren, May 7, 2026
  29. Phillip WoodMay 8, 2026
  30. checkout: add --fetch to fetch remote before resolving start-pointHarald Nordgren, May 8, 2026
  31. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 8, 2026
  32. Phillip WoodMay 11, 2026
  33. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 11, 2026
  34. Junio C HamanoMay 12, 2026
  35. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 12, 2026
  36. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 18, 2026
  37. Harald NordgrenMay 18, 2026
  38. Junio C HamanoMay 19, 2026
  39. Harald NordgrenMay 19, 2026
  40. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 19, 2026
  41. Junio C HamanoMay 19, 2026
  42. Harald NordgrenMay 19, 2026
  43. Harald NordgrenMay 19, 2026
  44. Junio C HamanoMay 19, 2026
  45. Phillip WoodMay 21, 2026
  46. checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 21, 2026
  47. Harald NordgrenMay 21, 2026
  48. Junio C HamanoMay 21, 2026
  49. Phillip WoodMay 21, 2026
  50. Junio C HamanoMay 21, 2026
  51. 0/2 checkout: --track=fetchHarald Nordgren via GitGitGadget, May 23, 2026
  52. 1/2 branch: expose helpers for finding the remote owning a tracking refHarald Nordgren via GitGitGadget, May 23, 2026
  53. 2/2 checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, May 23, 2026
  54. Harald NordgrenJun 13, 2026
  55. Junio C HamanoJun 17, 2026
  56. Harald NordgrenJun 17, 2026
  57. Junio C HamanoJun 18, 2026
  58. Harald NordgrenJun 18, 2026
  59. Harald NordgrenJun 18, 2026
  60. 0/2 checkout: --track=fetchHarald Nordgren via GitGitGadget, Jun 18, 2026
  61. 1/2 branch: expose helpers for finding the remote owning a tracking refHarald Nordgren via GitGitGadget, Jun 18, 2026
  62. 2/2 checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, Jun 18, 2026
  63. D. Ben KnobleJun 18, 2026
  64. Phillip WoodJun 23, 2026
  65. Harald NordgrenJun 23, 2026
  66. 0/2 checkout: --track=fetchHarald Nordgren via GitGitGadget, Jun 24, 2026
  67. 1/2 branch: expose helpers for finding the remote owning a tracking refHarald Nordgren via GitGitGadget, Jun 24, 2026
  68. 2/2 checkout: extend --track with a "fetch" mode to refresh start-pointHarald Nordgren via GitGitGadget, Jun 24, 2026
  69. Junio C HamanoJun 24, 2026
  70. Ben KnobleJun 25, 2026
  71. Harald NordgrenJun 25, 2026
  72. Kristofer KarlssonJun 25, 2026
  73. Junio C HamanoJul 23, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.