8

git grep seems to have simpler rules than regular GNU grep, which will allow you to search for tabs and to escape special characters with a backslash. I am trying to find occurrences of the string ->upload, and no way of escaping it seems to work.

How do I run git grep "->upload"?

$ git grep ->upload
No output; return 0
$ git grep "->upload"
error: unknown switch `>'
git grep "\-\>upload"
No output; return error
$ git grep '->upload'
error: unknown switch `>'
TRiG
  • 10,148
  • 7
  • 57
  • 107
  • Including the error message in the question would have let folks jump directly to the problem (which doesn't actually relate to the `>`). Try `git grep -upload` -- you'll see a very similar issue. – Charles Duffy Dec 19 '17 at 16:48
  • 1
    Repeating myself again: Try `git grep '-upload'`, with no `>` -- you'll still get "unknown switch", just with a different character being the immediate point of breakage. The `>` is included in the message only because it's the first character after the leading `-` that isn't recognized as a valid option. – Charles Duffy Dec 19 '17 at 16:51
  • 1
    BTW, `git grep "->upload"` and `git grep '->upload'` are exactly the same (likewise `git grep -\>upload`), to the point that `git` has no way to distinguish which of the three it was called as; the list of C strings passed to git's `main()` function is precisely identical in each of these cases. – Charles Duffy Dec 19 '17 at 16:54
  • 1
    Including the error message is great advice, and this is one instance where git fails miserably. In 2.14.1, this particular error generates 65 lines of error messages, only 1 of which is useful. If your terminal has less than 65 lines, that one useful error message has scrolled off the top of the tty. Rant off. – William Pursell Dec 19 '17 at 17:04

2 Answers2

13

When doubt, use a single-character class rather than a backslash to make a single character literal inside a regex:

git grep -e '-[>]upload'

Whereas the meaning of a backslash can be different depending on the specific character and the specific regex syntax in use, [>] means the same thing consistently.

That said, the most immediate issue here isn't caused by the > but by the leading dash, which makes the string indistinguishable from a list of options.

The -e is needed not because of the >, but because of the -. Without it, ->upload would be treated as a series of flags (->, -u, -p, -l, -o, -a, -d).


That said, you can get away without the -e by also moving the dash into a character class, thus making it no longer the first character on the command line:

git grep '[-][>]upload'
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 2
    Also note the common solution: `git grep -- -\>upload` Using two hyphens to indicate end of options is a common idiom. – William Pursell Dec 19 '17 at 17:01
  • @WilliamPursell. That's irritating, because [I already knew that](https://askubuntu.com/a/813432/652), but had forgotten it. – TRiG Dec 19 '17 at 17:02
  • *nod*; I prefer to `-e` to `--` in this case because it's more explicit and expressive: It means that the next string is the pattern to match, distinguishing it from, say, a filename (the other kind of data legal after `--`). – Charles Duffy Dec 19 '17 at 17:05
10
git grep -F -- '->upload'

Option -F means: use fixed strings for patterns (don't interpret pattern as a regex).

-- separates options from arguments to avoid interpreting -> as an option.

phd
  • 82,685
  • 13
  • 120
  • 165