mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
![Jeff King](/assets/img/avatar_default.png)
Because git's object format requires us to specify the number of bytes in the object in its header, we must know the size before streaming a blob into the object database. This is not a problem when adding a regular file, as we can get the size from stat(). However, when filters are in use (such as autocrlf, or the ident, filter, or eol gitattributes), we have no idea what the ultimate size will be. The current code just punts on the whole issue and ignores filter configuration entirely for files larger than core.bigfilethreshold. This can generate confusing results if you use filters for large binary files, as the filter will suddenly stop working as the file goes over a certain size. Rather than try to handle unknown input sizes with streaming, this patch just turns off the streaming optimization when filters are in use. This has a slight performance regression in a very specific case: if you have autocrlf on, but no gitattributes, a large binary file will avoid the streaming code path because we don't know beforehand whether it will need conversion or not. But if you are handling large binary files, you should be marking them as such via attributes (or at least not using autocrlf, and instead marking your text files as such). And the flip side is that if you have a large _non_-binary file, there is a correctness improvement; before we did not apply the conversion at all. The first half of the new t1051 script covers these failures on input. The second half tests the matching output code paths. These already work correctly, and do not need any adjustment. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
87 lines
1.9 KiB
Bash
Executable file
87 lines
1.9 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='test conversion filters on large files'
|
|
. ./test-lib.sh
|
|
|
|
set_attr() {
|
|
test_when_finished 'rm -f .gitattributes' &&
|
|
echo "* $*" >.gitattributes
|
|
}
|
|
|
|
check_input() {
|
|
git read-tree --empty &&
|
|
git add small large &&
|
|
git cat-file blob :small >small.index &&
|
|
git cat-file blob :large | head -n 1 >large.index &&
|
|
test_cmp small.index large.index
|
|
}
|
|
|
|
check_output() {
|
|
rm -f small large &&
|
|
git checkout small large &&
|
|
head -n 1 large >large.head &&
|
|
test_cmp small large.head
|
|
}
|
|
|
|
test_expect_success 'setup input tests' '
|
|
printf "\$Id: foo\$\\r\\n" >small &&
|
|
cat small small >large &&
|
|
git config core.bigfilethreshold 20 &&
|
|
git config filter.test.clean "sed s/.*/CLEAN/"
|
|
'
|
|
|
|
test_expect_success 'autocrlf=true converts on input' '
|
|
test_config core.autocrlf true &&
|
|
check_input
|
|
'
|
|
|
|
test_expect_success 'eol=crlf converts on input' '
|
|
set_attr eol=crlf &&
|
|
check_input
|
|
'
|
|
|
|
test_expect_success 'ident converts on input' '
|
|
set_attr ident &&
|
|
check_input
|
|
'
|
|
|
|
test_expect_success 'user-defined filters convert on input' '
|
|
set_attr filter=test &&
|
|
check_input
|
|
'
|
|
|
|
test_expect_success 'setup output tests' '
|
|
echo "\$Id\$" >small &&
|
|
cat small small >large &&
|
|
git add small large &&
|
|
git config core.bigfilethreshold 7 &&
|
|
git config filter.test.smudge "sed s/.*/SMUDGE/"
|
|
'
|
|
|
|
test_expect_success 'autocrlf=true converts on output' '
|
|
test_config core.autocrlf true &&
|
|
check_output
|
|
'
|
|
|
|
test_expect_success 'eol=crlf converts on output' '
|
|
set_attr eol=crlf &&
|
|
check_output
|
|
'
|
|
|
|
test_expect_success 'user-defined filters convert on output' '
|
|
set_attr filter=test &&
|
|
check_output
|
|
'
|
|
|
|
test_expect_success 'ident converts on output' '
|
|
set_attr ident &&
|
|
rm -f small large &&
|
|
git checkout small large &&
|
|
sed -n "s/Id: .*/Id: SHA/p" <small >small.clean &&
|
|
head -n 1 large >large.head &&
|
|
sed -n "s/Id: .*/Id: SHA/p" <large.head >large.clean &&
|
|
test_cmp small.clean large.clean
|
|
'
|
|
|
|
test_done
|