-3

As far as I can tell there are 2 different flags to filter by patch content

  • -S for simple string matches
  • -G for regex matches

Now I am not certain why there is a need for 2 separate flags, since any -S argument can be written as a -G argument.

Is there a performance or other notable difference why I should choose one over the other in certain cases?

  • Does this answer your question? [How to grep (search) committed code in the Git history](https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history) – mkrieger1 May 03 '21 at 13:59
  • 1
    See https://stackoverflow.com/a/12430097 – mkrieger1 May 03 '21 at 14:00
  • 2
    Consider reading the documentation? https://git-scm.com/docs/git-log#Documentation/git-log.txt--Gltregexgt – evolutionxbox May 03 '21 at 14:00
  • `since any -S argument can be written as a -G argument.` And basic regex can be extended, but there's `grep -E` and `sed -E`. – KamilCuk May 03 '21 at 14:04
  • Well, try and find the commit where you created a regular expression... but setting a regular expression of the regular expression. It can be done. It isn't fun. Are you really asking for the difference (as title suggests) or for the rationale of being able to search by exact strings (as question itself suggests)? – Álvaro González May 03 '21 at 14:08
  • @evolutionxbox If the documentation actually touched on what I am asking, that would be excellent. Did I ask for `-S` in combination with the `--pickaxe-regex` flag? No! –  May 03 '21 at 16:12

2 Answers2

3

Let me re-express what LeGEC's answer says, in a shorter way:1

  • There are two differences between -S and -G.

  • One is string vs regexp (as you already noted).

  • The other is that -S demands that the match occur a different number of times in the left and right (- and +) sides of the match. -G merely demands that the match occur in at least one of the two sides.

You can use --pickaxe-regex to eliminate the first difference, but not the second.


1Those who have read my long-form answers may now all be shocked.

torek
  • 448,244
  • 59
  • 642
  • 775
2

There is indeed a difference between the patterns that are accepted by -S (strings by default, can be changed to a regexp using --pickaxe-regexp) and -G (always interpreted as regexp), but, while both these options build on "searching for that pattern in the diff of each commit", they have a deeper difference :

  • -G <pattern> will report any commit where at least one of the diff chunks contains a line matching <pattern>
  • -S <pattern> will count the total numbber of added lines which match, count the total number of deleted lines which match, and will report a commit only if these two counts are different.

There is a pretty explanatory paragraph about the differences between -S and -G in git documentation :

To illustrate the difference between -S<regex> --pickaxe-regex and -G<regex>, consider a commit with the following diff in the same file:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of that string did not change).

(note: the --pickaxe-regexp in that paragraph is sort of a red herring, the example tries to match a fixed string anyway. The author of the docs could have written : " -G"frotz\(nitfol" will show this commit, -S"frotz(nitfol" will not " [<- the astute reader will notice the blatant absence of any '\' character in the second pattern], or alternatively choose an example pattern where no special char was involved)

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • But I was asking about `-S`, not in combination with the `--pickaxe-regex` flag. Has anyone actually read my question? –  May 03 '21 at 16:07
  • 1
    This is what I answered with, until I read the `--pickaxe-regex` part. So annoyingly it does not answer the question. – evolutionxbox May 03 '21 at 16:14
  • @evolutionbox : indeed, plus it is mentioned in the documentation snippet which I dutyfully copied from your deleted answer. There is the "string / regexp" distinction. – LeGEC May 03 '21 at 19:57
  • @ErikAigner : the statement that doesn't hold in your question is : "since any `-S` argument can be written as a `-G` argument". As stated in the docs, `-S` will report only commits where the "number of matches" changes, whereas `-G` will report any commit where the "number of matches" is at least 1. You would have to write a script on top of the output of `-G` to get the behavior of `-S`. – LeGEC May 03 '21 at 20:20
  • There is indeed the "string / regexp" difference, but that's not the main reason why these two options exist. – LeGEC May 03 '21 at 20:20