Git 2.46-rc0
[git.git] / t / t8014-blame-ignore-fuzzy.sh
blob933222cea15073411977b47fa343e2e221870c07
1 #!/bin/sh
3 test_description='git blame ignore fuzzy heuristic'
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
8 pick_author='s/^[0-9a-f^]* *(\([^ ]*\) .*/\1/'
10 # Each test is composed of 4 variables:
11 # titleN - the test name
12 # aN - the initial content
13 # bN - the final content
14 # expectedN - the line numbers from aN that we expect git blame
15 # on bN to identify, or "Final" if bN itself should
16 # be identified as the origin of that line.
18 # We start at test 2 because setup will show as test 1
19 title2="Regression test for partially overlapping search ranges"
20 cat <<EOF >a2
24 abcdef
28 ijkl
32 pqrs
36 wxyz
40 EOF
41 cat <<EOF >b2
42 abcde
43 ijk
44 pqr
45 wxy
46 EOF
47 cat <<EOF >expected2
52 EOF
54 title3="Combine 3 lines into 2"
55 cat <<EOF >a3
56 if ((maxgrow==0) ||
57 ( single_line_field && (field->dcols < maxgrow)) ||
58 (!single_line_field && (field->drows < maxgrow)))
59 EOF
60 cat <<EOF >b3
61 if ((maxgrow == 0) || (single_line_field && (field->dcols < maxgrow)) ||
62 (!single_line_field && (field->drows < maxgrow))) {
63 EOF
64 cat <<EOF >expected3
67 EOF
69 title4="Add curly brackets"
70 cat <<EOF >a4
71 if (rows) *rows = field->rows;
72 if (cols) *cols = field->cols;
73 if (frow) *frow = field->frow;
74 if (fcol) *fcol = field->fcol;
75 EOF
76 cat <<EOF >b4
77 if (rows) {
78 *rows = field->rows;
80 if (cols) {
81 *cols = field->cols;
83 if (frow) {
84 *frow = field->frow;
86 if (fcol) {
87 *fcol = field->fcol;
89 EOF
90 cat <<EOF >expected4
93 Final
96 Final
99 Final
102 Final
106 title5="Combine many lines and change case"
107 cat <<EOF >a5
108 for(row=0,pBuffer=field->buf;
109 row<height;
110 row++,pBuffer+=width )
112 if ((len = (int)( After_End_Of_Data( pBuffer, width ) - pBuffer )) > 0)
114 wmove( win, row, 0 );
115 waddnstr( win, pBuffer, len );
117 cat <<EOF >b5
118 for (Row = 0, PBuffer = field->buf; Row < Height; Row++, PBuffer += Width) {
119 if ((Len = (int)(afterEndOfData(PBuffer, Width) - PBuffer)) > 0) {
120 wmove(win, Row, 0);
121 waddnstr(win, PBuffer, Len);
123 cat <<EOF >expected5
130 title6="Rename and combine lines"
131 cat <<EOF >a6
132 bool need_visual_update = ((form != (FORM *)0) &&
133 (form->status & _POSTED) &&
134 (form->current==field));
136 if (need_visual_update)
137 Synchronize_Buffer(form);
139 if (single_line_field)
141 growth = field->cols * amount;
142 if (field->maxgrow)
143 growth = Minimum(field->maxgrow - field->dcols,growth);
144 field->dcols += growth;
145 if (field->dcols == field->maxgrow)
147 cat <<EOF >b6
148 bool NeedVisualUpdate = ((Form != (FORM *)0) && (Form->status & _POSTED) &&
149 (Form->current == field));
151 if (NeedVisualUpdate) {
152 synchronizeBuffer(Form);
155 if (SingleLineField) {
156 Growth = field->cols * amount;
157 if (field->maxgrow) {
158 Growth = Minimum(field->maxgrow - field->dcols, Growth);
160 field->dcols += Growth;
161 if (field->dcols == field->maxgrow) {
163 cat <<EOF >expected6
169 Final
175 Final
180 # Both lines match identically so position must be used to tie-break.
181 title7="Same line twice"
182 cat <<EOF >a7
186 cat <<EOF >b7
187 abcd
188 abcd
190 cat <<EOF >expected7
195 title8="Enforce line order"
196 cat <<EOF >a8
197 abcdef
198 ghijkl
201 cat <<EOF >b8
202 ghijk
203 abcd
205 cat <<EOF >expected8
210 title9="Expand lines and rename variables"
211 cat <<EOF >a9
212 int myFunction(int ArgumentOne, Thing *ArgTwo, Blah XuglyBug) {
213 Squiggle FabulousResult = squargle(ArgumentOne, *ArgTwo,
214 XuglyBug) + EwwwGlobalWithAReallyLongNameYepTooLong;
215 return FabulousResult * 42;
218 cat <<EOF >b9
219 int myFunction(int argument_one, Thing *arg_asdfgh,
220 Blah xugly_bug) {
221 Squiggle fabulous_result = squargle(argument_one,
222 *arg_asdfgh, xugly_bug)
223 + g_ewww_global_with_a_really_long_name_yep_too_long;
224 return fabulous_result * 42;
227 cat <<EOF >expected9
237 title10="Two close matches versus one less close match"
238 cat <<EOF >a10
239 abcdef
240 abcdef
241 ghijkl
243 cat <<EOF >b10
245 abcdefx
247 cat <<EOF >expected10
248 Final
252 # The first line of b matches best with the last line of a, but the overall
253 # match is better if we match it with the first line of a.
254 title11="Piggy in the middle"
255 cat <<EOF >a11
256 abcdefg
257 ijklmn
258 abcdefgh
260 cat <<EOF >b11
261 abcdefghx
262 ijklm
264 cat <<EOF >expected11
269 title12="No trailing newline"
270 printf "abc\ndef" >a12
271 printf "abx\nstu" >b12
272 cat <<EOF >expected12
274 Final
277 title13="Reorder includes"
278 cat <<EOF >a13
279 #include "c.h"
280 #include "b.h"
281 #include "a.h"
282 #include "e.h"
283 #include "d.h"
285 cat <<EOF >b13
286 #include "a.h"
287 #include "b.h"
288 #include "c.h"
289 #include "d.h"
290 #include "e.h"
292 cat <<EOF >expected13
300 last_test=13
302 test_expect_success setup '
303 for i in $(test_seq 2 $last_test)
305 # Append each line in a separate commit to make it easy to
306 # check which original line the blame output relates to.
308 line_count=0 &&
309 while IFS= read line
311 line_count=$((line_count+1)) &&
312 echo "$line" >>"$i" &&
313 git add "$i" &&
314 test_tick &&
315 GIT_AUTHOR_NAME="$line_count" git commit -m "$line_count" || return 1
316 done <"a$i"
317 done &&
319 for i in $(test_seq 2 $last_test)
321 # Overwrite the files with the final content.
322 cp b$i $i &&
323 git add $i || return 1
324 done &&
325 test_tick &&
327 # Commit the final content all at once so it can all be
328 # referred to with the same commit ID.
329 GIT_AUTHOR_NAME=Final git commit -m Final &&
331 IGNOREME=$(git rev-parse HEAD)
334 for i in $(test_seq 2 $last_test); do
335 eval title="\$title$i"
336 test_expect_success "$title" \
337 "git blame -M9 --ignore-rev $IGNOREME $i >output &&
338 sed -e \"$pick_author\" output >actual &&
339 test_cmp expected$i actual"
340 done
342 # This invoked a null pointer dereference when the chunk callback was called
343 # with a zero length parent chunk and there were no more suspects.
344 test_expect_success 'Diff chunks with no suspects' '
345 test_write_lines xy1 A B C xy1 >file &&
346 git add file &&
347 test_tick &&
348 GIT_AUTHOR_NAME=1 git commit -m 1 &&
350 test_write_lines xy2 A B xy2 C xy2 >file &&
351 git add file &&
352 test_tick &&
353 GIT_AUTHOR_NAME=2 git commit -m 2 &&
354 REV_2=$(git rev-parse HEAD) &&
356 test_write_lines xy3 A >file &&
357 git add file &&
358 test_tick &&
359 GIT_AUTHOR_NAME=3 git commit -m 3 &&
360 REV_3=$(git rev-parse HEAD) &&
362 test_write_lines 1 1 >expected &&
364 git blame --ignore-rev $REV_2 --ignore-rev $REV_3 file >output &&
365 sed -e "$pick_author" output >actual &&
367 test_cmp expected actual
370 test_expect_success 'position matching' '
371 test_write_lines abc def >file2 &&
372 git add file2 &&
373 test_tick &&
374 GIT_AUTHOR_NAME=1 git commit -m 1 &&
376 test_write_lines abc def abc def >file2 &&
377 git add file2 &&
378 test_tick &&
379 GIT_AUTHOR_NAME=2 git commit -m 2 &&
381 test_write_lines abcx defx abcx defx >file2 &&
382 git add file2 &&
383 test_tick &&
384 GIT_AUTHOR_NAME=3 git commit -m 3 &&
385 REV_3=$(git rev-parse HEAD) &&
387 test_write_lines abcy defy abcx defx >file2 &&
388 git add file2 &&
389 test_tick &&
390 GIT_AUTHOR_NAME=4 git commit -m 4 &&
391 REV_4=$(git rev-parse HEAD) &&
393 test_write_lines 1 1 2 2 >expected &&
395 git blame --ignore-rev $REV_3 --ignore-rev $REV_4 file2 >output &&
396 sed -e "$pick_author" output >actual &&
398 test_cmp expected actual
401 # This fails if each blame entry is processed independently instead of
402 # processing each diff change in full.
403 test_expect_success 'preserve order' '
404 test_write_lines bcde >file3 &&
405 git add file3 &&
406 test_tick &&
407 GIT_AUTHOR_NAME=1 git commit -m 1 &&
409 test_write_lines bcde fghij >file3 &&
410 git add file3 &&
411 test_tick &&
412 GIT_AUTHOR_NAME=2 git commit -m 2 &&
414 test_write_lines bcde fghij abcd >file3 &&
415 git add file3 &&
416 test_tick &&
417 GIT_AUTHOR_NAME=3 git commit -m 3 &&
419 test_write_lines abcdx fghijx bcdex >file3 &&
420 git add file3 &&
421 test_tick &&
422 GIT_AUTHOR_NAME=4 git commit -m 4 &&
423 REV_4=$(git rev-parse HEAD) &&
425 test_write_lines abcdx fghijy bcdex >file3 &&
426 git add file3 &&
427 test_tick &&
428 GIT_AUTHOR_NAME=5 git commit -m 5 &&
429 REV_5=$(git rev-parse HEAD) &&
431 test_write_lines 1 2 3 >expected &&
433 git blame --ignore-rev $REV_4 --ignore-rev $REV_5 file3 >output &&
434 sed -e "$pick_author" output >actual &&
436 test_cmp expected actual
439 test_done