git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/2 v3] WIP: allow "-" as a shorthand for "previous branch"
@ 2017-02-10 18:55 Siddharth Kannan
  2017-02-10 18:55 ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
  0 siblings, 1 reply; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-10 18:55 UTC (permalink / raw)
  To: git
  Cc: gitster, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals,
	Siddharth Kannan

Thanks a lot, Matthieu, for your comments on an earlier version of this 
patch! [1]

After the discussion there, I have considered the changes that have been made
and I broke them into two separate commits.

I have included the list of commands that are touched by this patch series in
the second commit message. (idea from the v1 discussion [2]) Reproduced here:

  * builtin/blame.c
  * builtin/diff.c
  * builtin/diff-files.c
  * builtin/diff-index.c
  * builtin/diff-tree.c
  * builtin/log.c
  * builtin/rev-list.c
  * builtin/shortlog.c
  * builtin/fast-export.c
  * builtin/fmt-merge-msg.c
  builtin/add.c
  builtin/checkout.c
  builtin/commit.c
  builtin/merge.c
  builtin/pack-objects.c
  builtin/revert.c

  * marked commands are information-only.

I have added the WIP tag because I am still unsure if the tests that I have
added (for git-log) are sufficient for this patch or more comprehensive tests
need to be added. So, please help me with some feedback on that.

I have removed the "log:" tag from the subject line because this patch now
affects commands other than log.

I have run the test suite locally and on Travis CI! [3]

[1]: https://public-inbox.org/git/vpqh944eof7.fsf@anie.imag.fr/#t
[2]: https://public-inbox.org/git/CAN-3QhoZN_wYvqbVdU_c1h4vUOaT5FOBFL7k+FemNpqkxjWDDA@mail.gmail.com/
[3]: https://travis-ci.org/icyflame/git/builds/200431159

Siddharth Kannan (2):
  revision.c: args starting with "-" might be a revision
  sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"

 revision.c               | 12 ++++++--
 sha1_name.c              |  5 ++++
 t/t4214-log-shorthand.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100755 t/t4214-log-shorthand.sh

-- 
2.1.4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-10 18:55 [PATCH 0/2 v3] WIP: allow "-" as a shorthand for "previous branch" Siddharth Kannan
@ 2017-02-10 18:55 ` Siddharth Kannan
  2017-02-10 18:55   ` [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}" Siddharth Kannan
  2017-02-10 23:35   ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Junio C Hamano
  0 siblings, 2 replies; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-10 18:55 UTC (permalink / raw)
  To: git
  Cc: gitster, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals,
	Siddharth Kannan

setup_revisions used to consider any argument starting with "-" to be either a
valid option or nothing at all. This patch will teach it to check if the
argument is a revision before declaring that it is nothing at all.

Before this patch, handle_revision_arg was not called for arguments starting
with "-" and once for arguments that didn't start with "-". Now, it will be
called once per argument.

This patch prepares the addition of "-" as a shorthand for "previous branch".

Signed-off-by: Siddharth Kannan <kannan.siddharth12@gmail.com>
---
 revision.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index b37dbec..4131ad5 100644
--- a/revision.c
+++ b/revision.c
@@ -2205,6 +2205,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];
+		int handle_rev_arg_called = 0, args;
 		if (*arg == '-') {
 			int opts;
 
@@ -2234,11 +2235,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			}
 			if (opts < 0)
 				exit(128);
-			continue;
+
+			args = handle_revision_arg(arg, revs, flags, revarg_opt);
+			handle_rev_arg_called = 1;
+			if (args)
+				continue;
+			else
+				--left;
 		}
 
 
