From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Jan Engelhardt <jengelh@medozas.de>, git@vger.kernel.org
Subject: Re: git-grep: option parsing conflicts with prefix-dash searches
Date: Fri, 5 Feb 2010 22:51:43 -0500 [thread overview]
Message-ID: <20100206035143.GA31784@sigill.intra.peff.net> (raw)
In-Reply-To: <7vsk9fs1j9.fsf@alter.siamese.dyndns.org>
On Fri, Feb 05, 2010 at 03:31:06PM -0800, Junio C Hamano wrote:
> Jan Engelhardt <jengelh@medozas.de> writes:
>
> > Just about now I wanted to grep for accesses of a particular struct
> > member. Needless to say that it was not a very amusing experience.
> > I would expect that (1) probably fails:
> >
> > (1) $ git grep '->cnt' net/ipv4/netfilter/
> > error: unknown switch `>'
> >
> > So far so good, seems reasonable and matches what I would expect from
> > most other userspace tools. So let's add -- to terminate the option
> > list:
>
> Also you can say "grep -e '->cnt'". Not just "git grep" but regular grep
> understands this, too.
GNU grep understands "grep -- '->cnt'", so I find myself typing it a
lot. Even though "--" is used for revision and pathname separation, I
don't think there is a conflict in also using it to separate options
from patterns for the case that there is no "-e" at all. In other words:
git grep -- foo
is not ambiguous. That "--" could not possibly be separating revisions
from pathnames because we have not yet seen any pattern, which is bogus.
In a case like:
git grep -e pattern -- foo
I think it is clear that the "--" is separating pathnames, because we
already have a pathname. This matches standard grep, which will treat
the first non-option as a pattern only if we have no "-e" pattern.
So I think we can do just do this:
diff --git a/builtin-grep.c b/builtin-grep.c
index 0ef849c..46ffc1d 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -889,6 +889,16 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
/* die the same way as if we did it at the beginning */
setup_git_directory();
+ /*
+ * skip a -- separator; we know it cannot be
+ * separating revisions from pathnames if
+ * we haven't even had any patterns yet
+ */
+ if (argc > 0 && !opt.pattern_list && !strcmp(argv[0], "--")) {
+ argv++;
+ argc--;
+ }
+
/* First unrecognized non-option token */
if (argc > 0 && !opt.pattern_list) {
append_grep_pattern(&opt, argv[0], "command line", 0,
and make everybody happy. But I admit I haven't thought about it more
than 5 minutes or so, so perhaps there is a case I am missing that will
be ambiguous or confusing. The worst I could come up with is the
double-double-dash case:
git grep -- pattern revision -- pathname
It is perhaps not as pretty as
git grep -e pattern revision -- pathname
but I don't think it is ambiguous.
> > (2) $ git grep -- '->cnt' net/ipv4/netfilter/
> > fatal: bad flag '->cnt' used after filename
> >
> > *bzzt*.
>
> This indeed is bzzt, especially if you had a file called "./->cnt" in the
> work tree. That would mean that you cannot tell the command to look for a
> pattern in the work tree.
>
> But because you are not giving anything before "--", that "git grep" is
> not looking for anything. Indeed, (2) is a user error. If you try this:
That is not quite true. The way "git grep" is implemented now, it is
actually grepping for "--". parse_options stops at the "--", leaving it
in argv, and then we assume whatever is left by parse_options is a
pattern (since we saw no "-e"). But of course it is looking in the
'->cnt' pathspec (or revision!), which is bogus (and gets you "bad flag used
after filename").
But as you noted with:
> > What works is (3).
> >
> > (3) $ git grep -- -- '->cnt' net/ipv4/netfilter/
...disambiguating the pathspec with the extra "--" gets it past option
parsing and looking for "--".
So actually my patch above is breaking somebody who truly wanted to grep
for "--" by doing
git grep --
but that is sufficiently insane that I'm not too worried about it.
-Peff
next prev parent reply other threads:[~2010-02-06 3:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-05 23:09 git-grep: option parsing conflicts with prefix-dash searches Jan Engelhardt
2010-02-05 23:17 ` Jan Engelhardt
2010-02-05 23:27 ` Santi Béjar
2010-02-05 23:34 ` Junio C Hamano
2010-02-05 23:31 ` Junio C Hamano
2010-02-06 3:51 ` Jeff King [this message]
2010-02-06 4:53 ` Junio C Hamano
2010-02-06 8:17 ` Miles Bader
2010-02-06 11:58 ` Jeff King
2010-02-06 17:39 ` Junio C Hamano
2010-02-07 4:44 ` Jeff King
2010-02-08 1:06 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100206035143.GA31784@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jengelh@medozas.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).