git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: mash <mash+git@crossperf.com>
To: Git Mailing List <git@vger.kernel.org>
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Vegard Nossum" <vegard.nossum@oracle.com>,
	"Štěpán Němec" <stepnem@gmail.com>
Subject: [PATCH] diff: allow "-" as a short-hand for "last branch"
Date: Wed, 08 Mar 2017 09:50:53 +0000	[thread overview]
Message-ID: <1clZj4-0006vN-9q@crossperf.com> (raw)

Just like "git merge -" is a short-hand for "git merge @{-1}" to
conveniently merge the previous branch, "git diff -" is a short-hand for
"git diff @{-1}" to conveniently diff against the previous branch.

Allow the usage of "-" in the dot dot notation to allow the use of
"git diff -..HEAD^" as a short-hand for "git diff @{-1}..HEAD^".

Signed-off-by: mash <mash+git@crossperf.com>
---
This is a GSoC microproject. I'm not sure how useful this change is.
Please review it and take it apart.

I'm not very happy with the change of handle_revision_arg.
Maybe I should teach sha1_name.c:get_sha1_basic how to handle a dash
instead.

Documentation was not updated. I could only think of updating revisions.txt but
that might be misleading since the use of dash does not work everywhere.

 revision.c           | 22 ++++++++++++++++++--
 t/t4063-diff-last.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 2 deletions(-)
 create mode 100755 t/t4063-diff-last.sh

diff --git a/revision.c b/revision.c
index b37dbec..c331bd5 100644
--- a/revision.c
+++ b/revision.c
@@ -1439,6 +1439,7 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 	const char *arg = arg_;
 	int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME;
 	unsigned get_sha1_flags = 0;
+	static const char previous_branch[] = "@{-1}";
 
 	flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM;
 
@@ -1457,6 +1458,8 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 
 		if (!*next)
 			next = head_by_default;
+		else if (!strcmp(next, "-"))
+			next = previous_branch;
 		if (dotdot == arg)
 			this = head_by_default;
 		if (this == head_by_default && next == head_by_default &&
@@ -1469,6 +1472,8 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 				*dotdot = '.';
 				return -1;
 			}
+		} else if (!strcmp(this, "-")) {
+			this = previous_branch;
 		}
 		if (!get_sha1_committish(this, from_sha1) &&
 		    !get_sha1_committish(next, sha1)) {
@@ -1568,6 +1573,8 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 	if (revarg_opt & REVARG_COMMITTISH)
 		get_sha1_flags = GET_SHA1_COMMITTISH;
 
+	if (!strcmp(arg, "-"))
+		arg = previous_branch;
 	if (get_sha1_with_context(arg, get_sha1_flags, sha1, &oc))
 		return revs->ignore_missing ? 0 : -1;
 	if (!cant_be_filename)
@@ -1578,6 +1585,15 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 	return 0;
 }
 
+/*
+ * Check if the argument is supposed to be a revision argument instead of an
+ * option even though it starts with a dash.
+ */
+static int is_revision_arg(const char *arg)
+{
+	return *arg == '\0' || starts_with(arg, "..");
+}
+
 struct cmdline_pathspec {
 	int alloc;
 	int nr;
@@ -1621,7 +1637,9 @@ static void read_revisions_from_stdin(struct rev_info *revs,
 				seen_dashdash = 1;
 				break;
 			}
-			die("options not supported in --stdin mode");
+			if (!is_revision_arg(sb.buf + 1)) {
+				die("options not supported in --stdin mode");
+			}
 		}
 		if (handle_revision_arg(sb.buf, revs, 0,
 					REVARG_CANNOT_BE_FILENAME))
@@ -2205,7 +2223,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 	read_from_stdin = 0;
 	for (left = i = 1; i < argc; i++) {
 		const char *arg = argv[i];
-		if (*arg == '-') {
+		if (*arg == '-' && !is_revision_arg(arg + 1)) {
 			int opts;
 
 			opts = handle_revision_pseudo_opt(submodule,
diff --git a/t/t4063-diff-last.sh b/t/t4063-diff-last.sh
new file mode 100755
index 0000000..1f635cb
--- /dev/null
+++ b/t/t4063-diff-last.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+test_description='diff against last branch'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	echo hello >world &&
+	git add world &&
+	git commit -m initial &&
+	git branch other &&
+	echo "hello again" >>world &&
+	git add world &&
+	git commit -m second
+'
+
+test_expect_success '"diff -" does not work initially' '
+	test_must_fail git diff -
+'
+
+test_expect_success '"diff -" diffs against previous branch' '
+	git checkout other &&
+
+	cat <<-\EOF >expect &&
+	diff --git a/world b/world
+	index c66f159..ce01362 100644
+	--- a/world
+	+++ b/world
+	@@ -1,2 +1 @@
+	 hello
+	-hello again
+	EOF
+
+	git diff - >out &&
+	test_cmp expect out
+'
+
+test_expect_success '"diff -.." diffs against previous branch' '
+	git diff -.. >out &&
+	test_cmp expect out
+'
+
+test_expect_success '"diff ..-" diffs inverted' '
+	cat <<-\EOF >expect &&
+	diff --git a/world b/world
+	index ce01362..c66f159 100644
+	--- a/world
+	+++ b/world
+	@@ -1 +1,2 @@
+	 hello
+	+hello again
+	EOF
+
+	git diff ..- >out &&
+	test_cmp expect out
+'
+
+test_done
-- 
2.9.3

             reply	other threads:[~2017-03-08 11:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-08  9:50 mash [this message]
2017-03-09 20:26 ` [PATCH v2 GSoC RFC] diff: allow "-" as a short-hand for "last branch" mash
     [not found]   ` <20170310034106.GB1984@instance-1.c.mfqp-source.internal>
2017-03-10  4:52     ` mash
2017-03-10  5:00       ` Siddharth Kannan

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=1clZj4-0006vN-9q@crossperf.com \
    --to=mash+git@crossperf.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=stepnem@gmail.com \
    --cc=vegard.nossum@oracle.com \
    /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).