git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Teemu Likonen <tlikonen@iki.fi>,
	Daniel Barkalow <barkalow@iabervon.org>,
	git@vger.kernel.org
Subject: Re: Friendly refspecs
Date: Wed, 23 Apr 2008 05:16:06 -0400	[thread overview]
Message-ID: <20080423091606.GC11935@sigill.intra.peff.net> (raw)
In-Reply-To: <7v1w4xuni1.fsf@gitster.siamese.dyndns.org>

On Tue, Apr 22, 2008 at 10:52:06PM -0700, Junio C Hamano wrote:

> Historically we did not favor one way or another for the general purpose
> syntax.  I think Jeff's proposed heuristics to favor branch if a branch
> tip is pushed and tag if a tag is pushed makes sense.

OK, here is a cleaned up patch with tests.

-- >8 --
push: allow unqualified dest refspecs to DWIM

Previously, a push like:

  git push remote src:dst

would go through the following steps:

  1. check for an unambiguous 'dst' on the remote; if it
     exists, then push to that ref
  2. otherwise, check if 'dst' begins with 'refs/'; if it
     does, create a new ref
  3. otherwise, complain because we don't know where in the
     refs hierarchy to put 'dst'

However, in some cases, we can guess about the ref type of
'dst' based on the ref type of 'src'. Specifically, before
complaining we now check:

  2.5. if 'src' resolves to a ref starting with refs/heads
       or refs/tags, then prepend that to 'dst'

So now this creates a new branch on the remote, whereas it
previously failed with an error message:

  git push master:newbranch

Note that, by design, we limit this DWIM behavior only to
source refs which resolve exactly (including symrefs which
resolve to existing refs). We still complain on a partial
destination refspec if the source is a raw sha1, or a ref
expression such as 'master~10'.

Signed-off-by: Jeff King <peff@peff.net>
---
 remote.c              |   32 +++++++++++++++++++++++++++++---
 t/t5516-fetch-push.sh |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/remote.c b/remote.c
index 06ad156..2d9af40 100644
--- a/remote.c
+++ b/remote.c
@@ -812,6 +812,26 @@ static struct ref *make_linked_ref(const char *name, struct ref ***tail)
 	return ret;
 }
 
