{"thread":{"id":"64871","subject":"Remote tracking option hint for git-switch still shows git-checkout command","startedAt":"2026-01-27T09:31:18Z","lastAt":"2026-01-27T16:29:35Z","messageCount":2,"participants":["Simon Cheng","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"534705","messageId":"CA+itcS0iyqNyzOP0cueLg7B3yadoEr_VWJ-QoL+YPFUPJiE2RQ@mail.gmail.com","threadId":"64871","inReplyTo":null,"subject":"Remote tracking option hint for git-switch still shows git-checkout command","fromName":"Simon Cheng","fromEmail":"cyqsimon@gmail.com","sentAt":"2026-01-27T09:31:06Z","receivedAt":"2026-01-27T09:31:18Z","isPatch":false,"sender":{"key":"cyqsimon@gmail.com","avatar":null},"body":"When `git-switch my-branch` is unable to guess a unique remote\ntracking branch, the shown hint still displays an example with the\n`git-checkout` command.\n\n❯ git switch my-branch\nhint: If you meant to check out a remote tracking branch on, e.g. 'origin',\nhint: you can do so by fully qualifying the name with the --track option:\nhint:\nhint:     git checkout --track origin/<name>\nhint:\nhint: If you'd like to always have checkouts of an ambiguous <name> prefer\nhint: one remote, e.g. the 'origin' remote, consider setting\nhint: checkout.defaultRemote=origin in your config.\nfatal: 'my-branch' matched multiple (2) remote tracking branches\n\nOf course that works too, but it keeps the user guessing whether the\n`--track` option also exists for `git-switch`. Not to mention that\n`git-checkout` is now largely superseded by `git-switch` and\n`git-restore` and is no longer recommended, as far as I understand it.\n\nSo I think it makes sense to either:\n1. make the recommended command match the one ran by the user, or\n2. always recommend `git-switch` as opposed to `git-checkout`\n\ngit version 2.52.0\ncpu: x86_64\nbuilt from commit: 9a2fb147f2c61d0cab52c883e7e26f5b7948e3ed\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nrust: enabled\nlibcurl: 8.17.0\nOpenSSL: OpenSSL 3.6.0 1 Oct 2025\nzlib-ng: 2.2.5\nSHA-1: SHA1_DC\nSHA-256: SHA256_BLK\ndefault-ref-format: files\ndefault-hash: sha1\n"},{"id":"534715","messageId":"xmqqecnbggsy.fsf@gitster.g","threadId":"64871","inReplyTo":"CA+itcS0iyqNyzOP0cueLg7B3yadoEr_VWJ-QoL+YPFUPJiE2RQ@mail.gmail.com","subject":"Re: Remote tracking option hint for git-switch still shows git-checkout command","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-27T16:29:33Z","receivedAt":"2026-01-27T16:29:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Simon Cheng <cyqsimon@gmail.com> writes:\n\n> When `git-switch my-branch` is unable to guess a unique remote\n> tracking branch, the shown hint still displays an example with the\n> `git-checkout` command.\n>\n> ❯ git switch my-branch\n> hint: If you meant to check out a remote tracking branch on, e.g. 'origin',\n> hint: you can do so by fully qualifying the name with the --track option:\n> hint:\n> hint:     git checkout --track origin/<name>\n> hint:\n> hint: If you'd like to always have checkouts of an ambiguous <name> prefer\n> hint: one remote, e.g. the 'origin' remote, consider setting\n> hint: checkout.defaultRemote=origin in your config.\n> fatal: 'my-branch' matched multiple (2) remote tracking branches\n>\n> Of course that works too, but it keeps the user guessing whether the\n> `--track` option also exists for `git-switch`. Not to mention that\n> `git-checkout` is now largely superseded by `git-switch` and\n> `git-restore` and is no longer recommended, as far as I understand it.\n>\n> So I think it makes sense to either:\n> 1. make the recommended command match the one ran by the user, or\n> 2. always recommend `git-switch` as opposed to `git-checkout`\n\nHere is what I did while waiting for -rc2 to pass my local tests,\nwhich is unfinished, but it would be a good start.  What missing are\n\n(1) get rid of the usagestr[] parameter from checkout_main(), move\n    the usage strings for these three commands into the function\n    scope of checkout_main(), and choose among them based on the\n    value of which_command parameter;\n\n(2) tests.\n\nWe are not deprecating checkout in any way, so #1 is far more\npreferrable than #2.\n\n\n builtin/checkout.c | 40 +++++++++++++++++++++++++++++++++++-----\n 1 file changed, 35 insertions(+), 5 deletions(-)\n\ndiff --git c/builtin/checkout.c w/builtin/checkout.c\nindex 0ba4f03f2e..4d0e70ea15 100644\n--- c/builtin/checkout.c\n+++ w/builtin/checkout.c\n@@ -1293,9 +1293,17 @@ static void setup_new_branch_info_and_source_tree(\n \t}\n }\n \n+\n+enum checkout_switch {\n+\tCHECKOUT_CHECKOUT = 1,\n+\tCHECKOUT_SWITCH = 2,\n+\tCHECKOUT_RESTORE = 3,\n+};\n+\n static char *parse_remote_branch(const char *arg,\n \t\t\t\t struct object_id *rev,\n-\t\t\t\t int could_be_checkout_paths)\n+\t\t\t\t int could_be_checkout_paths,\n+\t\t\t\t enum checkout_switch which_command)\n {\n \tint num_matches = 0;\n \tchar *remote = unique_tracking_name(arg, rev, &num_matches);\n@@ -1308,14 +1316,30 @@ static char *parse_remote_branch(const char *arg,\n \n \tif (!remote && num_matches > 1) {\n \t    if (advice_enabled(ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME)) {\n+\t\t    const char *cmdname;\n+\n+\t\t    switch (which_command) {\n+\t\t    case CHECKOUT_CHECKOUT:\n+\t\t\t    cmdname = \"checkout\";\n+\t\t\t    break;\n+\t\t    case CHECKOUT_SWITCH:\n+\t\t\t    cmdname = \"switch\";\n+\t\t\t    break;\n+\t\t    default:\n+\t\t\t    BUG(\"command <%d> should not reach parse_remote_branch\",\n+\t\t\t\twhich_command);\n+\t\t\t    break;\n+\t\t    }\n+\n \t\t    advise(_(\"If you meant to check out a remote tracking branch on, e.g. 'origin',\\n\"\n \t\t\t     \"you can do so by fully qualifying the name with the --track option:\\n\"\n \t\t\t     \"\\n\"\n-\t\t\t     \"    git checkout --track origin/<name>\\n\"\n+\t\t\t     \"    git %s --track origin/<name>\\n\"\n \t\t\t     \"\\n\"\n \t\t\t     \"If you'd like to always have checkouts of an ambiguous <name> prefer\\n\"\n \t\t\t     \"one remote, e.g. the 'origin' remote, consider setting\\n\"\n-\t\t\t     \"checkout.defaultRemote=origin in your config.\"));\n+\t\t\t     \"checkout.defaultRemote=origin in your config.\"),\n+\t\t\t   cmdname);\n \t    }\n \n \t    die(_(\"'%s' matched multiple (%d) remote tracking branches\"),\n@@ -1327,6 +1351,7 @@ static char *parse_remote_branch(const char *arg,\n \n static int parse_branchname_arg(int argc, const char **argv,\n \t\t\t\tint dwim_new_local_branch_ok,\n+\t\t\t\tenum checkout_switch which_command,\n \t\t\t\tstruct branch_info *new_branch_info,\n \t\t\t\tstruct checkout_opts *opts,\n \t\t\t\tstruct object_id *rev)\n@@ -1436,7 +1461,8 @@ static int parse_branchname_arg(int argc, const char **argv,\n \n \t\tif (recover_with_dwim) {\n \t\t\tremote = parse_remote_branch(arg, rev,\n-\t\t\t\t\t\t     could_be_checkout_paths);\n+\t\t\t\t\t\t     could_be_checkout_paths,\n+\t\t\t\t\t\t     which_command);\n \t\t\tif (remote) {\n \t\t\t\t*new_branch = arg;\n \t\t\t\targ = remote;\n@@ -1767,6 +1793,7 @@ static char cb_option = 'b';\n \n static int checkout_main(int argc, const char **argv, const char *prefix,\n \t\t\t struct checkout_opts *opts, struct option *options,\n+\t\t\t enum checkout_switch which_command,\n \t\t\t const char * const usagestr[])\n {\n \tint parseopt_flags = 0;\n@@ -1893,7 +1920,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,\n \t\t\topts->dwim_new_local_branch &&\n \t\t\topts->track == BRANCH_TRACK_UNSPECIFIED &&\n \t\t\t!opts->new_branch;\n-\t\tint n = parse_branchname_arg(argc, argv, dwim_ok,\n+\t\tint n = parse_branchname_arg(argc, argv, dwim_ok, which_command,\n \t\t\t\t\t     &new_branch_info, opts, &rev);\n \t\targv += n;\n \t\targc -= n;\n@@ -2032,6 +2059,7 @@ int cmd_checkout(int argc,\n \toptions = add_checkout_path_options(&opts, options);\n \n \treturn checkout_main(argc, argv, prefix, &opts, options,\n+\t\t\t     CHECKOUT_CHECKOUT,\n \t\t\t     checkout_usage);\n }\n \n@@ -2071,6 +2099,7 @@ int cmd_switch(int argc,\n \tcb_option = 'c';\n \n \treturn checkout_main(argc, argv, prefix, &opts, options,\n+\t\t\t     CHECKOUT_SWITCH,\n \t\t\t     switch_branch_usage);\n }\n \n@@ -2107,5 +2136,6 @@ int cmd_restore(int argc,\n \toptions = add_checkout_path_options(&opts, options);\n \n \treturn checkout_main(argc, argv, prefix, &opts, options,\n+\t\t\t     CHECKOUT_RESTORE,\n \t\t\t     restore_usage);\n }\n"}]}