Merge branch 'tb/log-G-binary'
authorJunio C Hamano <gitster@pobox.com>
Mon, 14 Jan 2019 23:29:31 +0000 (15:29 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 14 Jan 2019 23:29:31 +0000 (15:29 -0800)
"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

Documentation/diff-options.txt
Documentation/gitdiffcore.txt
diffcore-pickaxe.c
t/t4209-log-pickaxe.sh
index 0378cd574eb01069baba14221d511f580565c0eb..b94d332f71b0ff58fb12527f8ba13788b8aa6eeb 100644 (file)
@@ -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.
 
 -G<regex>::
        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
 information.
 
index c0a60f315811c788f3431b5757c38ffcea487386..c970d9fe438a091dc19900a4de1973ac4bcc4434 100644 (file)
@@ -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.
+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
index ad939d2861554746a9fd52947a38943928ece552..a9c6d60df22862e47ccb7fc1c7de9ed7cc4b1236 100644 (file)
@@ -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);
 
index 844df760f7d1c2b1b25eb01fada039efd0354711..5d06f5f45eace6010c1a003e03a814b5ba03f324 100755 (executable)
@@ -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
+'
+
 test_done