From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Simon Cheng <cyqsimon@gmail.com>,
Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>
Subject: [PATCH v2 2/2] checkout: tell "parse_remote_branch" which command is calling it
Date: Thu, 29 Jan 2026 11:06:16 -0800 [thread overview]
Message-ID: <20260129190616.645471-3-gitster@pobox.com> (raw)
In-Reply-To: <20260129190616.645471-1-gitster@pobox.com>
When "git checkout <dwim>" and "git switch <dwim>" need to error out
due to ambiguity of the branch name <dwim>, these two commands give
an advise message with a sample command that tells the user how to
disambiguate from the parse_remote_branch() function. The sample
command hardcodes "git checkout", since this feature predates "git
switch" by a large margin. To a user who said "git switch <dwim>"
and got this message, it is confusing.
Pass the "enum checkout_command", which was invented in the previous
step for this exact purpose, down the call chain leading to
parse_remote_branch() function to change the sample command shown to
the user in this advise message.
Also add a bit more test coverage for this "fail to DWIM under
ambiguity" that we lack, as well as the message we produce when we
fail.
Reported-by: Simon Cheng <cyqsimon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/checkout.c | 29 ++++++++++++++++++++++++-----
t/t2027-checkout-track.sh | 18 ++++++++++++++++++
2 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 4f189fde48..17f31c30b2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1286,7 +1286,8 @@ enum checkout_command {
static char *parse_remote_branch(const char *arg,
struct object_id *rev,
- int could_be_checkout_paths)
+ int could_be_checkout_paths,
+ enum checkout_command which_command)
{
int num_matches = 0;
char *remote = unique_tracking_name(arg, rev, &num_matches);
@@ -1299,14 +1300,30 @@ static char *parse_remote_branch(const char *arg,
if (!remote && num_matches > 1) {
if (advice_enabled(ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME)) {
+ const char *cmdname;
+
+ switch (which_command) {
+ case CHECKOUT_CHECKOUT:
+ cmdname = "checkout";
+ break;
+ case CHECKOUT_SWITCH:
+ cmdname = "switch";
+ break;
+ default:
+ BUG("command <%d> should not reach parse_remote_branch",
+ which_command);
+ break;
+ }
+
advise(_("If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
"you can do so by fully qualifying the name with the --track option:\n"
"\n"
- " git checkout --track origin/<name>\n"
+ " git %s --track origin/<name>\n"
"\n"
"If you'd like to always have checkouts of an ambiguous <name> prefer\n"
"one remote, e.g. the 'origin' remote, consider setting\n"
- "checkout.defaultRemote=origin in your config."));
+ "checkout.defaultRemote=origin in your config."),
+ cmdname);
}
die(_("'%s' matched multiple (%d) remote tracking branches"),
@@ -1318,6 +1335,7 @@ static char *parse_remote_branch(const char *arg,
static int parse_branchname_arg(int argc, const char **argv,
int dwim_new_local_branch_ok,
+ enum checkout_command which_command,
struct branch_info *new_branch_info,
struct checkout_opts *opts,
struct object_id *rev)
@@ -1427,7 +1445,8 @@ static int parse_branchname_arg(int argc, const char **argv,
if (recover_with_dwim) {
remote = parse_remote_branch(arg, rev,
- could_be_checkout_paths);
+ could_be_checkout_paths,
+ which_command);
if (remote) {
*new_branch = arg;
arg = remote;
@@ -1916,7 +1935,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
opts->dwim_new_local_branch &&
opts->track == BRANCH_TRACK_UNSPECIFIED &&
!opts->new_branch;
- int n = parse_branchname_arg(argc, argv, dwim_ok,
+ int n = parse_branchname_arg(argc, argv, dwim_ok, which_command,
&new_branch_info, opts, &rev);
argv += n;
argc -= n;
diff --git a/t/t2027-checkout-track.sh b/t/t2027-checkout-track.sh
index a397790df5..c01f1cd617 100755
--- a/t/t2027-checkout-track.sh
+++ b/t/t2027-checkout-track.sh
@@ -47,4 +47,22 @@ test_expect_success 'checkout --track -b overrides autoSetupMerge=inherit' '
test_cmp_config refs/heads/main branch.b4.merge
'
+test_expect_success 'ambiguous tracking info' '
+ # Set up a few remote repositories
+ git init --bare --initial-branch=trunk src1 &&
+ git init --bare --initial-branch=trunk src2 &&
+ git push src1 one:refs/heads/trunk &&
+ git push src2 two:refs/heads/trunk &&
+
+ git remote add -f src1 "file://$PWD/src1" &&
+ git remote add -f src2 "file://$PWD/src2" &&
+
+ # DWIM
+ test_must_fail git checkout trunk 2>hint.checkout &&
+ test_grep "hint: *git checkout --track" hint.checkout &&
+
+ test_must_fail git switch trunk 2>hint.switch &&
+ test_grep "hint: *git switch --track" hint.switch
+'
+
test_done
--
2.53.0-rc2-135-gb1217c0133
next prev parent reply other threads:[~2026-01-29 19:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-27 19:29 [PATCH 0/2] Improving advise messages from "switch" Junio C Hamano
2026-01-27 19:29 ` [PATCH 1/2] checkout: pass program-readable token to unified "main" Junio C Hamano
2026-01-27 19:29 ` [PATCH 2/2] checkout: tell "parse_remote_branch" which command is calling it Junio C Hamano
2026-01-27 20:35 ` Kristoffer Haugsbakk
2026-01-27 21:22 ` Junio C Hamano
2026-01-29 19:06 ` [PATCH v2 0/2] Improving advise messages from "switch" Junio C Hamano
2026-01-29 19:06 ` [PATCH v2 1/2] checkout: pass program-readable token to unified "main" Junio C Hamano
2026-02-06 16:05 ` Patrick Steinhardt
2026-02-19 22:21 ` Junio C Hamano
2026-01-29 19:06 ` Junio C Hamano [this message]
2026-02-06 16:05 ` [PATCH v2 2/2] checkout: tell "parse_remote_branch" which command is calling it Patrick Steinhardt
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=20260129190616.645471-3-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=cyqsimon@gmail.com \
--cc=git@vger.kernel.org \
--cc=kristofferhaugsbakk@fastmail.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