3 test_description
='git blame corner cases'
6 pick_fc
='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/'
8 test_expect_success setup
'
10 echo B B B B B >two &&
11 echo C C C C C >tres &&
13 for i in 1 2 3 4 5 6 7 8 9
17 for i in 1 2 3 4 5 6 7 8 9 a
21 git add one two tres mouse nine_lines ten_lines &&
23 GIT_AUTHOR_NAME=Initial git commit -m Initial &&
29 git add uno dos tres mouse &&
31 GIT_AUTHOR_NAME=Second git commit -a -m Second &&
36 GIT_AUTHOR_NAME=Third git commit -m Third &&
41 GIT_AUTHOR_NAME=Fourth git commit -m Fourth &&
51 GIT_AUTHOR_NAME=Fifth git commit -m Fifth
54 test_expect_success
'straight copy without -C' '
56 git blame uno | grep Second
60 test_expect_success
'straight move without -C' '
62 git blame dos | grep Initial
66 test_expect_success
'straight copy with -C' '
68 git blame -C1 uno | grep Second
72 test_expect_success
'straight move with -C' '
74 git blame -C1 dos | grep Initial
78 test_expect_success
'straight copy with -C -C' '
80 git blame -C -C1 uno | grep Initial
84 test_expect_success
'straight move with -C -C' '
86 git blame -C -C1 dos | grep Initial
90 test_expect_success
'append without -C' '
92 git blame -L2 tres | grep Second
96 test_expect_success
'append with -C' '
98 git blame -L2 -C1 tres | grep Second
102 test_expect_success
'append with -C -C' '
104 git blame -L2 -C -C1 tres | grep Second
108 test_expect_success
'append with -C -C -C' '
110 git blame -L2 -C -C -C1 tres | grep Initial
114 test_expect_success
'blame wholesale copy' '
116 git blame -f -C -C1 HEAD^ -- cow | sed -e "$pick_fc" >current &&
117 cat >expected <<-\EOF &&
122 test_cmp expected current
126 test_expect_success
'blame wholesale copy and more' '
128 git blame -f -C -C1 HEAD -- cow | sed -e "$pick_fc" >current &&
129 cat >expected <<-\EOF &&
135 test_cmp expected current
139 test_expect_success
'blame wholesale copy and more in the index' '
141 cat >horse <<-\EOF &&
149 test_when_finished "git rm -f horse" &&
150 git blame -f -C -C1 -- horse | sed -e "$pick_fc" >current &&
151 cat >expected <<-\EOF &&
158 test_cmp expected current
162 test_expect_success
'blame during cherry-pick with file rename conflict' '
164 test_when_finished "git reset --hard && git checkout master" &&
165 git checkout HEAD~3 &&
166 echo MOUSE >> mouse &&
167 git mv mouse rodent &&
169 GIT_AUTHOR_NAME=Rodent git commit -m "rodent" &&
170 git checkout --detach master &&
171 (git cherry-pick HEAD@{1} || test $? -eq 1) &&
172 git show HEAD@{1}:rodent > rodent &&
174 git blame -f -C -C1 rodent | sed -e "$pick_fc" >current &&
175 cat >expected <<-\EOF &&
180 test_cmp expected current
183 test_expect_success
'blame path that used to be a directory' '
185 echo A A A A A >path/file &&
186 echo B B B B B >path/elif &&
189 git commit -m "path was a directory" &&
191 echo A A A A A >path &&
194 git commit -m "path is a regular file" &&
195 git blame HEAD^.. -- path
198 test_expect_success
'blame to a commit with no author name' '
199 TREE=$(git rev-parse HEAD:) &&
200 cat >badcommit <<EOF &&
202 author <noname> 1234567890 +0000
203 committer David Reiss <dreiss@facebook.com> 1234567890 +0000
207 COMMIT=$(git hash-object -t commit -w badcommit) &&
208 git --no-pager blame $COMMIT -- uno >/dev/null
211 test_expect_success
'blame -L with invalid start' '
212 test_must_fail git blame -L5 tres 2>errors &&
213 test_i18ngrep "has only 2 lines" errors
216 test_expect_success
'blame -L with invalid end' '
217 git blame -L1,5 tres >out &&
218 test_line_count = 2 out
221 test_expect_success
'blame parses <end> part of -L' '
222 git blame -L1,1 tres >out &&
223 test_line_count = 1 out
226 test_expect_success
'blame -Ln,-(n+1)' '
227 git blame -L3,-4 nine_lines >out &&
228 test_line_count = 3 out
231 test_expect_success
'indent of line numbers, nine lines' '
232 git blame nine_lines >actual &&
233 test $(grep -c " " actual) = 0
236 test_expect_success
'indent of line numbers, ten lines' '
237 git blame ten_lines >actual &&
238 test $(grep -c " " actual) = 9
241 test_expect_success
'setup file with CRLF newlines' '
242 git config core.autocrlf false &&
243 printf "testcase\n" >crlffile &&
245 git commit -m testcase &&
246 printf "testcase\r\n" >crlffile
249 test_expect_success
'blame file with CRLF core.autocrlf true' '
250 git config core.autocrlf true &&
251 git blame crlffile >actual &&
252 grep "A U Thor" actual
255 test_expect_success
'blame file with CRLF attributes text' '
256 git config core.autocrlf false &&
257 echo "crlffile text" >.gitattributes &&
258 git blame crlffile >actual &&
259 grep "A U Thor" actual
262 test_expect_success
'blame file with CRLF core.autocrlf=true' '
263 git config core.autocrlf false &&
264 printf "testcase\r\n" >crlfinrepo &&
266 git add crlfinrepo &&
267 git commit -m "add crlfinrepo" &&
268 git config core.autocrlf true &&
270 git checkout crlfinrepo &&
272 git blame crlfinrepo >actual &&
273 grep "A U Thor" actual
276 test_expect_success
'setup coalesce tests' '
277 cat >giraffe <<-\EOF &&
282 git commit -m "original file" &&
283 orig=$(git rev-parse HEAD) &&
285 cat >giraffe <<-\EOF &&
291 git commit -m "interior SPLIT line" &&
292 split=$(git rev-parse HEAD) &&
294 cat >giraffe <<-\EOF &&
299 git commit -m "same contents as original" &&
300 final=$(git rev-parse HEAD)
303 test_expect_success
'blame coalesce' '
304 cat >expect <<-EOF &&
308 git blame --porcelain $final giraffe >actual.raw &&
309 grep "^$orig" actual.raw >actual &&
310 test_cmp expect actual
313 test_expect_success
'blame does not coalesce non-adjacent result lines' '
314 cat >expect <<-EOF &&
318 git blame --no-abbrev -s -L1,1 -L3,3 $split giraffe >actual &&
319 test_cmp expect actual