Skip to content

Commit ecf4a19

Browse files
push: suggest <remote> <branch> when a slash slips into the repository
"git push origin/main" treats "origin/main" as a repository, builds an anonymous remote from it, and fails later with "'origin/main' does not appear to be a git repository", giving no hint that the remote and the branch are separate arguments. When the repository argument does not name an existing path, is not a configured remote, and its part before the first slash names one, suggest the intended "git push <remote> <branch>" form. Skipping the suggestion when the argument is an existing path leaves a genuine push to a local "<remote>/<branch>" directory untouched. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
1 parent 479189f commit ecf4a19

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

builtin/push.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "advice.h"
99
#include "branch.h"
1010
#include "config.h"
11+
#include "dir.h"
1112
#include "environment.h"
1213
#include "gettext.h"
1314
#include "hex.h"
@@ -744,6 +745,19 @@ int cmd_push(int argc,
744745

745746
if (repo) {
746747
if (!add_remote_or_group(repo, &remote_group)) {
748+
const char *slash = strchr(repo, '/');
749+
750+
if (slash && !file_exists(repo)) {
751+
struct strbuf name = STRBUF_INIT;
752+
753+
strbuf_add(&name, repo, slash - repo);
754+
if (remote_is_configured(remote_get(name.buf), 0))
755+
die(_("'%s' is not a valid push target.\n"
756+
"Did you mean to use: git push %s %s?"),
757+
repo, name.buf, slash + 1);
758+
strbuf_release(&name);
759+
}
760+
747761
/*
748762
* Not a configured remote name or group name.
749763
* Try treating it as a direct URL or path, e.g.

t/t5529-push-errors.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,25 @@ test_expect_success 'detect empty remote with targeted refspec' '
5454
grep "fatal: bad repository ${SQ}${SQ}" stderr
5555
'
5656

57+
test_expect_success 'suggest <remote> <branch> for a <remote>/<branch> slip' '
58+
test_must_fail git push origin/main 2>stderr &&
59+
grep "${SQ}origin/main${SQ} is not a valid push target" stderr &&
60+
grep "Did you mean to use: git push origin main?" stderr
61+
'
62+
63+
test_expect_success 'no suggestion when prefix is not a configured remote' '
64+
test_must_fail git push not-a-remote/main 2>stderr &&
65+
! grep "Did you mean" stderr
66+
'
67+
68+
test_expect_success 'no suggestion when the argument is an existing path' '
69+
test_when_finished "rm -rf origin" &&
70+
git init --bare origin/main &&
71+
git push origin/main HEAD:refs/heads/pushed 2>stderr &&
72+
! grep "Did you mean" stderr &&
73+
git -C origin/main rev-parse --verify refs/heads/pushed
74+
'
75+
5776
test_expect_success 'detect ambiguous refs early' '
5877
git branch foo &&
5978
git tag foo &&

0 commit comments

Comments
 (0)