-		if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
+		if ((handle_rev_arg_called && args) ||
+				handle_revision_arg(arg, revs, flags, revarg_opt)) {
 			int j;
 			if (seen_dashdash || *arg == '^')
 				die("bad revision '%s'", arg);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"
  2017-02-10 18:55 ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
@ 2017-02-10 18:55   ` Siddharth Kannan
  2017-02-12  9:48     ` Matthieu Moy
  2017-02-10 23:35   ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Junio C Hamano
  1 sibling, 1 reply; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-10 18:55 UTC (permalink / raw)
  To: git
  Cc: gitster, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals,
	Siddharth Kannan

This patch introduces "-" as a method to refer to a revision, and adds tests to
test that git-log works with this shorthand.

This change will touch the following commands (through
revision.c:setup_revisions):

* builtin/blame.c
* builtin/diff.c
* builtin/diff-files.c
* builtin/diff-index.c
* builtin/diff-tree.c
* builtin/log.c
* builtin/rev-list.c
* builtin/shortlog.c
* builtin/fast-export.c
* builtin/fmt-merge-msg.c
builtin/add.c
builtin/checkout.c
builtin/commit.c
builtin/merge.c
builtin/pack-objects.c
builtin/revert.c

* marked commands are information-only.

As most commands in this list are not of the rm-variety, (i.e a command that
would delete something), this change does not make it easier for people to
delete. (eg: "git branch -d -" is *not* enabled by this patch)

Signed-off-by: Siddharth Kannan <kannan.siddharth12@gmail.com>
---
 sha1_name.c              |  5 ++++
 t/t4214-log-shorthand.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100755 t/t4214-log-shorthand.sh

diff --git a/sha1_name.c b/sha1_name.c
index 73a915f..d774e46 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -947,6 +947,11 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
 	if (!ret)
 		return 0;
 
+	if (!strcmp(name, "-")) {
+		name = "@{-1}";
+		len = 5;
+	}
+
 	ret = get_sha1_basic(name, len, sha1, lookup_flags);
 	if (!ret)
 		return 0;
diff --git a/t/t4214-log-shorthand.sh b/t/t4214-log-shorthand.sh
new file mode 100755
index 0000000..dec966c
--- /dev/null
+++ b/t/t4214-log-shorthand.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+test_description='log can show previous branch using shorthand - for @{-1}'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	echo hello >world &&
+	git add world &&
+	git commit -m initial &&
+	echo "hello second time" >>world &&
+	git add world &&
+	git commit -m second &&
+	echo "hello other file" >>planet &&
+	git add planet &&
+	git commit -m third &&
+	echo "hello yet another file" >>city &&
+	git add city &&
+	git commit -m fourth
+'
+
+test_expect_success '"log -" should not work initially' '
+	test_must_fail git log -
+'
+
+test_expect_success '"log -" should work' '
+	git checkout -b testing-1 master^ &&
+	git checkout -b testing-2 master~2 &&
+	git checkout master &&
+
+	git log testing-2 >expect &&
+	git log - >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'symmetric revision range should work when one end is left empty' '
+	git checkout testing-2 &&
+	git checkout master &&
+	git log ...@{-1} > expect.first_empty &&
+	git log @{-1}... > expect.last_empty &&
+	git log ...- > actual.first_empty &&
+	git log -... > actual.last_empty &&
+	test_cmp expect.first_empty actual.first_empty &&
+	test_cmp expect.last_empty actual.last_empty
+'
+
+test_expect_success 'asymmetric revision range should work when one end is left empty' '
+	git checkout testing-2 &&
+	git checkout master &&
+	git log ..@{-1} > expect.first_empty &&
+	git log @{-1}.. > expect.last_empty &&
+	git log ..- > actual.first_empty &&
+	git log -.. > actual.last_empty &&
+	test_cmp expect.first_empty actual.first_empty &&
+	test_cmp expect.last_empty actual.last_empty
+'
+
+test_expect_success 'symmetric revision range should work when both ends are given' '
+	git checkout testing-2 &&
+	git checkout master &&
+	git log -...testing-1 >expect &&
+	git log testing-2...testing-1 >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'asymmetric revision range should work when both ends are given' '
+	git checkout testing-2 &&
+	git checkout master &&
+	git log -..testing-1 >expect &&
+	git log testing-2..testing-1 >actual &&
+	test_cmp expect actual
+'
+test_done
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-10 18:55 ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
  2017-02-10 18:55   ` [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}" Siddharth Kannan
@ 2017-02-10 23:35   ` Junio C Hamano
  2017-02-11  7:52     ` Siddharth Kannan
  1 sibling, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2017-02-10 23:35 UTC (permalink / raw)
  To: Siddharth Kannan; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Siddharth Kannan <kannan.siddharth12@gmail.com> writes:

> @@ -2234,11 +2235,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
>  			}
>  			if (opts < 0)
>  				exit(128);
> -			continue;
> +
> +			args = handle_revision_arg(arg, revs, flags, revarg_opt);
> +			handle_rev_arg_called = 1;
> +			if (args)
> +				continue;
> +			else
> +				--left;
>  		}
>  
>  
> -		if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
> +		if ((handle_rev_arg_called && args) ||
> +				handle_revision_arg(arg, revs, flags, revarg_opt)) {

Naively I would have expected that removing the "continue" at the
end and letting the control go to the existing

	if (handle_revision_arg(arg, revs, flags, revarg_opt)) {

would be all that is needed.  The latter half of the patch is an
artifact of having ane xtra "handle_revision_arg() calls inside the
"if it begins with dash" block to avoid calling it twice.

So the difference is just "--left" (by the way, our codebase seem to
prefer "left--" when there is no difference between pre- or post-
decrement/increment) that adjusts the slot in argv[] where the next
unknown argument is stuffed to.

The adjustment is needed as the call to handle_revision_opt() that
is before the pre-context of this hunk stuffed the unknown thing
that begins with "-" into argv[left++]; if that thing turns out to
be a valid rev, then you would need to take it back, because after
all, that is not an unknown command line argument.

I am wondering if writing it like the following is easier to
understand.  I had a hard time figuring out what you are trying to
do, partly because "args" is quite a misnomer---implying "how many
arguments did we see" that is similar to opts that does mean "how
many options did handle_revision_opts() see?"  The variable means
means "yes we saw a valid rev" when it is zero.  The rewrite
below may avoid such a confusion.  I dunno.

 revision.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/revision.c b/revision.c
index b37dbec378..e238430948 100644
--- a/revision.c
+++ b/revision.c
@@ -2204,6 +2204,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 		revarg_opt |= REVARG_CANNOT_BE_FILENAME;
 	read_from_stdin = 0;
 	for (left = i = 1; i < argc; i++) {
+		int maybe_rev = 0;
 		const char *arg = argv[i];
 		if (*arg == '-') {
 			int opts;
@@ -2234,11 +2235,16 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			}
 			if (opts < 0)
 				exit(128);
-			continue;
+			maybe_rev = 1;
+			left--; /* tentatively cancel "unknown opt" */
 		}
 
-
-		if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
+		if (!handle_revision_arg(arg, revs, flags, revarg_opt)) {
+			got_rev_arg = 1;
+		} else if (maybe_rev) {
+			left++; /* it turns out that it was "unknown opt" */
+			continue;
+		} else {
 			int j;
 			if (seen_dashdash || *arg == '^')
 				die("bad revision '%s'", arg);
@@ -2255,8 +2261,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			append_prune_data(&prune_data, argv + i);
 			break;
 		}
-		else
-			got_rev_arg = 1;
 	}
 
 	if (prune_data.nr) {

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-10 23:35   ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Junio C Hamano
@ 2017-02-11  7:52     ` Siddharth Kannan
  2017-02-11 21:08       ` Junio C Hamano
  0 siblings, 1 reply; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-11  7:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Hey Junio,
On Fri, Feb 10, 2017 at 03:35:47PM -0800, Junio C Hamano wrote:
> So the difference is just "--left" (by the way, our codebase seem to
> prefer "left--" when there is no difference between pre- or post-
> decrement/increment) that adjusts the slot in argv[] where the next
> unknown argument is stuffed to.

Understood, I will use post decrement.

> I am wondering if writing it like the following is easier to
> understand.  I had a hard time figuring out what you are trying to
> do, partly because "args" is quite a misnomer---implying "how many
> arguments did we see" that is similar to opts that does mean "how
> many options did handle_revision_opts() see?"  

Um, okay, I see that "args" is very confusing. Would it help if this variable
was called "arg_not_rev"? Because the value that is returned from
handle_revision_arg is 1 when it is not a revision, and 0 when it is a
revision. The changed block of code would look like this:

---
 revision.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index b37dbec..4131ad5 100644
--- a/revision.c
+++ b/revision.c
@@ -2205,6 +2205,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];
+		int handle_rev_arg_called = 0, arg_not_rev;
 		if (*arg == '-') {
 			int opts;
@@ -2234,11 +2235,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
                    }
                    if (opts < 0)
                            exit(128);
-                   continue;
+
+                   arg_not_rev = handle_revision_arg(arg, revs, flags, revarg_opt);
+                   handle_rev_arg_called = 1;
+                   if (arg_not_rev)
+                           continue; /* arg is neither an option nor a revision */
+                   else
+                           left--; /* arg is a revision! */
            }
 
 
-           if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
+           if ((handle_rev_arg_called && arg_not_rev) ||
+                           handle_revision_arg(arg, revs, flags, revarg_opt)) {

> The rewrite below may avoid such a confusion.  I dunno.

Um, I am sorry, but I feel that decrementing left, and incrementing it again is
also confusing. I think that with a better name for the return value from
handle_revision_arg, the earlier confusion should be resolved.

I base this on my previous experience following the codepath. It was easy for
me to understand with the previous code that "continue" will be executed from
within the first if block whenever arg begins with a "-" and it is determined
that it is not an option. 

going by that, now, "continue" will be executed whenever it's not an option and
_also_ not an argument. Otherwise, the further parts of the code will execute
as before, and there are no continue statements there. I hope this argument
makes sense.

Also worth noting, The two `if` lines look better now:

1. If arg is not a revision, go to the next arg (because we have already
determined that it is not an option)

2. If handle_rev_arg was called AND the argument was not a revision, OR
if handle_revision_arg says that arg is not a rev, execute the following block.

Perhaps, someone else could please have a look at the changes in the block
above and the block below and give some feedback on which one is easier to
understand and the reason that they feel so. Thanks a lot!

> 
>  revision.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/revision.c b/revision.c
> index b37dbec378..e238430948 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -2204,6 +2204,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
>               revarg_opt |= REVARG_CANNOT_BE_FILENAME;
>       read_from_stdin = 0;
>       for (left = i = 1; i < argc; i++) {
> +             int maybe_rev = 0;
>               const char *arg = argv[i];
>               if (*arg == '-') {
>                       int opts;
> @@ -2234,11 +2235,16 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
>                       }
>                       if (opts < 0)
>                               exit(128);
> -                     continue;
> +                     maybe_rev = 1;
> +                     left--; /* tentatively cancel "unknown opt" */
>               }
>  
> -
> -             if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
> +             if (!handle_revision_arg(arg, revs, flags, revarg_opt)) {
> +                     got_rev_arg = 1;
> +             } else if (maybe_rev) {
> +                     left++; /* it turns out that it was "unknown opt" */
> +                     continue;
> +             } else {
>                       int j;
>                       if (seen_dashdash || *arg == '^')
>                               die("bad revision '%s'", arg);
> @@ -2255,8 +2261,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
>                       append_prune_data(&prune_data, argv + i);
>                       break;
>               }
> -             else
> -                     got_rev_arg = 1;
>       }
>  
>       if (prune_data.nr) {

Thanks Junio, for the time you spent analysing and writing the above version of
the patch!

Regards,

- Siddharth Kannan

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-11  7:52     ` Siddharth Kannan
@ 2017-02-11 21:08       ` Junio C Hamano
  2017-02-11 23:40         ` Junio C Hamano
  2017-02-12 12:36         ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
  0 siblings, 2 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-11 21:08 UTC (permalink / raw)
  To: Siddharth Kannan; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Siddharth Kannan <kannan.siddharth12@gmail.com> writes:

> On Fri, Feb 10, 2017 at 03:35:47PM -0800, Junio C Hamano wrote:
>
>> I am wondering if writing it like the following is easier to
>> understand.  I had a hard time figuring out what you are trying to
>> do, partly because "args" is quite a misnomer---implying "how many
>> arguments did we see" that is similar to opts that does mean "how
>> many options did handle_revision_opts() see?"
>
> Um, okay, I see that "args" is very confusing. Would it help if this variable
> was called "arg_not_rev"?

Not really.  If we absolutely need to have one variable that is
meant to escape the "if it begins with a dash" block and to affect
what comes next, I think the variable should mean "we know we saw a
revision and you do not have to call it again".  IOW the code that
needs to do "handle_rev_arg_called && arg_not_rev" is just being
silly.  At that point in the codeflow, I do not see why the code
needs to take two bits of information and combine them; the one that
sets these two variables should have done the work for it.

And that would make the if statement slightly easier to read
compared to the original.  I am however not suggesting to do that;
read on.

> Because the value that is returned from
> handle_revision_arg is 1 when it is not a revision, and 0 when it is a
> revision.

The function follows the convention to return 0 for success, -1 for
error/unexpected, by the way.

> Um, I am sorry, but I feel that decrementing left, and incrementing it again is
> also confusing.

Yes, but it is no more confusing than your original "left--".

If we want to make the flow of logic easier to follow, we need to
step back and view what the codepath _wants_ to do at the higher
level, which is:

 * If it is an option known to us, handle it and go to the next arg.

 * If it is an option that we do not understand, stuff it in
   argv[left++] and go to the next arg.

 * If it is a rev, handle it, and note that fact in got_rev_arg.

 * If it is not a rev and we haven't seen dashdash, verify that it
   and everything that follows it are pathnames (which is an inexact
   but a cheap way to avoid ambiguity), make all them the prune_data
   and conclude.

Because the second step currently is implemented by calling
handle_opt(), which not just tells if it is an option we understand
or not, but also mucks with argv[left++], you need to undo it once
you start making it possible for a valid "rev" to begin with a dash.
That is what your left-- was, and that is what "decrement and then
increment when it turns out it was an unknown option after all" is.

The first step to a saner flow _could_ be to stop passing the unkv
and unkc to handle_revision_opt() and instead make the caller
responsible for doing that.  That would express what your patch
wanted to do in the most natural way, i.e.

 * If it is an option known to us, handle it and go to the next arg.

 * If it is a rev, handle it, and note that fact in got_rev_arg
   (this change of order enables you to allow a rev that begins with
   a dash, which would have been misrecognised as a possible unknown
   option).

 * If it looks like an option (i.e. "begins with a dash"), then we
   already know that it is not something we understand, because the
   first step would have caught it already.  Stuff it in
   argv[left++] and go to the next arg.

 * If it is not a rev and we haven't seen dashdash, verify that it
   and everything that follows it are pathnames (which is an inexact
   but a cheap way to avoid ambiguity), make all them the prune_data
   and conclude.

Such a change to handle_revision_opt() unfortunately affects other
callers of the function, so it may not be worth it, but I think
"decrement and then increment, because this codepath wants to check
to see something that may ordinarily be clasified as an unknown
option if it is a rev" is an ugly workaround, just like your left--
was.  But I think the resulting code flow is much closer to the
above ideal.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-11 21:08       ` Junio C Hamano
@ 2017-02-11 23:40         ` Junio C Hamano
  2017-02-12 18:41           ` [PATCH 0/3] prepare for a rev/range that begins with a dash Junio C Hamano
  2017-02-12 12:36         ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
  1 sibling, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2017-02-11 23:40 UTC (permalink / raw)
  To: Siddharth Kannan; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Junio C Hamano <gitster@pobox.com> writes:

> Such a change to handle_revision_opt() unfortunately affects other
> callers of the function, so it may not be worth it, and I think
> "decrement and then increment, because this codepath wants to check
> to see something that may ordinarily be clasified as an unknown
> option if it is a rev" is an ugly workaround, just like your left--
> was.  But I think the resulting code flow is much closer to the
> above ideal.

Having re-analysed the codepath like so, I realize that the new
variable I introduced was misnamed.  Its purpose is to let the
"if arg begins with dash, do this" block communicate that what the
later part of the code is told to inspect in "arg" may be an option
that we do not recognise.  So I shouldn't have called it maybe_rev;
the message from the former to the latter is "this may be an unknown
option" and I should have called it "maybe_unknown_opt".


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"
  2017-02-10 18:55   ` [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}" Siddharth Kannan
@ 2017-02-12  9:48     ` Matthieu Moy
  2017-02-12 10:42       ` Siddharth Kannan
  2017-02-13 19:51       ` Junio C Hamano
  0 siblings, 2 replies; 18+ messages in thread
From: Matthieu Moy @ 2017-02-12  9:48 UTC (permalink / raw)
  To: Siddharth Kannan; +Cc: git, gitster, pranit.bauva, peff, pclouds, sandals

Siddharth Kannan <kannan.siddharth12@gmail.com> writes:

>  sha1_name.c              |  5 ++++
>  t/t4214-log-shorthand.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 78 insertions(+)
>  create mode 100755 t/t4214-log-shorthand.sh
>
> diff --git a/sha1_name.c b/sha1_name.c
> index 73a915f..d774e46 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -947,6 +947,11 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
>  	if (!ret)
>  		return 0;
>  
> +	if (!strcmp(name, "-")) {
> +		name = "@{-1}";
> +		len = 5;
> +	}

One drawback of this approach is that further error messages will be
given from the "@{-1}" string that the user never typed.

After you do that, the existing "turn - into @{-1}" pieces of code
become useless and you should remove it (probably in a further patch).

There are at least:

$ git grep -n -A1 'strcmp.*"-"' | grep -B 1 '@\{1\}'
builtin/checkout.c:975: if (!strcmp(arg, "-"))
builtin/checkout.c-976-         arg = "@{-1}";
--
builtin/merge.c:1231:   } else if (argc == 1 && !strcmp(argv[0], "-")) {
builtin/merge.c-1232-           argv[0] = "@{-1}";
--
builtin/revert.c:158:           if (!strcmp(argv[1], "-"))
builtin/revert.c-159-                   argv[1] = "@{-1}";
--
builtin/worktree.c:344: if (!strcmp(branch, "-"))
builtin/worktree.c-345-         branch = "@{-1}";

In the final version, obviously the same "refactoring" (specific
command -> git-wide) should be done for documentation (it should be in
this patch to avoid letting not-up-to-date documentation even for a
single commit).

> diff --git a/t/t4214-log-shorthand.sh b/t/t4214-log-shorthand.sh
> new file mode 100755
> index 0000000..dec966c
> --- /dev/null
> +++ b/t/t4214-log-shorthand.sh
> @@ -0,0 +1,73 @@
> +#!/bin/sh
> +
> +test_description='log can show previous branch using shorthand - for @{-1}'
> +
> +. ./test-lib.sh
> +
> +test_expect_success 'setup' '
> +	echo hello >world &&
> +	git add world &&
> +	git commit -m initial &&
> +	echo "hello second time" >>world &&
> +	git add world &&
> +	git commit -m second &&
> +	echo "hello other file" >>planet &&
> +	git add planet &&
> +	git commit -m third &&
> +	echo "hello yet another file" >>city &&
> +	git add city &&
> +	git commit -m fourth
> +'

You may use test_commit to save a few lines of code.

> +test_expect_success '"log -" should work' '
> +	git checkout -b testing-1 master^ &&
> +	git checkout -b testing-2 master~2 &&
> +	git checkout master &&
> +
> +	git log testing-2 >expect &&
> +	git log - >actual &&
> +	test_cmp expect actual
> +'

I'd have split this into a "setup branches" and a '"log -" should work'
test (to actually see where "setup branches" happen in the output, and
to allow running the setup step separately if needed). Not terribly
important.

> +test_expect_success 'symmetric revision range should work when one end is left empty' '
> +	git checkout testing-2 &&
> +	git checkout master &&
> +	git log ...@{-1} > expect.first_empty &&
> +	git log @{-1}... > expect.last_empty &&
> +	git log ...- > actual.first_empty &&
> +	git log -... > actual.last_empty &&

Nitpick: we stick the > and the filename (as you did in most places
already).

It may be worth adding tests for more cases like

* Check what happens with suffixes, i.e. -^, -@{yesterday} and -~.

* -..- -> to make sure you handle the presence of two - properly.

* multiple separate arguments to make sure you handle them all, e.g.
  "git log - -", "git log HEAD -", "git log - HEAD".

The last two may be overkill, but the first one is probably important.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"
  2017-02-12  9:48     ` Matthieu Moy
@ 2017-02-12 10:42       ` Siddharth Kannan
  2017-02-13 19:51       ` Junio C Hamano
  1 sibling, 0 replies; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-12 10:42 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git, gitster, pranit.bauva, peff, pclouds, sandals

Hey Matthieu,
On Sun, Feb 12, 2017 at 10:48:56AM +0100, Matthieu Moy wrote:
> Siddharth Kannan <kannan.siddharth12@gmail.com> writes:
> 
> >  sha1_name.c              |  5 ++++
> >  t/t4214-log-shorthand.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 78 insertions(+)
> >  create mode 100755 t/t4214-log-shorthand.sh
> >
> > diff --git a/sha1_name.c b/sha1_name.c
> > index 73a915f..d774e46 100644
> > --- a/sha1_name.c
> > +++ b/sha1_name.c
> > @@ -947,6 +947,11 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
> >  	if (!ret)
> >  		return 0;
> >  
> > +	if (!strcmp(name, "-")) {
> > +		name = "@{-1}";
> > +		len = 5;
> > +	}
> 
> After you do that, the existing "turn - into @{-1}" pieces of code
> become useless and you should remove it (probably in a further patch).

Yeah, this is currently also implemented in checkout, apart from the
grepped list that you have supplied here. I will find all the
instances, and ensure that they work, and remove them. (This will
require some more digging into the codepath the commands, to ensure
that get_sha1_1 is called somewhere down the line)
> 
> > diff --git a/t/t4214-log-shorthand.sh b/t/t4214-log-shorthand.sh
> > ...
> > +test_expect_success 'setup' '
> > +	echo hello >world &&
> > +	git add world &&
> > +	git commit -m initial &&
> > +	echo "hello second time" >>world &&
> > ...
> 
> You may use test_commit to save a few lines of code.

Oh, yeah! I will use that. I need to work on improving the tests, as
well as adding the documentation.
> 
> > +test_expect_success 'symmetric revision range should work when one end is left empty' '
> > +	git checkout testing-2 &&
> > +	git checkout master &&
> > +	git log ...@{-1} > expect.first_empty &&
> > +	git log @{-1}... > expect.last_empty &&
> > +	git log ...- > actual.first_empty &&
> > +	git log -... > actual.last_empty &&
> 
> Nitpick: we stick the > and the filename (as you did in most places
> already).
Sorry, slipped my mind!
> 
> It may be worth adding tests for more cases like
> 
> * Check what happens with suffixes, i.e. -^, -@{yesterday} and -~.

These do not work right now. The first and last cases here are handled
by peel_onion, if I remember correctly. I have to find out why exactly
these are not working. Thanks for mentioning this!

> 
> * -..- -> to make sure you handle the presence of two - properly.
> 
> * multiple separate arguments to make sure you handle them all, e.g.
>   "git log - -", "git log HEAD -", "git log - HEAD".

Yeah, will add these tests.

> 
> The last two may be overkill, but the first one is probably important.
> 
> -- 
> Matthieu Moy
> http://www-verimag.imag.fr/~moy/

--
Regards,

Siddharth Kannan.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-11 21:08       ` Junio C Hamano
  2017-02-11 23:40         ` Junio C Hamano
@ 2017-02-12 12:36         ` Siddharth Kannan
  2017-02-12 18:56           ` Junio C Hamano
  1 sibling, 1 reply; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-12 12:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

On Sat, Feb 11, 2017 at 01:08:09PM -0800, Junio C Hamano wrote:
> Siddharth Kannan <kannan.siddharth12@gmail.com> writes:
> 
> > Um, I am sorry, but I feel that decrementing left, and incrementing it again is
> > also confusing.
> 
> Yes, but it is no more confusing than your original "left--".
> ...
> 
>  * If it is an option known to us, handle it and go to the next arg.
> 
>  * If it is an option that we do not understand, stuff it in
>    argv[left++] and go to the next arg.
> 
> Because the second step currently is implemented by calling
> handle_opt(), which not just tells if it is an option we understand
> or not, but also mucks with argv[left++], you need to undo it once
> you start making it possible for a valid "rev" to begin with a dash.
> That is what your left-- was, and that is what "decrement and then
> increment when it turns out it was an unknown option after all" is.

So, our problem here is that the function handle_revision_opt is opaquely also
incrementing "left", which we need to decrement somehow.

Or: we could change the flow of the code so that this incrementing
will happen only when we have decided that the argument is not a
revision.
> 
>  * If it is an option known to us, handle it and go to the next arg.
> 
>  * If it is a rev, handle it, and note that fact in got_rev_arg
>    (this change of order enables you to allow a rev that begins with
>    a dash, which would have been misrecognised as a possible unknown
>    option).
> 
>  * If it looks like an option (i.e. "begins with a dash"), then we
>    already know that it is not something we understand, because the
>    first step would have caught it already.  Stuff it in
>    argv[left++] and go to the next arg.
> 
>  * If it is not a rev and we haven't seen dashdash, verify that it
>    and everything that follows it are pathnames (which is an inexact
>    but a cheap way to avoid ambiguity), make all them the prune_data
>    and conclude.

This "changing the order" gave me the idea to change the flow. I tried to
implement the above steps without touching the function handle_revision_opt. By
inserting the handle_revision_arg call just before calling handle_revision_opt.

The decrementing then incrementing or "left--" things have now been removed.
(But there is still one thing which doesn't look good)

diff --git a/revision.c b/revision.c
index b37dbec..8c0acea 100644
--- a/revision.c
+++ b/revision.c
@@ -2203,11 +2203,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 	if (seen_dashdash)
 		revarg_opt |= REVARG_CANNOT_BE_FILENAME;
 	read_from_stdin = 0;
+
 	for (left = i = 1; i < argc; i++) {
 		const char *arg = argv[i];
+		int opts;
 		if (*arg == '-') {
-			int opts;
-
 			opts = handle_revision_pseudo_opt(submodule,
 						revs, argc - i, argv + i,
 						&flags);
@@ -2226,7 +2226,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 				read_revisions_from_stdin(revs, &prune_data);
 				continue;
 			}
+		}
 
+		if (!handle_revision_arg(arg, revs, flags, revarg_opt))
+			got_rev_arg = 1;
+		else if (*arg == '-') {
 			opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
 			if (opts > 0) {
 				i += opts - 1;
@@ -2234,11 +2238,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			}
 			if (opts < 0)
 				exit(128);
-			continue;
-		}
-
-
-		if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
+		} else {
 			int j;
 			if (seen_dashdash || *arg == '^')
 				die("bad revision '%s'", arg);
@@ -2255,8 +2255,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			append_prune_data(&prune_data, argv + i);
 			break;
 		}
-		else
-			got_rev_arg = 1;
 	}
 
 	if (prune_data.nr) {


The "if (*arg =='-')" line is repeated. On analysing the resulting
revision.c:setup_revisions function, I feel that the codepath is still as
easily followable as it was earlier, and there is definitely no confusion
because of a mysterious decrement. Also, the repeated condition doesn't make it
any harder (it looks like a useful check because we already know that every
option would start with a "-"). But that's only my opinion, and you definitely
know better.

now the flow is very close to the ideal flow that we prefer:

1. If it is a pseudo_opt or --stdin, handle and go to the next arg
2. If it is a revision, note that in "got_rev_arg", and go to the next arg
3. If it starts with a "-" and is a known option, handle and go to the next arg
4. If it is none of {revision, known-option} and we haven't seen dashdash,
   verify that it and everything that follows it are pathnames (which is an
   inexact but a cheap way to avoid ambiguity), make all them the prune_data and
   conclude.

> But I think the resulting code flow is much closer to the
> above ideal.

(about Junio's version of the patch): Yes, I agree with you on this. It's like
the ideal, but the argv has already been populated, so the only remaining step
is "left++".

> 
> Such a change to handle_revision_opt() unfortunately affects other
> callers of the function, so it may not be worth it.

handle_revision_opt is called once apart from within setup_revisions,
from within revision.c:parse_revision_opt.

If this version is not acceptable, we should either revert back to your version
of the patch with the fixed variable name OR consider re-writing
handle_revision_opt, as per your suggested flow. Note that this will put the
code for "Stuff it in argv[left++]" in every caller.

Thank you for the time you have spent on analysing each version of the patch!

--
Best Regards,

Siddharth Kannan.

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 0/3] prepare for a rev/range that begins with a dash
  2017-02-11 23:40         ` Junio C Hamano
@ 2017-02-12 18:41           ` Junio C Hamano
  2017-02-12 18:41             ` [PATCH 1/3] handle_revision_opt(): do not update argv[left++] with an unknown arg Junio C Hamano
                               ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-12 18:41 UTC (permalink / raw)
  To: git; +Cc: Siddharth Kannan

It turns out that telling handle_revision_opt() not to molest argv[left++]
does not have heavy fallout.

Junio C Hamano (3):
  handle_revision_opt(): do not update argv[left++] with an unknown arg
  setup_revisions(): swap if/else bodies to make the next step more readable
  setup_revisions(): allow a rev that begins with a dash

 revision.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

-- 
2.12.0-rc1-212-ga9adfb24fa


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/3] handle_revision_opt(): do not update argv[left++] with an unknown arg
  2017-02-12 18:41           ` [PATCH 0/3] prepare for a rev/range that begins with a dash Junio C Hamano
@ 2017-02-12 18:41             ` Junio C Hamano
  2017-02-12 18:41             ` [PATCH 2/3] setup_revisions(): swap if/else bodies to make the next step more readable Junio C Hamano
  2017-02-12 18:41             ` [PATCH 3/3] setup_revisions(): allow a rev that begins with a dash Junio C Hamano
  2 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-12 18:41 UTC (permalink / raw)
  To: git; +Cc: Siddharth Kannan

In future steps, we will make it possible for a rev or a revision
range (i.e. what is understood by handle_revision_arg() helper) to
begin with a dash.  The setup_revisions() function however currently
considers anything that begins with a dash to be:

 - an option it itself understands and handles (some take effect by
   setting fields in the revision structure, some others are left
   in the argv[left++] to be handled in later steps);
 - an option handle_revision_opt() understands and tells us to skip;
 - an option handle_revision_opt() found to be incorrect; or
 - an option handle_revision_opt() did not understand, which is
   stuffed in argv[left++].

and does not give a chance to handle_revision_arg() to inspect it.
The handle_revision_opt() function returns a positive count, a
negative count or zero to allow the caller to tell the latter three
cases apart.  A rev that begins with a dash would be thrown into the
last category.

Teach handle_revision_opt() not to touch argv[left++] in the last
case.  Because the other one among the two callers of this function
immediately errors out with the usage string when it returns zero
(i.e. the last case above), there is no negative effect to that
caller.

In setup_revisions(), which is the other caller of this function,
we need to stuff the unknown arg to argv[left++] in this case, to
preserve the current behaviour.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index b37dbec378..4f46b8ba81 100644
--- a/revision.c
+++ b/revision.c
@@ -2016,8 +2016,6 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->ignore_missing = 1;
 	} else {
 		int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);
-		if (!opts)
-			unkv[(*unkc)++] = arg;
 		return opts;
 	}
 	if (revs->graph && revs->track_linear)
@@ -2234,6 +2232,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			}
 			if (opts < 0)
 				exit(128);
+			/* arg looks like an opt but something we do not recognise. */
+			argv[left++] = arg;
 			continue;
 		}
 
-- 
2.12.0-rc1-212-ga9adfb24fa


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/3] setup_revisions(): swap if/else bodies to make the next step more readable
  2017-02-12 18:41           ` [PATCH 0/3] prepare for a rev/range that begins with a dash Junio C Hamano
  2017-02-12 18:41             ` [PATCH 1/3] handle_revision_opt(): do not update argv[left++] with an unknown arg Junio C Hamano
@ 2017-02-12 18:41             ` Junio C Hamano
  2017-02-12 18:41             ` [PATCH 3/3] setup_revisions(): allow a rev that begins with a dash Junio C Hamano
  2 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-12 18:41 UTC (permalink / raw)
  To: git; +Cc: Siddharth Kannan

Swap the condition and bodies of an "if (A) do_A else do_B" in
setup_revisions() to "if (!A) do_B else do A", to make the change in
the the next step easier to read.  

No behaviour change is intended in this step.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/revision.c b/revision.c
index 4f46b8ba81..eccf1ab695 100644
--- a/revision.c
+++ b/revision.c
@@ -2237,8 +2237,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			continue;
 		}
 
-
-		if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
+		if (!handle_revision_arg(arg, revs, flags, revarg_opt)) {
+			got_rev_arg = 1;
+		} else {
 			int j;
 			if (seen_dashdash || *arg == '^')
 				die("bad revision '%s'", arg);
@@ -2255,8 +2256,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			append_prune_data(&prune_data, argv + i);
 			break;
 		}
-		else
-			got_rev_arg = 1;
 	}
 
 	if (prune_data.nr) {
-- 
2.12.0-rc1-212-ga9adfb24fa


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/3] setup_revisions(): allow a rev that begins with a dash
  2017-02-12 18:41           ` [PATCH 0/3] prepare for a rev/range that begins with a dash Junio C Hamano
  2017-02-12 18:41             ` [PATCH 1/3] handle_revision_opt(): do not update argv[left++] with an unknown arg Junio C Hamano
  2017-02-12 18:41             ` [PATCH 2/3] setup_revisions(): swap if/else bodies to make the next step more readable Junio C Hamano
@ 2017-02-12 18:41             ` Junio C Hamano
  2 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-12 18:41 UTC (permalink / raw)
  To: git; +Cc: Siddharth Kannan

Now all the preparatory pieces are in place, it is a matter of
handling a truly unknown option _after_ handle_revision_arg()
decides that arg is not a rev.  

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 We _could_ do without a new variable maybe_opt and instead check if
 arg begins with a dash one more time, but it is cleaner to do it
 the way this patch does to avoid writing the same check twice.  We
 may be hit with a desire similar to but an opposite of the current
 topic (which wants to allow a rev that begins with a dash), to
 start allowing an option that does not begin with a dash someday.

 revision.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/revision.c b/revision.c
index eccf1ab695..0f772ba73d 100644
--- a/revision.c
+++ b/revision.c
@@ -2203,6 +2203,8 @@ 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];
+		int maybe_opt = 0;
+
 		if (*arg == '-') {
 			int opts;
 
@@ -2232,13 +2234,20 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 			}
 			if (opts < 0)
 				exit(128);
-			/* arg looks like an opt but something we do not recognise. */
-			argv[left++] = arg;
-			continue;
+			/*
+			 * arg looks like an opt but something we do not recognise.
+			 * It may be a rev that begins with a dash; fall through to
+			 * let handle_revision_arg() have a say in this.
+			 */
+			maybe_opt = 1;
 		}
 
 		if (!handle_revision_arg(arg, revs, flags, revarg_opt)) {
 			got_rev_arg = 1;
+		} else if (maybe_opt) {
+			/* it turns out that it is not a rev after all */
+			argv[left++] = arg;
+			continue;
 		} else {
 			int j;
 			if (seen_dashdash || *arg == '^')
-- 
2.12.0-rc1-212-ga9adfb24fa


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-12 12:36         ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
@ 2017-02-12 18:56           ` Junio C Hamano
  2017-02-14  4:23             ` Siddharth Kannan
  0 siblings, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2017-02-12 18:56 UTC (permalink / raw)
  To: Siddharth Kannan; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Siddharth Kannan <kannan.siddharth12@gmail.com> writes:

> This "changing the order" gave me the idea to change the flow. I tried to
> implement the above steps without touching the function handle_revision_opt. By
> inserting the handle_revision_arg call just before calling handle_revision_opt.

Changing the order is changing the order of the function calls,
i.e. changing the flow.  So at the idea level we are on the same
page.

I was shooting for not having to duplicate calls to
handle_revision_arg().  

>> But I think the resulting code flow is much closer to the
>> above ideal.
>
> (about Junio's version of the patch): Yes, I agree with you on this. It's like
> the ideal, but the argv has already been populated, so the only remaining step
> is "left++".
>> 
>> Such a change to handle_revision_opt() unfortunately affects other
>> callers of the function, so it may not be worth it.

See the 3-patch series I just sent out.  I didn't think it through
very carefully (especially the error message the other caller
produces), but the whole thing _smells_ correct to me.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"
  2017-02-12  9:48     ` Matthieu Moy
  2017-02-12 10:42       ` Siddharth Kannan
@ 2017-02-13 19:51       ` Junio C Hamano
  2017-02-13 20:03         ` Junio C Hamano
  1 sibling, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2017-02-13 19:51 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Siddharth Kannan, git, pranit.bauva, peff, pclouds, sandals

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> Siddharth Kannan <kannan.siddharth12@gmail.com> writes:
>
>> +	if (!strcmp(name, "-")) {
>> +		name = "@{-1}";
>> +		len = 5;
>> +	}
>
> One drawback of this approach is that further error messages will be
> given from the "@{-1}" string that the user never typed.

Right.

> There are at least:
>
> $ git grep -n -A1 'strcmp.*"-"' | grep -B 1 '@\{1\}'
> builtin/checkout.c:975: if (!strcmp(arg, "-"))
> builtin/checkout.c-976-         arg = "@{-1}";

I didn't check the surrounding context to be sure, but I think this
"- to @{-1}" conversion cannot be delegated down to revision parsing
that eventually wants to return a 40-hex as the result.  

We do want a branch _name_ sometimes when we say "@{-1}"; "checkout
master" (i.e. checkout by name) and "checkout master^0" (i.e. the
same commit object, but not by name) do different things.

> builtin/merge.c:1231:   } else if (argc == 1 && !strcmp(argv[0], "-")) {
> builtin/merge.c-1232-           argv[0] = "@{-1}";
> --
> builtin/revert.c:158:           if (!strcmp(argv[1], "-"))
> builtin/revert.c-159-                   argv[1] = "@{-1}";

These should be safe to delegate down.

> builtin/worktree.c:344: if (!strcmp(branch, "-"))
> builtin/worktree.c-345-         branch = "@{-1}";

I do not know about this one, but it smells like a branch name that
wants to be used before it gets turned into 40-hex.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}"
  2017-02-13 19:51       ` Junio C Hamano
@ 2017-02-13 20:03         ` Junio C Hamano
  0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2017-02-13 20:03 UTC (permalink / raw)
  To: Siddharth Kannan, Matthieu Moy; +Cc: git, pranit.bauva, peff, pclouds, sandals

Junio C Hamano <gitster@pobox.com> writes:

> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>
>> Siddharth Kannan <kannan.siddharth12@gmail.com> writes:
>>
>>> +	if (!strcmp(name, "-")) {
>>> +		name = "@{-1}";
>>> +		len = 5;
>>> +	}
>>
>> One drawback of this approach is that further error messages will be
>> given from the "@{-1}" string that the user never typed.
>
> Right.
>
>> There are at least:
>>
>> $ git grep -n -A1 'strcmp.*"-"' | grep -B 1 '@\{1\}'
>> builtin/checkout.c:975: if (!strcmp(arg, "-"))
>> builtin/checkout.c-976-         arg = "@{-1}";
>
> I didn't check the surrounding context to be sure, but I think this
> "- to @{-1}" conversion cannot be delegated down to revision parsing
> that eventually wants to return a 40-hex as the result.  
>
> We do want a branch _name_ sometimes when we say "@{-1}"; "checkout
> master" (i.e. checkout by name) and "checkout master^0" (i.e. the
> same commit object, but not by name) do different things.

FYI, the "@{-<number>} to branch name" translation happens in
interpret_branch_name().  I do not offhand recall if any callers
protect their calls to the function with conditionals that assume
the thing must begin with "@{" or cannot begin with "-" (the latter
of which is similar to the topic of patch 1/2 of this series), but I
suspect that teaching the function that "-" means the same as
"@{-1}" would bring us closer to where we want to go.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision
  2017-02-12 18:56           ` Junio C Hamano
@ 2017-02-14  4:23             ` Siddharth Kannan
  0 siblings, 0 replies; 18+ messages in thread
From: Siddharth Kannan @ 2017-02-14  4:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Matthieu.Moy, pranit.bauva, peff, pclouds, sandals

Hey Junio,
> 
> See the 3-patch series I just sent out.  I didn't think it through
> very carefully (especially the error message the other caller
> produces), but the whole thing _smells_ correct to me.

Okay, got it! I will write-up those changes, and make sure nothing bad
happens. (Also, the one other function that calls handle_revision_opt,
parse_revision_opt needs to be fixed for any changes in
handle_revision_opt.)

I will do all of this in the next week (Unfortunately, exams!) and
submit a new version of this patch (Also, I need to update tests, add
documentation, and remove code that does this shorthand stuff for
other commands as per Matthieu's comments)

--
Best Regards,

Siddharth Kannan.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-02-14  4:23 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-10 18:55 [PATCH 0/2 v3] WIP: allow "-" as a shorthand for "previous branch" Siddharth Kannan
2017-02-10 18:55 ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
2017-02-10 18:55   ` [PATCH 2/2 v3] sha1_name: teach get_sha1_1 "-" shorthand for "@{-1}" Siddharth Kannan
2017-02-12  9:48     ` Matthieu Moy
2017-02-12 10:42       ` Siddharth Kannan
2017-02-13 19:51       ` Junio C Hamano
2017-02-13 20:03         ` Junio C Hamano
2017-02-10 23:35   ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Junio C Hamano
2017-02-11  7:52     ` Siddharth Kannan
2017-02-11 21:08       ` Junio C Hamano
2017-02-11 23:40         ` Junio C Hamano
2017-02-12 18:41           ` [PATCH 0/3] prepare for a rev/range that begins with a dash Junio C Hamano
2017-02-12 18:41             ` [PATCH 1/3] handle_revision_opt(): do not update argv[left++] with an unknown arg Junio C Hamano
2017-02-12 18:41             ` [PATCH 2/3] setup_revisions(): swap if/else bodies to make the next step more readable Junio C Hamano
2017-02-12 18:41             ` [PATCH 3/3] setup_revisions(): allow a rev that begins with a dash Junio C Hamano
2017-02-12 12:36         ` [PATCH 1/2 v3] revision.c: args starting with "-" might be a revision Siddharth Kannan
2017-02-12 18:56           ` Junio C Hamano
2017-02-14  4:23             ` Siddharth Kannan

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).