+static char *guess_ref(const char *name, struct ref *peer)
+{
+	struct strbuf buf = STRBUF_INIT;
+	unsigned char sha1[20];
+
+	const char *r = resolve_ref(peer->name, sha1, 1, NULL);
+	if (!r)
+		return NULL;
+
+	if (!prefixcmp(r, "refs/heads/"))
+		strbuf_addstr(&buf, "refs/heads/");
+	else if (!prefixcmp(r, "refs/tags/"))
+		strbuf_addstr(&buf, "refs/tags/");
+	else
+		return NULL;
+
+	strbuf_addstr(&buf, name);
+	return strbuf_detach(&buf, NULL);
+}
+
 static int match_explicit(struct ref *src, struct ref *dst,
 			  struct ref ***dst_tail,
 			  struct refspec *rs,
@@ -820,6 +840,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
 	struct ref *matched_src, *matched_dst;
 
 	const char *dst_value = rs->dst;
+	char *dst_guess;
 
 	if (rs->pattern)
 		return errs;
@@ -866,10 +887,15 @@ static int match_explicit(struct ref *src, struct ref *dst,
 	case 0:
 		if (!memcmp(dst_value, "refs/", 5))
 			matched_dst = make_linked_ref(dst_value, dst_tail);
+		else if((dst_guess = guess_ref(dst_value, matched_src)))
+			matched_dst = make_linked_ref(dst_guess, dst_tail);
 		else
-			error("dst refspec %s does not match any "
-			      "existing ref on the remote and does "
-			      "not start with refs/.", dst_value);
+			error("unable to push to unqualified destination: %s\n"
+			      "The destination refspec neither matches an "
+			      "existing ref on the remote nor\n"
+			      "begins with refs/, and we are unable to "
+			      "guess a prefix based on the source ref.",
+			      dst_value);
 		break;
 	default:
 		matched_dst = NULL;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index f93a100..0a757d5 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -273,6 +273,37 @@ test_expect_success 'push with colon-less refspec (4)' '
 
 '
 
+test_expect_success 'push head with non-existant, incomplete dest' '
+
+	mk_test &&
+	git push testrepo master:branch &&
+	check_push_result $the_commit heads/branch
+
+'
+
+test_expect_success 'push tag with non-existant, incomplete dest' '
+
+	mk_test &&
+	git tag -f v1.0 &&
+	git push testrepo v1.0:tag &&
+	check_push_result $the_commit tags/tag
+
+'
+
+test_expect_success 'push sha1 with non-existant, incomplete dest' '
+
+	mk_test &&
+	test_must_fail git push testrepo `git rev-parse master`:foo
+
+'
+
+test_expect_success 'push ref expression with non-existant, incomplete dest' '
+
+	mk_test &&
+	test_must_fail git push testrepo master^:branch
+
+'
+
 test_expect_success 'push with HEAD' '
 
 	mk_test heads/master &&
@@ -311,6 +342,15 @@ test_expect_success 'push with +HEAD' '
 
 '
 
+test_expect_success 'push HEAD with non-existant, incomplete dest' '
+
+	mk_test &&
+	git checkout master &&
+	git push testrepo HEAD:branch &&
+	check_push_result $the_commit heads/branch
+
+'
+
 test_expect_success 'push with config remote.*.push = HEAD' '
 
 	mk_test heads/local &&
-- 
1.5.5.1.69.g9c889.dirty

  parent reply	other threads:[~2008-04-23  9:17 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-09 10:14 git annoyances Ingo Molnar
2008-04-09 10:41 ` Björn Steinbrink
2008-04-09 14:57 ` Jeff King
2008-04-09 15:15   ` [PATCH] git-remote: show all remotes with "git remote show" Jeff King
2008-04-09 16:54     ` Johannes Schindelin
2008-04-10 10:56       ` Junio C Hamano
2008-04-09 20:07     ` Ingo Molnar
2008-04-10 19:59     ` Ingo Molnar
2008-04-09 17:08   ` git annoyances Avery Pennarun
2008-04-10  8:41     ` Karl Hasselström
2008-04-10 15:05       ` Avery Pennarun
2008-04-11  7:00         ` Karl Hasselström
2008-04-09 20:08   ` Friendly refspecs (Was: Re: git annoyances) Teemu Likonen
2008-04-09 20:32     ` Avery Pennarun
2008-04-09 20:34     ` Jeff King
2008-04-09 22:25       ` Teemu Likonen
2008-04-09 22:51         ` Jeff King
2008-04-10  0:03           ` Jeff King
2008-04-10  0:11             ` Jeff King
2008-04-10  7:51               ` Friendly refspecs Junio C Hamano
2008-04-10  8:03                 ` Jeff King
     [not found]           ` <bd6139dc0804091616k53f4e0c1sf75aa9585c5a54c5@mail.gmail.com>
2008-04-10  0:33             ` Friendly refspecs (Was: Re: git annoyances) Jeff King
2008-04-10  7:58               ` Sverre Rabbelier
2008-04-13  9:31           ` Friendly refspecs Teemu Likonen
2008-04-13  9:34             ` [PATCH] Add examples section to 'git fetch' manual Teemu Likonen
2008-04-13 18:56               ` Junio C Hamano
2008-04-13 19:48                 ` Matt Graham
2008-04-13 20:05                 ` Teemu Likonen
2008-04-14  1:02                   ` Junio C Hamano
2008-04-16  3:48             ` Friendly refspecs Jeff King
2008-04-16  4:25               ` Jeff King
2008-04-16  4:41               ` Junio C Hamano
2008-04-16  4:47                 ` Jeff King
2008-04-16 15:42               ` Daniel Barkalow
2008-04-16 20:03                 ` Junio C Hamano
2008-04-22 10:56                   ` Jeff King
2008-04-22 16:52                     ` Junio C Hamano
2008-04-22 17:19                       ` Daniel Barkalow
2008-04-22 20:12                         ` Jeff King
2008-04-22 20:05                       ` Jeff King
2008-04-22 20:45                         ` Junio C Hamano
2008-04-22 21:52                           ` Jeff King
2008-04-23  4:24                           ` Teemu Likonen
2008-04-23  5:52                             ` Junio C Hamano
2008-04-23  6:24                               ` Andreas Ericsson
2008-04-23  9:16                               ` Jeff King [this message]
2008-04-23  9:21                                 ` Jeff King
2008-04-23 11:15                                   ` Teemu Likonen
2008-04-09 21:21     ` Junio C Hamano
2008-04-10  7:38       ` Teemu Likonen
2008-04-12 18:59   ` git annoyances Santiago Gala
2008-04-09 19:21 ` Daniel Barkalow
2008-04-09 20:41   ` Ingo Molnar
2008-04-10 14:08     ` Daniel Barkalow
2008-04-09 21:04 ` Junio C Hamano
2008-04-09 21:39   ` Jon Loeliger
2008-04-09 23:45     ` Nicolas Pitre
2008-04-09 21:45   ` Jeff King
2008-04-09 23:56   ` André Goddard Rosa
2008-04-10 19:45     ` Govind Salinas
2008-04-10  6:08   ` Jean-Christian de Rivaz
2008-04-10  8:19     ` Sverre Rabbelier
2008-04-10 11:47 ` git-bisect annoyances Ingo Molnar
2008-04-11  5:41   ` Christian Couder
2008-04-11 11:41     ` Ingo Molnar
2008-04-12  6:56       ` Christian Couder
2008-04-11  5:56   ` Junio C Hamano
2008-04-10 23:25 ` [PATCH] When a remote is added but not fetched, tell the user Gabriel
2008-04-11 15:21   ` Johannes Schindelin
2008-04-11 18:35     ` Gabriel
2008-04-11 18:39       ` [PATCH] Default to fetching a remote after adding it Gabriel
2008-04-11 19:17         ` Stephen Sinclair
2008-04-12 14:33         ` Johannes Schindelin
2008-04-12 15:13           ` Gabriel
2008-04-12 15:24             ` Johannes Schindelin
2008-04-11 19:08       ` [PATCH] When a remote is added but not fetched, tell the user Teemu Likonen
2008-04-11 21:39         ` Junio C Hamano
2008-04-11 22:35           ` Sverre Rabbelier
2008-04-11 23:15             ` Junio C Hamano
2008-04-11 23:20               ` Sverre Rabbelier
2008-04-15  3:15         ` Miles Bader
2008-04-11 19:29       ` [PATCH] Default to fetching a remote after adding it Gabriel
2008-04-11 19:36         ` Wincent Colaiuta
2008-04-11 19:46           ` Gabriel
2008-04-11 10:15 ` git annoyances Luciano Rocha
2008-04-11 10:27   ` Wincent Colaiuta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080423091606.GC11935@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=barkalow@iabervon.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=tlikonen@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).