[PATCH 1/2] branch: suggest <remote>/<branch> on upstream slip
- From
Harald Nordgren via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Jun 12, 2026, 11:10 UTC
- Message-ID
- <21684539debaf433b6b63404e1a7622a5cc33283.1781262619.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2331.git.git.1781262619.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
"git branch --set-upstream-to origin main" reads the trailing word as the local branch to operate on and dies with "branch 'main' does not exist", pointing at the wrong problem.
When that branch is missing and "<remote>/<branch>" names a real remote-tracking ref, suggest the intended "git branch --set-upstream-to=<remote>/<branch>" form.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> --- builtin/branch.c | 17 +++++++++++++++++ t/t3200-branch.sh | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+)
diff --git a/builtin/branch.c b/builtin/branch.c index 1572a4f9ef..7ad3efb908 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -957,6 +957,23 @@ int cmd_branch(int argc, if (!refs_ref_exists(get_main_ref_store(the_repository), branch->refname)) { if (!argc || branch_checked_out(branch->refname)) die(_("no commit on branch '%s' yet"), branch->name); + if (argc == 1 && !strchr(new_upstream, '/') && + remote_is_configured(remote_get(new_upstream), 0)) { + struct strbuf remote_ref = STRBUF_INIT; + + strbuf_addf(&remote_ref, "refs/remotes/%s/%s", + new_upstream, argv[0]); + if (refs_ref_exists(get_main_ref_store(the_repository), + remote_ref.buf)) { + int code = die_message(_("--set-upstream-to takes a single <remote>/<branch> argument")); + advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE, + _("Did you mean to use: git branch --set-upstream-to=%s/%s?"), + new_upstream, argv[0]); + strbuf_release(&remote_ref); + exit(code); + } + strbuf_release(&remote_ref); + } die(_("branch '%s' does not exist"), branch->name); } diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e7829c2c4b..e2682a83a0 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1022,6 +1022,44 @@ test_expect_success '--set-upstream-to fails on a missing dst branch' ' test_cmp expect err ' +test_expect_success '--set-upstream-to suggests <remote>/<branch> on slip' ' + test_when_finished "git remote remove slip-remote" && + git remote add slip-remote . && + git update-ref refs/remotes/slip-remote/slip-feature HEAD && + test_must_fail git branch --set-upstream-to slip-remote slip-feature 2>err && + test_grep "takes a single <remote>/<branch> argument" err && + test_grep "hint: Did you mean to use: git branch --set-upstream-to=slip-remote/slip-feature?" err && + test_must_fail git -c advice.setUpstreamFailure=false \ + branch --set-upstream-to slip-remote slip-feature 2>err && + test_grep ! "Did you mean" err +' + +test_expect_success '--set-upstream-to does not suggest when no matching remote ref' ' + test_when_finished "git remote remove slip-remote" && + git remote add slip-remote . && + test_must_fail git branch --set-upstream-to slip-remote no-such-branch 2>err && + test_grep "branch ${SQ}no-such-branch${SQ} does not exist" err && + test_grep ! "Did you mean" err +' + +test_expect_success '--set-upstream-to to a local branch is not mistaken for a slip' ' + git branch slip-local-upstream && + git branch slip-local-target && + git branch --set-upstream-to=slip-local-upstream slip-local-target 2>err && + test_grep ! "Did you mean" err && + echo refs/heads/slip-local-upstream >expect && + git config branch.slip-local-target.merge >actual && + test_cmp expect actual +' + +test_expect_success '--set-upstream-to slip suggestion keeps a slashed branch name' ' + test_when_finished "git remote remove slip-remote" && + git remote add slip-remote . && + git update-ref refs/remotes/slip-remote/slip/feature HEAD && + test_must_fail git branch --set-upstream-to slip-remote slip/feature 2>err && + test_grep "hint: Did you mean to use: git branch --set-upstream-to=slip-remote/slip/feature?" err +' + test_expect_success '--set-upstream-to fails on a missing src branch' ' test_must_fail git branch --set-upstream-to does-not-exist main 2>err && test_grep "the requested upstream branch '"'"'does-not-exist'"'"' does not exist" err
-- gitgitgadget