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)