return 0;
}
+static void die_if_upstream_looks_like_remote(const char *new_upstream, const char *branch_name)
+{
+ struct strbuf remote_ref = STRBUF_INIT;
+ int code;
+
+ if (strchr(new_upstream, '/') ||
+ !remote_is_configured(remote_get(new_upstream), 0))
+ return;
+
+ strbuf_addf(&remote_ref, "refs/remotes/%s/%s", new_upstream, branch_name);
+ if (!refs_ref_exists(get_main_ref_store(the_repository), remote_ref.buf)) {
+ strbuf_release(&remote_ref);
+ return;
+ }
+
+ 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, branch_name);
+ strbuf_release(&remote_ref);
+ exit(code);
+}
+
int cmd_branch(int argc,
const char **argv,
const char *prefix,
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);
+ /*
+ * Check the advice up front to avoid the ref
+ * lookups when the hint is off. The helper still
+ * calls advise_if_enabled() so the hint carries the
+ * standard "disable this message" instructions.
+ */
+ if (argc == 1 &&
+ advice_enabled(ADVICE_SET_UPSTREAM_FAILURE))
+ die_if_upstream_looks_like_remote(new_upstream, argv[0]);
die(_("branch '%s' does not exist"), branch->name);
}
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