118 lines
2.7 KiB
Bash
118 lines
2.7 KiB
Bash
|
#!/bin/sh
|
||
|
|
||
|
test_description='
|
||
|
The general idea is that we have a single file whose lines come from
|
||
|
multiple other files, and those individual files were modified in the same
|
||
|
commits. That means that we will see the same commit in multiple contexts,
|
||
|
and each one should be attributed to the correct file.
|
||
|
|
||
|
Note that we need to use "blame -C" to find the commit for all lines. We will
|
||
|
not bother testing that the non-C case fails to find it. That is how blame
|
||
|
behaves now, but it is not a property we want to make sure is retained.
|
||
|
'
|
||
|
. ./test-lib.sh
|
||
|
|
||
|
# help avoid typing and reading long strings of similar lines
|
||
|
# in the tests below
|
||
|
generate_expect () {
|
||
|
while read nr data
|
||
|
do
|
||
|
i=0
|
||
|
while test $i -lt $nr
|
||
|
do
|
||
|
echo $data
|
||
|
i=$((i + 1))
|
||
|
done
|
||
|
done
|
||
|
}
|
||
|
|
||
|
test_expect_success 'setup split file case' '
|
||
|
# use lines long enough to trigger content detection
|
||
|
test_seq 1000 1010 >one &&
|
||
|
test_seq 2000 2010 >two &&
|
||
|
git add one two &&
|
||
|
test_commit base &&
|
||
|
|
||
|
sed "6s/^/modified /" <one >one.tmp &&
|
||
|
mv one.tmp one &&
|
||
|
sed "6s/^/modified /" <two >two.tmp &&
|
||
|
mv two.tmp two &&
|
||
|
git add -u &&
|
||
|
test_commit modified &&
|
||
|
|
||
|
cat one two >combined &&
|
||
|
git add combined &&
|
||
|
git rm one two &&
|
||
|
test_commit combined
|
||
|
'
|
||
|
|
||
|
test_expect_success 'setup simulated porcelain' '
|
||
|
# This just reads porcelain-ish output and tries
|
||
|
# to output the value of a given field for each line (either by
|
||
|
# reading the field that accompanies this line, or referencing
|
||
|
# the information found last time the commit was mentioned).
|
||
|
cat >read-porcelain.pl <<-\EOF
|
||
|
my $field = shift;
|
||
|
while (<>) {
|
||
|
if (/^[0-9a-f]{40} /) {
|
||
|
flush();
|
||
|
$hash = $&;
|
||
|
} elsif (/^$field (.*)/) {
|
||
|
$cache{$hash} = $1;
|
||
|
}
|
||
|
}
|
||
|
flush();
|
||
|
|
||
|
sub flush {
|
||
|
return unless defined $hash;
|
||
|
if (defined $cache{$hash}) {
|
||
|
print "$cache{$hash}\n";
|
||
|
} else {
|
||
|
print "NONE\n";
|
||
|
}
|
||
|
}
|
||
|
EOF
|
||
|
'
|
||
|
|
||
|
for output in porcelain line-porcelain
|
||
|
do
|
||
|
test_expect_success "generate --$output output" '
|
||
|
git blame --root -C --$output combined >output
|
||
|
'
|
||
|
|
||
|
test_expect_success "$output output finds correct commits" '
|
||
|
generate_expect >expect <<-\EOF &&
|
||
|
5 base
|
||
|
1 modified
|
||
|
10 base
|
||
|
1 modified
|
||
|
5 base
|
||
|
EOF
|
||
|
perl read-porcelain.pl summary <output >actual &&
|
||
|
test_cmp expect actual
|
||
|
'
|
||
|
|
||
|
test_expect_success "$output output shows correct filenames" '
|
||
|
generate_expect >expect <<-\EOF &&
|
||
|
11 one
|
||
|
11 two
|
||
|
EOF
|
||
|
perl read-porcelain.pl filename <output >actual &&
|
||
|
test_cmp expect actual
|
||
|
'
|
||
|
|
||
|
test_expect_success "$output output shows correct previous pointer" '
|
||
|
generate_expect >expect <<-EOF &&
|
||
|
5 NONE
|
||
|
1 $(git rev-parse modified^) one
|
||
|
10 NONE
|
||
|
1 $(git rev-parse modified^) two
|
||
|
5 NONE
|
||
|
EOF
|
||
|
perl read-porcelain.pl previous <output >actual &&
|
||
|
test_cmp expect actual
|
||
|
'
|
||
|
done
|
||
|
|
||
|
test_done
|