Merge branch 'sb/doc-config-submodule-update'
[git] / t / t8011-blame-split-file.sh
1 #!/bin/sh
2
3 test_description='
4 The general idea is that we have a single file whose lines come from
5 multiple other files, and those individual files were modified in the same
6 commits. That means that we will see the same commit in multiple contexts,
7 and each one should be attributed to the correct file.
8
9 Note that we need to use "blame -C" to find the commit for all lines. We will
10 not bother testing that the non-C case fails to find it. That is how blame
11 behaves now, but it is not a property we want to make sure is retained.
12 '
13 . ./test-lib.sh
14
15 # help avoid typing and reading long strings of similar lines
16 # in the tests below
17 generate_expect () {
18         while read nr data
19         do
20                 i=0
21                 while test $i -lt $nr
22                 do
23                         echo $data
24                         i=$((i + 1))
25                 done
26         done
27 }
28
29 test_expect_success 'setup split file case' '
30         # use lines long enough to trigger content detection
31         test_seq 1000 1010 >one &&
32         test_seq 2000 2010 >two &&
33         git add one two &&
34         test_commit base &&
35
36         sed "6s/^/modified /" <one >one.tmp &&
37         mv one.tmp one &&
38         sed "6s/^/modified /" <two >two.tmp &&
39         mv two.tmp two &&
40         git add -u &&
41         test_commit modified &&
42
43         cat one two >combined &&
44         git add combined &&
45         git rm one two &&
46         test_commit combined
47 '
48
49 test_expect_success 'setup simulated porcelain' '
50         # This just reads porcelain-ish output and tries
51         # to output the value of a given field for each line (either by
52         # reading the field that accompanies this line, or referencing
53         # the information found last time the commit was mentioned).
54         cat >read-porcelain.pl <<-\EOF
55         my $field = shift;
56         while (<>) {
57                 if (/^[0-9a-f]{40} /) {
58                         flush();
59                         $hash = $&;
60                 } elsif (/^$field (.*)/) {
61                         $cache{$hash} = $1;
62                 }
63         }
64         flush();
65
66         sub flush {
67                 return unless defined $hash;
68                 if (defined $cache{$hash}) {
69                         print "$cache{$hash}\n";
70                 } else {
71                         print "NONE\n";
72                 }
73         }
74         EOF
75 '
76
77 for output in porcelain line-porcelain
78 do
79         test_expect_success "generate --$output output" '
80                 git blame --root -C --$output combined >output
81         '
82
83         test_expect_success "$output output finds correct commits" '
84                 generate_expect >expect <<-\EOF &&
85                 5 base
86                 1 modified
87                 10 base
88                 1 modified
89                 5 base
90                 EOF
91                 perl read-porcelain.pl summary <output >actual &&
92                 test_cmp expect actual
93         '
94
95         test_expect_success "$output output shows correct filenames" '
96                 generate_expect >expect <<-\EOF &&
97                 11 one
98                 11 two
99                 EOF
100                 perl read-porcelain.pl filename <output >actual &&
101                 test_cmp expect actual
102         '
103
104         test_expect_success "$output output shows correct previous pointer" '
105                 generate_expect >expect <<-EOF &&
106                 5 NONE
107                 1 $(git rev-parse modified^) one
108                 10 NONE
109                 1 $(git rev-parse modified^) two
110                 5 NONE
111                 EOF
112                 perl read-porcelain.pl previous <output >actual &&
113                 test_cmp expect actual
114         '
115 done
116
117 test_done