The -G<regex> option of log looks for the differences whose patch text
contains added/removed lines that match regex.
Currently -G looks also into patches of binary files (which
according to [1]) is binary as well.
This has a couple of issues:
- It makes the pickaxe search slow. In a proprietary repository of the
  author with only ~5500 commits and a total .git size of ~300MB
  searching takes ~13 seconds
    $time git log -Gwave > /dev/null
    real    0m13,241s
    user    0m12,596s
    sys     0m0,644s
  whereas when we ignore binary files with this patch it takes ~4s
    $time ~/devel/git/git log -Gwave > /dev/null
    real    0m3,713s
    user    0m3,608s
    sys     0m0,105s
  which is a speedup of more than fourfold.
- The internally used algorithm for generating patch text is based on
  xdiff and its states in [1]
  > The output format of the binary patch file is proprietary
  > (and binary) and it is basically a collection of copy and insert
  > commands [..]
  which means that the current format could change once the internal
  algorithm is changed as the format is not standardized. In addition
  the git binary patch format used for preparing patches for git apply
  is *different* from the xdiff format as can be seen by comparing
  git log -p -a
    commit 6e95bf4bafccf14650d02ab57f3affe669be10cf
    Author: A U Thor <author@example.com>
    Date:   Thu Apr 7 15:14:13 2005 -0700
        modify binary file
    diff --git a/data.bin b/data.bin
    index f414c84..edfeb6f 100644
    --- a/data.bin
    +++ b/data.bin
    @@ -1,2 +1,4 @@
     a
     a^@a
    +a
    +a^@a
  with git log --binary
    commit 6e95bf4bafccf14650d02ab57f3affe669be10cf
    Author: A U Thor <author@example.com>
    Date:   Thu Apr 7 15:14:13 2005 -0700
        modify binary file
    diff --git a/data.bin b/data.bin
    index f414c84bd3aa25fa07836bb1fb73db784635e24b..edfeb6f501[..]
    GIT binary patch
    literal 12
    QcmYe~N@Pgn0zx1O01)N^ZvX%Q
    literal 6
    NcmYe~N@Pgn0ssWg0XP5v
  which seems unexpected.
To resolve these issues this patch makes -G<regex> ignore binary files
by default. Textconv filters are supported and also -a/--text for
getting the old and broken behaviour back.
The -S<block of text> option of log looks for differences that changes
the number of occurrences of the specified block of text (i.e.
addition/deletion) in a file. As we want to keep the current behaviour,
add a test to ensure it stays that way.
[1]: http://www.xmailserver.org/xdiff.html
Signed-off-by: Thomas Braun <thomas.braun@virtuell-zuhause.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/sh
 | 
						|
 | 
						|
test_description='log --grep/--author/--regexp-ignore-case/-S/-G'
 | 
						|
. ./test-lib.sh
 | 
						|
 | 
						|
test_log () {
 | 
						|
	expect=$1
 | 
						|
	kind=$2
 | 
						|
	needle=$3
 | 
						|
	shift 3
 | 
						|
	rest=$@
 | 
						|
 | 
						|
	case $kind in
 | 
						|
	--*)
 | 
						|
		opt=$kind=$needle
 | 
						|
		;;
 | 
						|
	*)
 | 
						|
		opt=$kind$needle
 | 
						|
		;;
 | 
						|
	esac
 | 
						|
	case $expect in
 | 
						|
	expect_nomatch)
 | 
						|
		match=nomatch
 | 
						|
		;;
 | 
						|
	*)
 | 
						|
		match=match
 | 
						|
		;;
 | 
						|
	esac
 | 
						|
 | 
						|
	test_expect_success "log $kind${rest:+ $rest} ($match)" "
 | 
						|
		git log $rest $opt --format=%H >actual &&
 | 
						|
		test_cmp $expect actual
 | 
						|
	"
 | 
						|
}
 | 
						|
 | 
						|
# test -i and --regexp-ignore-case and expect both to behave the same way
 | 
						|
test_log_icase () {
 | 
						|
	test_log $@ --regexp-ignore-case
 | 
						|
	test_log $@ -i
 | 
						|
}
 | 
						|
 | 
						|
test_expect_success setup '
 | 
						|
	>expect_nomatch &&
 | 
						|
 | 
						|
	>file &&
 | 
						|
	git add file &&
 | 
						|
	test_tick &&
 | 
						|
	git commit -m initial &&
 | 
						|
	git rev-parse --verify HEAD >expect_initial &&
 | 
						|
 | 
						|
	echo Picked >file &&
 | 
						|
	git add file &&
 | 
						|
	test_tick &&
 | 
						|
	git commit --author="Another Person <another@example.com>" -m second &&
 | 
						|
	git rev-parse --verify HEAD >expect_second
 | 
						|
'
 | 
						|
 | 
						|
test_log	expect_initial	--grep initial
 | 
						|
test_log	expect_nomatch	--grep InItial
 | 
						|
test_log_icase	expect_initial	--grep InItial
 | 
						|
test_log_icase	expect_nomatch	--grep initail
 | 
						|
 | 
						|
test_log	expect_second	--author Person
 | 
						|
test_log	expect_nomatch	--author person
 | 
						|
test_log_icase	expect_second	--author person
 | 
						|
test_log_icase	expect_nomatch	--author spreon
 | 
						|
 | 
						|
test_log	expect_nomatch	-G picked
 | 
						|
test_log	expect_second	-G Picked
 | 
						|
test_log_icase	expect_nomatch	-G pickle
 | 
						|
test_log_icase	expect_second	-G picked
 | 
						|
 | 
						|
test_expect_success 'log -G --textconv (missing textconv tool)' '
 | 
						|
	echo "* diff=test" >.gitattributes &&
 | 
						|
	test_must_fail git -c diff.test.textconv=missing log -Gfoo &&
 | 
						|
	rm .gitattributes
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success 'log -G --no-textconv (missing textconv tool)' '
 | 
						|
	echo "* diff=test" >.gitattributes &&
 | 
						|
	git -c diff.test.textconv=missing log -Gfoo --no-textconv >actual &&
 | 
						|
	test_cmp expect_nomatch actual &&
 | 
						|
	rm .gitattributes
 | 
						|
'
 | 
						|
 | 
						|
test_log	expect_nomatch	-S picked
 | 
						|
test_log	expect_second	-S Picked
 | 
						|
test_log_icase	expect_second	-S picked
 | 
						|
test_log_icase	expect_nomatch	-S pickle
 | 
						|
 | 
						|
test_log	expect_nomatch	-S p.cked --pickaxe-regex
 | 
						|
test_log	expect_second	-S P.cked --pickaxe-regex
 | 
						|
test_log_icase	expect_second	-S p.cked --pickaxe-regex
 | 
						|
test_log_icase	expect_nomatch	-S p.ckle --pickaxe-regex
 | 
						|
 | 
						|
test_expect_success 'log -S --textconv (missing textconv tool)' '
 | 
						|
	echo "* diff=test" >.gitattributes &&
 | 
						|
	test_must_fail git -c diff.test.textconv=missing log -Sfoo &&
 | 
						|
	rm .gitattributes
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success 'log -S --no-textconv (missing textconv tool)' '
 | 
						|
	echo "* diff=test" >.gitattributes &&
 | 
						|
	git -c diff.test.textconv=missing log -Sfoo --no-textconv >actual &&
 | 
						|
	test_cmp expect_nomatch actual &&
 | 
						|
	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
 |