diff options
authorJunio C Hamano <>2019-01-14 23:29:31 (GMT)
committerJunio C Hamano <>2019-01-14 23:29:31 (GMT)
commitecdc7cbbac04241f1e5a90fb1fff13cff2ed7a82 (patch)
parent932b867be0cec606ec7355fc25de13ace42f4c71 (diff)
parente0e7cb8080cb4a0b3a24f288bf363fe517b49790 (diff)
Merge branch 'tb/log-G-binary'
"git log -G<regex>" looked for a hunk in the "git log -p" patch output that contained a string that matches the given pattern. Optimize this code to ignore binary files, which by default will not show any hunk that would match any pattern (unless textconv or the --text option is in effect, that is). * tb/log-G-binary: log -G: ignore binary files
4 files changed, 48 insertions, 1 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 0378cd5..b94d332 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -524,6 +524,8 @@ struct), and want to know the history of that block since it first
came into being: use the feature iteratively to feed the interesting
block in the preimage back into `-S`, and keep going until you get the
very first version of the block.
+Binary files are searched as well.
Look for differences whose patch text contains added/removed
@@ -543,6 +545,9 @@ While `git log -G"regexec\(regexp"` will show this commit, `git log
-S"regexec\(regexp" --pickaxe-regex` will not (because the number of
occurrences of that string did not change).
+Unless `--text` is supplied patches of binary files without a textconv
+filter will be ignored.
See the 'pickaxe' entry in linkgit:gitdiffcore[7] for more
diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt
index c0a60f3..c970d9f 100644
--- a/Documentation/gitdiffcore.txt
+++ b/Documentation/gitdiffcore.txt
@@ -242,7 +242,8 @@ textual diff has an added or a deleted line that matches the given
regular expression. This means that it will detect in-file (or what
rename-detection considers the same file) moves, which is noise. The
implementation runs diff twice and greps, and this can be quite
+expensive. To speed things up binary files without textconv filters
+will be ignored.
When `-S` or `-G` are used without `--pickaxe-all`, only filepairs
that match their respective criterion are kept in the output. When
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index ad939d2..a9c6d60 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -154,6 +154,12 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
if (textconv_one == textconv_two && diff_unmodified_pair(p))
return 0;
+ if ((o->pickaxe_opts & DIFF_PICKAXE_KIND_G) &&
+ !o->flags.text &&
+ ((!textconv_one && diff_filespec_is_binary(o->repo, p->one)) ||
+ (!textconv_two && diff_filespec_is_binary(o->repo, p->two))))
+ return 0;
mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr);
mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr);
diff --git a/t/ b/t/
index 844df76..5d06f5f 100755
--- a/t/
+++ b/t/
@@ -106,4 +106,39 @@ test_expect_success 'log -S --no-textconv (missing textconv tool)' '
rm .gitattributes
+test_expect_success 'setup log -[GS] binary & --text' '
+ git checkout --orphan GS-binary-and-text &&
+ git read-tree --empty &&
+ printf "a\na\0a\n" >data.bin &&
+ git add data.bin &&
+ git commit -m "create binary file" data.bin &&
+ printf "a\na\0a\n" >>data.bin &&
+ git commit -m "modify binary file" data.bin &&
+ git rm data.bin &&
+ git commit -m "delete binary file" data.bin &&
+ git log >full-log
+test_expect_success 'log -G ignores binary files' '
+ git log -Ga >log &&
+ test_must_be_empty log
+test_expect_success 'log -G looks into binary files with -a' '
+ git log -a -Ga >log &&
+ test_cmp log full-log
+test_expect_success 'log -G looks into binary files with textconv filter' '
+ test_when_finished "rm .gitattributes" &&
+ echo "* diff=bin" >.gitattributes &&
+ git -c diff.bin.textconv=cat log -Ga >log &&
+ test_cmp log full-log
+test_expect_success 'log -S looks into binary files' '
+ git log -Sa >log &&
+ test_cmp log full-log