Skip to content

Commit f37dae0

Browse files
branch: suggest <remote>/<branch> when set-upstream-to slips
"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>
1 parent 3e65291 commit f37dae0

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

builtin/branch.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,23 @@ int cmd_branch(int argc,
957957
if (!refs_ref_exists(get_main_ref_store(the_repository), branch->refname)) {
958958
if (!argc || branch_checked_out(branch->refname))
959959
die(_("no commit on branch '%s' yet"), branch->name);
960+
if (argc == 1 && !strchr(new_upstream, '/') &&
961+
remote_is_configured(remote_get(new_upstream), 0)) {
962+
struct strbuf remote_ref = STRBUF_INIT;
963+
964+
strbuf_addf(&remote_ref, "refs/remotes/%s/%s",
965+
new_upstream, argv[0]);
966+
if (refs_ref_exists(get_main_ref_store(the_repository),
967+
remote_ref.buf)) {
968+
int code = die_message(_("--set-upstream-to takes a single <remote>/<branch> argument"));
969+
advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE,
970+
_("Did you mean to use: git branch --set-upstream-to=%s/%s?"),
971+
new_upstream, argv[0]);
972+
strbuf_release(&remote_ref);
973+
exit(code);
974+
}
975+
strbuf_release(&remote_ref);
976+
}
960977
die(_("branch '%s' does not exist"), branch->name);
961978
}
962979

t/t3200-branch.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,53 @@ test_expect_success '--set-upstream-to fails on a missing dst branch' '
10221022
test_cmp expect err
10231023
'
10241024

1025+
test_expect_success '--set-upstream-to suggests <remote>/<branch> on slip' '
1026+
test_when_finished "git remote remove upstream-remote" &&
1027+
test_config_global protocol.file.allow always &&
1028+
git init --bare slip-remote.git &&
1029+
git remote add upstream-remote slip-remote.git &&
1030+
git push upstream-remote main:slip-feature &&
1031+
git fetch upstream-remote &&
1032+
test_must_fail git rev-parse --verify refs/heads/slip-feature &&
1033+
test_must_fail git branch --set-upstream-to upstream-remote slip-feature 2>err &&
1034+
test_grep "takes a single <remote>/<branch> argument" err &&
1035+
test_grep "hint: Did you mean to use: git branch --set-upstream-to=upstream-remote/slip-feature?" err &&
1036+
test_must_fail git -c advice.setUpstreamFailure=false \
1037+
branch --set-upstream-to upstream-remote slip-feature 2>err &&
1038+
test_grep ! "Did you mean" err
1039+
'
1040+
1041+
test_expect_success '--set-upstream-to does not suggest when no matching remote ref' '
1042+
test_when_finished "git remote remove upstream-remote" &&
1043+
git init --bare slip-remote2.git &&
1044+
git remote add upstream-remote slip-remote2.git &&
1045+
test_must_fail git branch --set-upstream-to upstream-remote no-such-branch 2>err &&
1046+
test_grep "branch ${SQ}no-such-branch${SQ} does not exist" err &&
1047+
test_grep ! "Did you mean" err
1048+
'
1049+
1050+
test_expect_success '--set-upstream-to to a local branch is not mistaken for a slip' '
1051+
git branch slip-local-upstream &&
1052+
git branch slip-local-target &&
1053+
git branch --set-upstream-to=slip-local-upstream slip-local-target 2>err &&
1054+
test_grep ! "Did you mean" err &&
1055+
echo refs/heads/slip-local-upstream >expect &&
1056+
git config branch.slip-local-target.merge >actual &&
1057+
test_cmp expect actual
1058+
'
1059+
1060+
test_expect_success '--set-upstream-to slip suggestion keeps a slashed branch name' '
1061+
test_when_finished "git remote remove upstream-remote" &&
1062+
test_config_global protocol.file.allow always &&
1063+
git init --bare slip-remote3.git &&
1064+
git remote add upstream-remote slip-remote3.git &&
1065+
git push upstream-remote main:slip/feature &&
1066+
git fetch upstream-remote &&
1067+
test_must_fail git rev-parse --verify refs/heads/slip/feature &&
1068+
test_must_fail git branch --set-upstream-to upstream-remote slip/feature 2>err &&
1069+
test_grep "hint: Did you mean to use: git branch --set-upstream-to=upstream-remote/slip/feature?" err
1070+
'
1071+
10251072
test_expect_success '--set-upstream-to fails on a missing src branch' '
10261073
test_must_fail git branch --set-upstream-to does-not-exist main 2>err &&
10271074
test_grep "the requested upstream branch '"'"'does-not-exist'"'"' does not exist" err

0 commit comments

Comments
 (0)