* [BUG] redundant error message
@ 2013-12-05 10:07 Duy Nguyen
2013-12-05 19:15 ` Jeff King
0 siblings, 1 reply; 28+ messages in thread
From: Duy Nguyen @ 2013-12-05 10:07 UTC (permalink / raw)
To: Git Mailing List
$ git rev-parse foobar --
foobar
fatal: ambiguous argument 'foobar': unknown revision or path not in
the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
I already put "--" there. So it should shut up.
--
Duy
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 10:07 [BUG] redundant error message Duy Nguyen
@ 2013-12-05 19:15 ` Jeff King
2013-12-05 20:00 ` Junio C Hamano
0 siblings, 1 reply; 28+ messages in thread
From: Jeff King @ 2013-12-05 19:15 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Git Mailing List
On Thu, Dec 05, 2013 at 05:07:31PM +0700, Duy Nguyen wrote:
> $ git rev-parse foobar --
> foobar
> fatal: ambiguous argument 'foobar': unknown revision or path not in
> the working tree.
> Use '--' to separate paths from revisions, like this:
> 'git <command> [<revision>...] -- [<file>...]'
>
> I already put "--" there. So it should shut up.
I think it is more than just a bad error message; if we get that
message, it means we are following the wrong code path in interpreting
"foobar":
$ >foobar
$ git rev-parse foobar --
foobar
--
fatal: bad flag '--' used after filename
That's not right. It looks like this isn't a new breakage, though.
v1.5.0 produces the same result.
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 19:15 ` Jeff King
@ 2013-12-05 20:00 ` Junio C Hamano
2013-12-05 20:03 ` Jeff King
0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2013-12-05 20:00 UTC (permalink / raw)
To: Jeff King; +Cc: Duy Nguyen, Git Mailing List
Jeff King <peff@peff.net> writes:
> $ >foobar
> $ git rev-parse foobar --
> foobar
> --
> fatal: bad flag '--' used after filename
>
> That's not right.
Hmph, it looks like it is following the usual "zero-or-more dashed
options, zero-or-more revs and then zero-or-one double-dash and then
zero-or-more paths" rule to parse the thing. "foobar" is a file and
not a rev, so "--" should not be there, no?
Confused why you think it is not right...
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 20:00 ` Junio C Hamano
@ 2013-12-05 20:03 ` Jeff King
2013-12-05 20:15 ` Junio C Hamano
0 siblings, 1 reply; 28+ messages in thread
From: Jeff King @ 2013-12-05 20:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Thu, Dec 05, 2013 at 12:00:16PM -0800, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
> > $ >foobar
> > $ git rev-parse foobar --
> > foobar
> > --
> > fatal: bad flag '--' used after filename
> >
> > That's not right.
>
> Hmph, it looks like it is following the usual "zero-or-more dashed
> options, zero-or-more revs and then zero-or-one double-dash and then
> zero-or-more paths" rule to parse the thing. "foobar" is a file and
> not a rev, so "--" should not be there, no?
>
> Confused why you think it is not right...
Because once you say "--", then all ambiguity goes away, no? Everything
to the left is a rev, not a filename, and everything to the right is a
filename. E.g.:
$ git log foobar --
fatal: bad revision 'foobar'
I think rev-parse is not following the same rules that the rest of the
revision-parsing programs do.
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 20:03 ` Jeff King
@ 2013-12-05 20:15 ` Junio C Hamano
2013-12-05 21:00 ` Jeff King
0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2013-12-05 20:15 UTC (permalink / raw)
To: Jeff King; +Cc: Duy Nguyen, Git Mailing List
Jeff King <peff@peff.net> writes:
> On Thu, Dec 05, 2013 at 12:00:16PM -0800, Junio C Hamano wrote:
>
>> Jeff King <peff@peff.net> writes:
>>
>> > $ >foobar
>> > $ git rev-parse foobar --
>> > foobar
>> > --
>> > fatal: bad flag '--' used after filename
>> >
>> > That's not right.
>>
>> Hmph, it looks like it is following the usual "zero-or-more dashed
>> options, zero-or-more revs and then zero-or-one double-dash and then
>> zero-or-more paths" rule to parse the thing. "foobar" is a file and
>> not a rev, so "--" should not be there, no?
>>
>> Confused why you think it is not right...
>
> Because once you say "--", then all ambiguity goes away, no?
But it is tricky (not from implementation but from semantics point
of view) to make rev-parse follow that "-- separates revs and paths"
rule literally. The primary use of rev-parse is to convert revs in
extended SHA-1 expressions into concrete object names, so that
scripts do not have to worry about having to deal with object names
in a format that is not 40-hexdecimal. "git rev-parse foobar --"
that gives
foobar
--
without any error, because 'foobar' cannot be made into an object
name, would be behaving in a way unexpected by the calling script,
no?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 20:15 ` Junio C Hamano
@ 2013-12-05 21:00 ` Jeff King
2013-12-05 21:28 ` Jeff King
0 siblings, 1 reply; 28+ messages in thread
From: Jeff King @ 2013-12-05 21:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Thu, Dec 05, 2013 at 12:15:07PM -0800, Junio C Hamano wrote:
> >> Hmph, it looks like it is following the usual "zero-or-more dashed
> >> options, zero-or-more revs and then zero-or-one double-dash and then
> >> zero-or-more paths" rule to parse the thing. "foobar" is a file and
> >> not a rev, so "--" should not be there, no?
> >>
> >> Confused why you think it is not right...
> >
> > Because once you say "--", then all ambiguity goes away, no?
>
> But it is tricky (not from implementation but from semantics point
> of view) to make rev-parse follow that "-- separates revs and paths"
> rule literally. The primary use of rev-parse is to convert revs in
> extended SHA-1 expressions into concrete object names, so that
> scripts do not have to worry about having to deal with object names
> in a format that is not 40-hexdecimal. "git rev-parse foobar --"
> that gives
>
> foobar
> --
>
> without any error, because 'foobar' cannot be made into an object
> name, would be behaving in a way unexpected by the calling script,
> no?
Yes, I do expect an error. But it should not be "-- after filename". It
should be "foobar is not a revision".
Thinking on it more, though, the problem is purely limited to wrong
error messages. If "foobar" exists as a rev, we do parse it correctly.
If it does not, we are in the wrong code path, but it _must_ be an error
at that point (either because foobar does not exist as a file, or it
does and has "--" after it).
It would be nice to get the error messages right, though. I do not see
any reason why it could not follow the same steps as "git log",
converting revisions (or throwing an error as appropriate) on the left
side of the "--", and passing through the right side untouched.
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 21:00 ` Jeff King
@ 2013-12-05 21:28 ` Jeff King
2013-12-05 21:44 ` Junio C Hamano
2013-12-06 1:15 ` [BUG] redundant error message Duy Nguyen
0 siblings, 2 replies; 28+ messages in thread
From: Jeff King @ 2013-12-05 21:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Thu, Dec 05, 2013 at 04:00:00PM -0500, Jeff King wrote:
> Yes, I do expect an error. But it should not be "-- after filename". It
> should be "foobar is not a revision".
> [...]
> It would be nice to get the error messages right, though. I do not see
> any reason why it could not follow the same steps as "git log",
> converting revisions (or throwing an error as appropriate) on the left
> side of the "--", and passing through the right side untouched.
IOW, the patch below, which is the same strategy that setup_revisions
uses:
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index c76b89d..845eab9 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -476,6 +476,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+ int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
const char *name = NULL;
@@ -489,6 +490,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) {
+ has_dashdash = 1;
+ break;
+ }
+ }
+
prefix = setup_git_directory();
git_config(git_default_config, NULL);
for (i = 1; i < argc; i++) {
@@ -765,6 +774,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (verify)
die_no_single_rev(quiet);
+ if (has_dashdash)
+ die("bad revision '%s'", arg);
as_is = 1;
if (!show_file(arg, output_prefix))
continue;
BTW, the raw looping to find "--" made me wonder how we handle:
git log --grep -- HEAD
I'd expect it to be equivalent to:
git log --grep=-- HEAD
but it's not; we truncate the arguments and complain that --grep is
missing its argument. Which is probably good enough, given that the
alternative is doing a pass that understands all of the options. But it
does mean that the "--long-opt=arg" form is safer than the split form if
you are passing along an arbitrary "arg".
-Peff
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 21:28 ` Jeff King
@ 2013-12-05 21:44 ` Junio C Hamano
2013-12-06 21:12 ` [PATCH 0/2] rev-parse and "--" Jeff King
2013-12-06 1:15 ` [BUG] redundant error message Duy Nguyen
1 sibling, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2013-12-05 21:44 UTC (permalink / raw)
To: Jeff King; +Cc: Duy Nguyen, Git Mailing List
Jeff King <peff@peff.net> writes:
> BTW, the raw looping to find "--" made me wonder how we handle:
>
> git log --grep -- HEAD
>
> I'd expect it to be equivalent to:
>
> git log --grep=-- HEAD
>
> but it's not; we truncate the arguments and complain that --grep is
> missing its argument. Which is probably good enough, given that the
> alternative is doing a pass that understands all of the options. But it
> does mean that the "--long-opt=arg" form is safer than the split form if
> you are passing along an arbitrary "arg".
;-) Good flow of thought. As to your rev-parse change, I don't
immediately think of a hole/flaw offhand; it looked a good
straight-forward change to me.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-05 21:28 ` Jeff King
2013-12-05 21:44 ` Junio C Hamano
@ 2013-12-06 1:15 ` Duy Nguyen
2013-12-06 22:13 ` Jeff King
1 sibling, 1 reply; 28+ messages in thread
From: Duy Nguyen @ 2013-12-06 1:15 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Git Mailing List
On Fri, Dec 6, 2013 at 4:28 AM, Jeff King <peff@peff.net> wrote:
> BTW, the raw looping to find "--" made me wonder how we handle:
>
> git log --grep -- HEAD
>
> I'd expect it to be equivalent to:
>
> git log --grep=-- HEAD
>
> but it's not; we truncate the arguments and complain that --grep is
> missing its argument. Which is probably good enough, given that the
> alternative is doing a pass that understands all of the options. But it
> does mean that the "--long-opt=arg" form is safer than the split form if
> you are passing along an arbitrary "arg".
Maybe we could make setup_revisions() use parse_options() someday,
which understands about arguments and dashdash.
$ ./git grep -e -- foo
fatal: ambiguous argument 'foo': both revision and filename
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ ./git grep -e -- -- foo
$
--
Duy
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 0/2] rev-parse and "--"
2013-12-05 21:44 ` Junio C Hamano
@ 2013-12-06 21:12 ` Jeff King
2013-12-06 21:13 ` [PATCH 1/2] rev-parse: correctly diagnose revision errors before "--" Jeff King
2013-12-06 21:15 ` [PATCH 2/2] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
0 siblings, 2 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 21:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Thu, Dec 05, 2013 at 01:44:12PM -0800, Junio C Hamano wrote:
> ;-) Good flow of thought. As to your rev-parse change, I don't
> immediately think of a hole/flaw offhand; it looked a good
> straight-forward change to me.
Here it is with tests and a commit message. While writing the tests, I
noticed that also do not handle true ambiguity the same (we prefer revs,
rather than complaining). That's fixed in the second commit.
[1/2]: rev-parse: correctly diagnose revision errors before "--"
[2/2]: rev-parse: diagnose ambiguous revision/filename arguments
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 1/2] rev-parse: correctly diagnose revision errors before "--"
2013-12-06 21:12 ` [PATCH 0/2] rev-parse and "--" Jeff King
@ 2013-12-06 21:13 ` Jeff King
2013-12-06 21:15 ` [PATCH 2/2] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
1 sibling, 0 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 21:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
Rev-parse understands that a "--" may separate revisions and
filenames, and that anything after the "--" is taken as-is.
However, it does not understand that anything before the
token must be a revision (which is the usual rule
implemented by the setup_revisions parser).
Since rev-parse prefers revisions to files when parsing
before the "--", we end up with the correct result (if such
an argument is a revision, we parse it as one, and if it is
not, it is an error either way). However, we misdiagnose
the errors:
$ git rev-parse foobar -- >/dev/null
fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ >foobar
$ git rev-parse foobar -- >/dev/null
fatal: bad flag '--' used after filename
In both cases, we should know that the real error is that
"foobar" is meant to be a revision, but could not be
resolved.
Signed-off-by: Jeff King <peff@peff.net>
---
builtin/rev-parse.c | 10 ++++++++++
t/t1506-rev-parse-diagnosis.sh | 24 ++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 1d9ecaf..bb694ab 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -488,6 +488,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+ int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
const char *name = NULL;
@@ -501,6 +502,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) {
+ has_dashdash = 1;
+ break;
+ }
+ }
+
prefix = setup_git_directory();
git_config(git_default_config, NULL);
for (i = 1; i < argc; i++) {
@@ -788,6 +796,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (verify)
die_no_single_rev(quiet);
+ if (has_dashdash)
+ die("bad revision '%s'", arg);
as_is = 1;
if (!show_file(arg, output_prefix))
continue;
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index f950c10..613d9bf 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -196,4 +196,28 @@ test_expect_success 'dotdot is not an empty set' '
test_cmp expect actual
'
+test_expect_success 'arg before dashdash must be a revision (missing)' '
+ test_must_fail git rev-parse foobar -- 2>stderr &&
+ test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (file)' '
+ >foobar &&
+ test_must_fail git rev-parse foobar -- 2>stderr &&
+ test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
+ >foobar &&
+ git update-ref refs/heads/foobar HEAD &&
+ {
+ # we do not want to use rev-parse here, because
+ # we are testing it
+ cat .git/refs/heads/foobar &&
+ printf "%s\n" --
+ } >expect &&
+ git rev-parse foobar -- >actual &&
+ test_cmp expect actual
+'
+
test_done
--
1.8.5.524.g6743da6
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 2/2] rev-parse: diagnose ambiguous revision/filename arguments
2013-12-06 21:12 ` [PATCH 0/2] rev-parse and "--" Jeff King
2013-12-06 21:13 ` [PATCH 1/2] rev-parse: correctly diagnose revision errors before "--" Jeff King
@ 2013-12-06 21:15 ` Jeff King
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
1 sibling, 1 reply; 28+ messages in thread
From: Jeff King @ 2013-12-06 21:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
If you have both a file and a branch named "foo", running:
git log foo
will complain. We should do the same in rev-parse, and
demand that it be disambiguated with:
git rev-parse foo --
or
git rev-parse -- foo
Signed-off-by: Jeff King <peff@peff.net>
---
Hmm, looking at this again, I guess we need to give the same treatment
to the try_difference code path above, as "foo..bar" can be ambiguous
with a filename (and "git log" seems to diagnose that).
builtin/rev-parse.c | 5 ++++-
t/t1506-rev-parse-diagnosis.sh | 7 +++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index bb694ab..3ff4f8a 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -790,8 +790,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!get_sha1(name, sha1)) {
if (verify)
revs_count++;
- else
+ else {
show_rev(type, sha1, name);
+ if (!has_dashdash)
+ verify_non_filename(prefix, arg);
+ }
continue;
}
if (verify)
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 613d9bf..7ccbcf4 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -220,4 +220,11 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
test_cmp expect actual
'
+test_expect_success 'ambiguous arg without dashdash' '
+ >foobar &&
+ git update-ref refs/heads/foobar HEAD &&
+ test_must_fail git rev-parse foobar 2>stderr &&
+ test_i18ngrep ambiguous stderr
+'
+
test_done
--
1.8.5.524.g6743da6
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 0/3] rev-parse and "--"
2013-12-06 21:15 ` [PATCH 2/2] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
@ 2013-12-06 22:05 ` Jeff King
2013-12-06 22:05 ` [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--" Jeff King
` (4 more replies)
0 siblings, 5 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 22:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Fri, Dec 06, 2013 at 04:15:09PM -0500, Jeff King wrote:
> If you have both a file and a branch named "foo", running:
>
> git log foo
>
> will complain. We should do the same in rev-parse, and
> demand that it be disambiguated with:
>
> git rev-parse foo --
>
> or
>
> git rev-parse -- foo
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Hmm, looking at this again, I guess we need to give the same treatment
> to the try_difference code path above, as "foo..bar" can be ambiguous
> with a filename (and "git log" seems to diagnose that).
Here's a revised series which handles that:
[1/3]: rev-parse: correctly diagnose revision errors before "--"
[2/3]: rev-parse: be more careful with munging arguments
[3/3]: rev-parse: diagnose ambiguous revision/filename arguments
While fixing this commit, I noticed another bug whose fix is a
prerequisite. That's now patch 2 in the series. I think the first two
patches are correct and should be applied.
Patch 3 is the revised version of this patch which notices ambiguity.
However, I'm having second thoughts on it. I think it's the right thing
to do if you want to help people build something like "git log"
themselves. But it does mean that we are breaking somebody who does:
echo foo >HEAD
commit=$(git rev-parse HEAD)
I'm tempted to say that people who did that are stupid and wrong (and
ugly, too). They should probably be using "--verify" in this case. But
it has been that way for a long time, and there are two instances in our
test scripts that are broken by the patch.
Is it better for "rev-parse" to be more careful, and to behave more like
the rest of git? Or is better to be historically compatible?
One thing to note is that "git rev-parse HEAD" is slightly broken there
already. Because "git rev-parse $some_branch" may do very different
things than what the caller expects if $some_branch does not exist (but
there is a file with the same name). So maybe we are doing a favor by
calling out the problem; if they want a rev, they should be using
"--verify" (or "--").
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--"
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
@ 2013-12-06 22:05 ` Jeff King
2013-12-06 23:34 ` Jonathan Nieder
2013-12-06 22:07 ` [PATCH v2 2/3] rev-parse: be more careful with munging arguments Jeff King
` (3 subsequent siblings)
4 siblings, 1 reply; 28+ messages in thread
From: Jeff King @ 2013-12-06 22:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
Rev-parse understands that a "--" may separate revisions and
filenames, and that anything after the "--" is taken as-is.
However, it does not understand that anything before the
token must be a revision (which is the usual rule
implemented by the setup_revisions parser).
Since rev-parse prefers revisions to files when parsing
before the "--", we end up with the correct result (if such
an argument is a revision, we parse it as one, and if it is
not, it is an error either way). However, we misdiagnose
the errors:
$ git rev-parse foobar -- >/dev/null
fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ >foobar
$ git rev-parse foobar -- >/dev/null
fatal: bad flag '--' used after filename
In both cases, we should know that the real error is that
"foobar" is meant to be a revision, but could not be
resolved.
Signed-off-by: Jeff King <peff@peff.net>
---
builtin/rev-parse.c | 10 ++++++++++
t/t1506-rev-parse-diagnosis.sh | 24 ++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 1d9ecaf..bb694ab 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -488,6 +488,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+ int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
const char *name = NULL;
@@ -501,6 +502,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) {
+ has_dashdash = 1;
+ break;
+ }
+ }
+
prefix = setup_git_directory();
git_config(git_default_config, NULL);
for (i = 1; i < argc; i++) {
@@ -788,6 +796,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (verify)
die_no_single_rev(quiet);
+ if (has_dashdash)
+ die("bad revision '%s'", arg);
as_is = 1;
if (!show_file(arg, output_prefix))
continue;
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index f950c10..613d9bf 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -196,4 +196,28 @@ test_expect_success 'dotdot is not an empty set' '
test_cmp expect actual
'
+test_expect_success 'arg before dashdash must be a revision (missing)' '
+ test_must_fail git rev-parse foobar -- 2>stderr &&
+ test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (file)' '
+ >foobar &&
+ test_must_fail git rev-parse foobar -- 2>stderr &&
+ test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
+ >foobar &&
+ git update-ref refs/heads/foobar HEAD &&
+ {
+ # we do not want to use rev-parse here, because
+ # we are testing it
+ cat .git/refs/heads/foobar &&
+ printf "%s\n" --
+ } >expect &&
+ git rev-parse foobar -- >actual &&
+ test_cmp expect actual
+'
+
test_done
--
1.8.5.524.g6743da6
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 2/3] rev-parse: be more careful with munging arguments
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
2013-12-06 22:05 ` [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--" Jeff King
@ 2013-12-06 22:07 ` Jeff King
2013-12-07 0:04 ` Jonathan Nieder
2013-12-09 21:33 ` Eric Sunshine
2013-12-06 22:08 ` [PATCH v2 3/3] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
` (2 subsequent siblings)
4 siblings, 2 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 22:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
When rev-parse looks at whether an argument like "foo..bar"
or "foobar^@" is a difference or parent-shorthand, it
internally munges the arguments so that it can pass the
individual rev arguments to get_sha1. However, we do not
consistently un-munge the result.
For cases where we do not match (e.g., "doesnotexist..HEAD"),
we wouuld then want to try to treat the argument as a
filename. try_difference gets this right, and always
unmunges in this case. However, try_parent_shorthand never
unmunges, leading to incorrect error messages, or even
incorrect results:
$ git rev-parse foobar^@
foobar
fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ >foobar
$ git rev-parse foobar^@
foobar
For cases where we do match, neither function unmunges. This
does not currently matter, since we are done with the
argument. However, a future patch will do further
processing, and this prepares for it. In addition, it's
simply a confusing interface for some cases to modify the
const argument, and others not to.
Signed-off-by: Jeff King <peff@peff.net>
---
As an aside, this is one of those places where C's string functions do
gross things with const. We modify a const argument to the function
without any casts or warnings, because the return value from strstr
implicitly drops the const. Time for us all to move to C++ with
templated strstr, right?
builtin/rev-parse.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index bb694ab..a60fcd3 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -286,6 +286,7 @@ static int try_difference(const char *arg)
exclude = n;
}
}
+ *dotdot = '.';
return 1;
}
*dotdot = '.';
@@ -309,8 +310,10 @@ static int try_parent_shorthands(const char *arg)
return 0;
*dotdot = 0;
- if (get_sha1_committish(arg, sha1))
+ if (get_sha1_committish(arg, sha1)) {
+ *dotdot = '^';
return 0;
+ }
if (!parents_only)
show_rev(NORMAL, sha1, arg);
@@ -319,6 +322,7 @@ static int try_parent_shorthands(const char *arg)
show_rev(parents_only ? NORMAL : REVERSED,
parents->item->object.sha1, arg);
+ *dotdot = '^';
return 1;
}
--
1.8.5.524.g6743da6
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 3/3] rev-parse: diagnose ambiguous revision/filename arguments
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
2013-12-06 22:05 ` [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--" Jeff King
2013-12-06 22:07 ` [PATCH v2 2/3] rev-parse: be more careful with munging arguments Jeff King
@ 2013-12-06 22:08 ` Jeff King
2013-12-06 23:25 ` [PATCH v2 0/3] rev-parse and "--" Jonathan Nieder
2013-12-09 19:05 ` Junio C Hamano
4 siblings, 0 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 22:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
If you have both a file and a branch named "foo", running:
git log foo
will complain. We should do the same in rev-parse, and
demand that it be disambiguated with:
git rev-parse foo --
or
git rev-parse -- foo
Signed-off-by: Jeff King <peff@peff.net>
---
builtin/rev-parse.c | 12 ++++++++----
t/t1506-rev-parse-diagnosis.sh | 22 ++++++++++++++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index a60fcd3..a3a58bf 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -781,10 +781,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
/* Not a flag argument */
- if (try_difference(arg))
- continue;
- if (try_parent_shorthands(arg))
+ if (try_difference(arg) || try_parent_shorthands(arg)) {
+ if (!has_dashdash)
+ verify_non_filename(prefix, arg);
continue;
+ }
name = arg;
type = NORMAL;
if (*arg == '^') {
@@ -794,8 +795,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!get_sha1(name, sha1)) {
if (verify)
revs_count++;
- else
+ else {
show_rev(type, sha1, name);
+ if (!has_dashdash)
+ verify_non_filename(prefix, arg);
+ }
continue;
}
if (verify)
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 613d9bf..dc1f1dc 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -220,4 +220,26 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
test_cmp expect actual
'
+test_expect_success 'ambiguous arg without dashdash (normal)' '
+ >foobar &&
+ git update-ref refs/heads/foobar HEAD &&
+ test_must_fail git rev-parse foobar 2>stderr &&
+ test_i18ngrep ambiguous stderr
+'
+
+test_expect_success 'ambiguous arg without dashdash (difference)' '
+ >one..two &&
+ git update-ref refs/heads/one HEAD &&
+ git update-ref refs/heads/two HEAD &&
+ test_must_fail git rev-parse one..two 2>stderr &&
+ test_i18ngrep ambiguous stderr
+'
+
+test_expect_success 'ambiguous arg without dashdash (parents)' '
+ >"foobar^@" &&
+ git update-ref refs/heads/foobar HEAD &&
+ test_must_fail git rev-parse foobar^@ 2>stderr &&
+ test_i18ngrep ambiguous stderr
+'
+
test_done
--
1.8.5.524.g6743da6
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [BUG] redundant error message
2013-12-06 1:15 ` [BUG] redundant error message Duy Nguyen
@ 2013-12-06 22:13 ` Jeff King
0 siblings, 0 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 22:13 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Junio C Hamano, Git Mailing List
On Fri, Dec 06, 2013 at 08:15:52AM +0700, Duy Nguyen wrote:
> On Fri, Dec 6, 2013 at 4:28 AM, Jeff King <peff@peff.net> wrote:
> > BTW, the raw looping to find "--" made me wonder how we handle:
> >
> > git log --grep -- HEAD
> >
> > I'd expect it to be equivalent to:
> >
> > git log --grep=-- HEAD
> >
> > but it's not; we truncate the arguments and complain that --grep is
> > missing its argument. Which is probably good enough, given that the
> > alternative is doing a pass that understands all of the options. But it
> > does mean that the "--long-opt=arg" form is safer than the split form if
> > you are passing along an arbitrary "arg".
>
> Maybe we could make setup_revisions() use parse_options() someday,
> which understands about arguments and dashdash.
>
> $ ./git grep -e -- foo
> fatal: ambiguous argument 'foo': both revision and filename
> Use '--' to separate paths from revisions, like this:
> 'git <command> [<revision>...] -- [<file>...]'
> $ ./git grep -e -- -- foo
Yes, although we use it some in handle_revision_opt, I believe. The
problem isn't inherent to parse_options or not, though. To do it
correctly, we need to either:
1. make two passes with the code that actually understands the options
(be it parse_options or not); the first looking for "--", and the
second to do the actual parsing. Right now our first pass does not
understand the options at all.
2. store the non-option arguments (including "--"), and only resolve
and verify them after we have gone through the whole command-line
and know whether we hit a "--" or not.
I suspect the second option would be simpler, as neither parse-options
nor the current revision code is safe to run through twice (e.g.,
parse-options may have callbacks that add to a list, and we would need
to add some kind of "dry-run" flag).
It's something that would be nice to fix, but I don't see myself working
on it anytime soon. It's a lot of work for very little benefit.
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
` (2 preceding siblings ...)
2013-12-06 22:08 ` [PATCH v2 3/3] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
@ 2013-12-06 23:25 ` Jonathan Nieder
2013-12-06 23:30 ` Jeff King
2013-12-09 19:05 ` Junio C Hamano
4 siblings, 1 reply; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-06 23:25 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List
Jeff King wrote:
> Patch 3 is the revised version of this patch which notices ambiguity.
> However, I'm having second thoughts on it. I think it's the right thing
> to do if you want to help people build something like "git log"
> themselves. But it does mean that we are breaking somebody who does:
>
> echo foo >HEAD
> commit=$(git rev-parse HEAD)
>
> I'm tempted to say that people who did that are stupid and wrong (and
> ugly, too). They should probably be using "--verify" in this case. But
> it has been that way for a long time, and there are two instances in our
> test scripts that are broken by the patch.
Wouldn't the same thing happen for $(git rev-parse HEAD^..HEAD) when
there is a 'HEAD^..HEAD' file, too? --verify doesn't support that.
I think it's a nice idea to provide this functionality for people who
need it, which would mean protected by an option (--check-ambiguity or
something). I don't think it's a good change to do it
unconditionally.
My two cents,
Jonathan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-06 23:25 ` [PATCH v2 0/3] rev-parse and "--" Jonathan Nieder
@ 2013-12-06 23:30 ` Jeff King
0 siblings, 0 replies; 28+ messages in thread
From: Jeff King @ 2013-12-06 23:30 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List
On Fri, Dec 06, 2013 at 03:25:56PM -0800, Jonathan Nieder wrote:
> > commit=$(git rev-parse HEAD)
> >
> > I'm tempted to say that people who did that are stupid and wrong (and
> > ugly, too). They should probably be using "--verify" in this case. But
> > it has been that way for a long time, and there are two instances in our
> > test scripts that are broken by the patch.
>
> Wouldn't the same thing happen for $(git rev-parse HEAD^..HEAD) when
> there is a 'HEAD^..HEAD' file, too? --verify doesn't support that.
True, but they can use "rev-parse HEAD^..HEAD --", which is probably a
better alternative to --verify.
> I think it's a nice idea to provide this functionality for people who
> need it, which would mean protected by an option (--check-ambiguity or
> something). I don't think it's a good change to do it
> unconditionally.
I don't think it's worth making it conditional. Literally nobody has
asked for it. I was mostly trying to harmonize "rev-parse" and the rest
of the revision parser. If that's not worth doing, I'd just as soon drop
it (and people using "--" properly already get the right behavior).
-Peff
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--"
2013-12-06 22:05 ` [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--" Jeff King
@ 2013-12-06 23:34 ` Jonathan Nieder
0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-06 23:34 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List
Jeff King wrote:
> Since rev-parse prefers revisions to files when parsing
> before the "--", we end up with the correct result (if such
> an argument is a revision, we parse it as one, and if it is
> not, it is an error either way). However, we misdiagnose
> the errors:
>
> $ git rev-parse foobar -- >/dev/null
> fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
> Use '--' to separate paths from revisions, like this:
> 'git <command> [<revision>...] -- [<file>...]'
>
> $ >foobar
> $ git rev-parse foobar -- >/dev/null
> fatal: bad flag '--' used after filename
>
> In both cases, we should know that the real error is that
> "foobar" is meant to be a revision, but could not be
> resolved.
Neat.
[...]
> --- a/builtin/rev-parse.c
> +++ b/builtin/rev-parse.c
> @@ -488,6 +488,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
> int cmd_rev_parse(int argc, const char **argv, const char *prefix)
> {
> int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
> + int has_dashdash = 0;
> int output_prefix = 0;
> unsigned char sha1[20];
> const char *name = NULL;
> @@ -501,6 +502,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
> if (argc > 1 && !strcmp("-h", argv[1]))
> usage(builtin_rev_parse_usage);
>
> + for (i = 1; i < argc; i++) {
> + if (!strcmp(argv[i], "--")) {
> + has_dashdash = 1;
> + break;
> + }
> + }
> +
> prefix = setup_git_directory();
> git_config(git_default_config, NULL);
> for (i = 1; i < argc; i++) {
> @@ -788,6 +796,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
> }
> if (verify)
> die_no_single_rev(quiet);
> + if (has_dashdash)
> + die("bad revision '%s'", arg);
> as_is = 1;
Yep, this is the "fall back to looking for a file" part of rev-parse,
so erroring out if there as a dashdash coming is the right thing to
do. And a quick code search for "rev-parse.*\ --\ " reveals that
most callers would simply not be affected by this.
Thanks for a pleasant patch.
For what it's worth,
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/3] rev-parse: be more careful with munging arguments
2013-12-06 22:07 ` [PATCH v2 2/3] rev-parse: be more careful with munging arguments Jeff King
@ 2013-12-07 0:04 ` Jonathan Nieder
2013-12-09 21:33 ` Eric Sunshine
1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-07 0:04 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List
Jeff King wrote:
> As an aside, this is one of those places where C's string functions do
> gross things with const.
Yes, yuck.
The fundamental grossness is that argv is semantically char **
(assuming this doesn't segfault) but passed around as const char **.
I wonder why we don't use the same trick in git_extract_argv0_path and
when handling STRIP_EXTENSION in git.c.
Alternatively, try_difference could create a new buffer for its own
use. Originally (v0.99~273, 2005-06-13) this dotdot handling code was
pretty simple:
for (i = 1; i < argc; i++) {
char *arg = argv[i];
...
dotdot = strstr(arg, "..");
if (dotdot) {
unsigned char end[20];
char *n = dotdot+2;
*dotdot = 0;
if (!get_sha1(arg, sha1)) {
if (!*n)
n = "HEAD";
if (!get_sha1(n, end)) {
printf("%s\n", sha1_to_hex(end));
printf("^%s\n", sha1_to_hex(sha1));
continue;
}
}
*dotdot = '.';
}
printf("%s\n", arg);
}
The 'continue' without making the argument right again was justified
because we were done with the argument.
Now it is still not much more complicated --- the function is
logically just trying to parse the argument into a "this" and "next"
part and print them.
Something like the following (untested). Or if the allocation churn
is too much, it could use a static strbuf.
diff --git i/builtin/rev-parse.c w/builtin/rev-parse.c
index c76b89d..98262b3 100644
--- i/builtin/rev-parse.c
+++ w/builtin/rev-parse.c
@@ -234,37 +234,35 @@ static int try_difference(const char *arg)
unsigned char sha1[20];
unsigned char end[20];
const char *next;
- const char *this;
+ struct strbuf this = STRBUF_INIT;
int symmetric;
- static const char head_by_default[] = "HEAD";
if (!(dotdot = strstr(arg, "..")))
return 0;
next = dotdot + 2;
- this = arg;
symmetric = (*next == '.');
-
- *dotdot = 0;
next += symmetric;
- if (!*next)
- next = head_by_default;
- if (dotdot == arg)
- this = head_by_default;
-
- if (this == head_by_default && next == head_by_default &&
- !symmetric) {
+ if (!*next && dotdot == arg && !symmetric)
/*
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
- *dotdot = '.';
return 0;
+
+ strbuf_add(&this, arg, dotdot - arg);
+
+ if (!*next)
+ next = "HEAD";
+ if (dotdot == arg) {
+ strbuf_reset(&this);
+ strbuf_addstr(&this, "HEAD");
}
- if (!get_sha1_committish(this, sha1) && !get_sha1_committish(next, end)) {
+ if (!get_sha1_committish(this.buf, sha1)
+ && !get_sha1_committish(next, end)) {
show_rev(NORMAL, end, next);
- show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
+ show_rev(symmetric ? NORMAL : REVERSED, sha1, this.buf);
if (symmetric) {
struct commit_list *exclude;
struct commit *a, *b;
@@ -279,9 +277,10 @@ static int try_difference(const char *arg)
exclude = n;
}
}
+ strbuf_release(&this);
return 1;
}
- *dotdot = '.';
+ strbuf_release(&this);
return 0;
}
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
` (3 preceding siblings ...)
2013-12-06 23:25 ` [PATCH v2 0/3] rev-parse and "--" Jonathan Nieder
@ 2013-12-09 19:05 ` Junio C Hamano
2013-12-09 19:12 ` Jonathan Nieder
4 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2013-12-09 19:05 UTC (permalink / raw)
To: Jeff King; +Cc: Duy Nguyen, Git Mailing List
Jeff King <peff@peff.net> writes:
> Is it better for "rev-parse" to be more careful, and to behave more like
> the rest of git? Or is better to be historically compatible?
>
> One thing to note is that "git rev-parse HEAD" is slightly broken there
> already. Because "git rev-parse $some_branch" may do very different
> things than what the caller expects if $some_branch does not exist (but
> there is a file with the same name). So maybe we are doing a favor by
> calling out the problem; if they want a rev, they should be using
> "--verify" (or "--").
I tend to agree with the reasoning in the last sentence. Let's cook
it for a while and see what happens.
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-09 19:05 ` Junio C Hamano
@ 2013-12-09 19:12 ` Jonathan Nieder
2013-12-09 19:23 ` Jonathan Nieder
2013-12-09 20:48 ` Junio C Hamano
0 siblings, 2 replies; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-09 19:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Duy Nguyen, Git Mailing List
Junio C Hamano wrote:
>> So maybe we are doing a favor by
>> calling out the problem; if they want a rev, they should be using
>> "--verify" (or "--").
>
> I tend to agree with the reasoning in the last sentence. Let's cook
> it for a while and see what happens.
Isn't this essentially breaking a contract that would have been relied
on by any script that used "git rev-parse HEAD~3..HEAD"? Worse, it's
breaking that contract in a way that no one would notice until they
are asked to manipulate a worktree with a file named 'HEAD~3..HEAD'
--- in other words, the breakage it introduces is painfully subtle.
I agree that "git rev-parse HEAD" is better written as "git rev-parse
--verify HEAD" and hence not so much worth worrying about, but I don't
find it easy to believe that people should have anticipated this
change and added a trailing "--" to more complex rev-parse
expressions.
So to be clear, I think unless it is protected by a new option, this
is a bad idea.
Hope that helps,
Jonathan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-09 19:12 ` Jonathan Nieder
@ 2013-12-09 19:23 ` Jonathan Nieder
2013-12-09 20:48 ` Junio C Hamano
1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-09 19:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Duy Nguyen, Git Mailing List
Jonathan Nieder wrote:
> Isn't this essentially breaking a contract
To clarify, if there were some strong motivation --- e.g. if this
were resolving some security problem --- then I would be all for
breaking compatibility in this way. What's confusing to me is that I
just don't see the motivation. Why wouldn't someone that wants this
functionality be able to pass a flag for it?
Is the idea that without a flag it's easier to teach or something?
Hoping that clarifies,
Jonathan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-09 19:12 ` Jonathan Nieder
2013-12-09 19:23 ` Jonathan Nieder
@ 2013-12-09 20:48 ` Junio C Hamano
2013-12-09 20:56 ` Jonathan Nieder
1 sibling, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2013-12-09 20:48 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Jeff King, Duy Nguyen, Git Mailing List
Jonathan Nieder <jrnieder@gmail.com> writes:
> Junio C Hamano wrote:
>
>>> So maybe we are doing a favor by
>>> calling out the problem; if they want a rev, they should be using
>>> "--verify" (or "--").
>>
>> I tend to agree with the reasoning in the last sentence. Let's cook
>> it for a while and see what happens.
>
> Isn't this essentially breaking a contract that would have been relied
> on by any script that used "git rev-parse HEAD~3..HEAD"? Worse, it's
> breaking that contract in a way that no one would notice until they
> are asked to manipulate a worktree with a file named 'HEAD~3..HEAD'
> --- in other words, the breakage it introduces is painfully subtle.
>
> I agree that "git rev-parse HEAD" is better written as "git rev-parse
> --verify HEAD" and hence not so much worth worrying about,
I do not share the "with --verify is better hence no problem"
reasoning. My "not so much worth worrying about" comes solely from
a hunch that nobody has "HEAD~3..HEAD" in their working directory,
and if somebody has one, then they must be using "--verify" (or a
clarifying "--"), because their "git log" and whatever they use "git
rev-parse HEAD~3..HEAD" for would behave very differently otherwise.
So it is not merely "--verify is better"---in a situation where the
backward incompatibility matters, I doubt the existing behaves
sensibly in the first place.
But if we cook it for a while, I suspect that we will find more and
more breakages of expectations in the existing scripts in and out of
the tree; in general, I hate _any_ change, and I do not mind
dropping it ;-).
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-09 20:48 ` Junio C Hamano
@ 2013-12-09 20:56 ` Jonathan Nieder
2013-12-09 21:10 ` Junio C Hamano
0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Nieder @ 2013-12-09 20:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Duy Nguyen, Git Mailing List
Junio C Hamano wrote:
> I do not share the "with --verify is better hence no problem"
> reasoning. My "not so much worth worrying about" comes solely from
> a hunch that nobody has "HEAD~3..HEAD" in their working directory,
That's what makes it a problem. This change makes it very easy to
make a general-purpose script that breaks in an edge case that the
script's author is not likely to run into. Then as soon as someone
adds a file with such a name to the test data in their repo, their
favorite general-purpose repo munger just breaks.
If we wanted to forbid git from tracking files named HEAD~3..HEAD
altogether, that would be a different story.
> and if somebody has one, then they must be using "--verify" (or a
> clarifying "--"), because their "git log" and whatever they use "git
> rev-parse HEAD~3..HEAD" for would behave very differently otherwise.
Isn't protecting against this kind of thing the reason we ask authors
of general-purpose scripts to use "simple, do what I say and not what
I mean" plumbing commands?
Another relevant detail is that using rev-parse with "--" is more
painful than without, since it includes the "--" in its output.
Without this change, it seems much more likely to me that someone
would do
git rev-parse <commits> |
while read commit
do
...
done
than
git rev-parse <commits> -- |
while read commit
do
if test "$commit" = "--"
then
continue
fi
...
done
> So it is not merely "--verify is better"---in a situation where the
> backward incompatibility matters, I doubt the existing behaves
> sensibly in the first place.
What in the former of the above two loops is broken?
> But if we cook it for a while, I suspect that we will find more and
> more breakages of expectations in the existing scripts in and out of
> the tree;
Alas, probably no, because nobody has "HEAD~3..HEAD" in their working
directory. That's exactly the problem --- it creates an edge case
that nobody is likely to test until the once-in-a-few-years moment
when they need it.
Jonathan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/3] rev-parse and "--"
2013-12-09 20:56 ` Jonathan Nieder
@ 2013-12-09 21:10 ` Junio C Hamano
0 siblings, 0 replies; 28+ messages in thread
From: Junio C Hamano @ 2013-12-09 21:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Jeff King, Duy Nguyen, Git Mailing List
Jonathan Nieder <jrnieder@gmail.com> writes:
>> But if we cook it for a while, I suspect that we will find more and
>> more breakages of expectations in the existing scripts in and out of
>> the tree;
>
> Alas, probably no, because nobody has "HEAD~3..HEAD" in their working
> directory. That's exactly the problem --- it creates an edge case
> that nobody is likely to test...
I didn't mean to say that running and encoutering the issue is the
only way to find "more breakges of expectations", by the way. I am
still on the fence, but leaning towards not merging it too hastily.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/3] rev-parse: be more careful with munging arguments
2013-12-06 22:07 ` [PATCH v2 2/3] rev-parse: be more careful with munging arguments Jeff King
2013-12-07 0:04 ` Jonathan Nieder
@ 2013-12-09 21:33 ` Eric Sunshine
1 sibling, 0 replies; 28+ messages in thread
From: Eric Sunshine @ 2013-12-09 21:33 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List
On Fri, Dec 6, 2013 at 5:07 PM, Jeff King <peff@peff.net> wrote:
> When rev-parse looks at whether an argument like "foo..bar"
> or "foobar^@" is a difference or parent-shorthand, it
> internally munges the arguments so that it can pass the
> individual rev arguments to get_sha1. However, we do not
> consistently un-munge the result.
>
> For cases where we do not match (e.g., "doesnotexist..HEAD"),
> we wouuld then want to try to treat the argument as a
s/wouuld/would/
> filename. try_difference gets this right, and always
> unmunges in this case. However, try_parent_shorthand never
> unmunges, leading to incorrect error messages, or even
> incorrect results:
>
> $ git rev-parse foobar^@
> foobar
> fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
> Use '--' to separate paths from revisions, like this:
> 'git <command> [<revision>...] -- [<file>...]'
>
> $ >foobar
> $ git rev-parse foobar^@
> foobar
>
> For cases where we do match, neither function unmunges. This
> does not currently matter, since we are done with the
> argument. However, a future patch will do further
> processing, and this prepares for it. In addition, it's
> simply a confusing interface for some cases to modify the
> const argument, and others not to.
>
> Signed-off-by: Jeff King <peff@peff.net>
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2013-12-09 21:33 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-05 10:07 [BUG] redundant error message Duy Nguyen
2013-12-05 19:15 ` Jeff King
2013-12-05 20:00 ` Junio C Hamano
2013-12-05 20:03 ` Jeff King
2013-12-05 20:15 ` Junio C Hamano
2013-12-05 21:00 ` Jeff King
2013-12-05 21:28 ` Jeff King
2013-12-05 21:44 ` Junio C Hamano
2013-12-06 21:12 ` [PATCH 0/2] rev-parse and "--" Jeff King
2013-12-06 21:13 ` [PATCH 1/2] rev-parse: correctly diagnose revision errors before "--" Jeff King
2013-12-06 21:15 ` [PATCH 2/2] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
2013-12-06 22:05 ` [PATCH v2 0/3] rev-parse and "--" Jeff King
2013-12-06 22:05 ` [PATCH v2 1/3] rev-parse: correctly diagnose revision errors before "--" Jeff King
2013-12-06 23:34 ` Jonathan Nieder
2013-12-06 22:07 ` [PATCH v2 2/3] rev-parse: be more careful with munging arguments Jeff King
2013-12-07 0:04 ` Jonathan Nieder
2013-12-09 21:33 ` Eric Sunshine
2013-12-06 22:08 ` [PATCH v2 3/3] rev-parse: diagnose ambiguous revision/filename arguments Jeff King
2013-12-06 23:25 ` [PATCH v2 0/3] rev-parse and "--" Jonathan Nieder
2013-12-06 23:30 ` Jeff King
2013-12-09 19:05 ` Junio C Hamano
2013-12-09 19:12 ` Jonathan Nieder
2013-12-09 19:23 ` Jonathan Nieder
2013-12-09 20:48 ` Junio C Hamano
2013-12-09 20:56 ` Jonathan Nieder
2013-12-09 21:10 ` Junio C Hamano
2013-12-06 1:15 ` [BUG] redundant error message Duy Nguyen
2013-12-06 22:13 ` Jeff King
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).