Raw
1 #!/bin/sh
2
3 test_description='git log --graph visual root indentations'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-log-graph.sh
7
8 check_graph_with_description () {
9 cat >expect &&
10 lib_test_cmp_graph --format="%s%ndescription%nsecond-line" "$@"
11 }
12
13 create_orphan () {
14 git checkout --orphan "$1" &&
15 test_might_fail git rm -rf .
16 }
17
18 # disable commit-graph topo order to have the graph to render in different
19 # ways (used in --first-parent tests to have multiple visual roots while a
20 # column is active at the same time).
21 unset_commit_graph () {
22 sane_unset GIT_TEST_COMMIT_GRAPH &&
23 rm -f .git/objects/info/commit-graph &&
24 rm -rf .git/objects/info/commit-graphs
25 }
26
27 test_expect_success 'single root commit is not indented' '
28 create_orphan _1 && test_commit 1_A &&
29 lib_test_check_graph _1 <<-\EOF
30 * 1_A
31 EOF
32 '
33
34 test_expect_success 'visual root indented before unrelated branch' '
35 create_orphan _2 && test_commit 2_A && test_commit 2_B &&
36 create_orphan _3 && test_commit 3_A &&
37 lib_test_check_graph _2 _3 <<-\EOF
38 * 3_A
39 * 2_B
40 * 2_A
41 EOF
42 '
43
44 test_expect_success 'visual root indentation with --left-right' '
45 lib_test_check_graph --left-right _2..._3 <<-\EOF
46 > 3_A
47 < 2_B
48 < 2_A
49 EOF
50 '
51
52 # A better case of why indentation is still needed with '--left-right' flag is
53 # that unrelated branches can be on the same side, so it's needed to
54 # differentiate visual roots on the same side.
55 test_expect_success 'visual root indentation with --left-right having unrelated commits on the same side' '
56 lib_test_check_graph --left-right _2..._3 _1 <<-\EOF
57 > 3_A
58 < 2_B
59 \
60 < 2_A
61 > 1_A
62 EOF
63 '
64
65 test_expect_success 'visual root indents the description also' '
66 check_graph_with_description _2 _3 <<-\EOF
67 * 3_A
68 description
69 second-line
70 * 2_B
71 | description
72 | second-line
73 * 2_A
74 description
75 second-line
76 EOF
77 '
78
79 test_expect_success 'indented visual root parent gets connected to its child' '
80 create_orphan _4 && test_commit 4_A && test_commit 4_B &&
81 create_orphan _5 && test_commit 5_A && test_commit 5_B &&
82 lib_test_check_graph _4 _5 <<-\EOF
83 * 5_B
84 \
85 * 5_A
86 * 4_B
87 * 4_A
88 EOF
89 '
90
91 test_expect_success 'indented visual root parent gets connected to its child with description' '
92 check_graph_with_description _4 _5 <<-\EOF
93 * 5_B
94 | description
95 | second-line
96 \
97 * 5_A
98 description
99 second-line
100 * 4_B
101 | description
102 | second-line
103 * 4_A
104 description
105 second-line
106 EOF
107 '
108
109 test_expect_success 'visual roots cascade and last root does not' '
110 create_orphan _7 && test_commit 7_A && test_commit 7_B &&
111 create_orphan _8 && test_commit 8_A &&
112 create_orphan _9 && test_commit 9_A &&
113 create_orphan _10 && test_commit 10_A &&
114 lib_test_check_graph _7 _8 _9 _10 <<-\EOF
115 * 10_A
116 * 9_A
117 * 8_A
118 * 7_B
119 * 7_A
120 EOF
121 '
122
123 test_expect_success 'last root does not cascade' '
124 lib_test_check_graph _8 _9 _10 <<-\EOF
125 * 10_A
126 * 9_A
127 * 8_A
128 EOF
129 '
130
131 test_expect_success 'merge parents are roots between them but they do not indent' '
132 create_orphan _11 && test_commit 11_A &&
133 create_orphan _12 && test_commit 12_A &&
134 create_orphan _13 && test_commit 13_A &&
135 git checkout _11 &&
136 TREE=$(git write-tree) &&
137 MERGE=$(git commit-tree $TREE -p _11 -p _12 -p _13 -m 11_octopus) &&
138 git reset --hard $MERGE &&
139 lib_test_check_graph _11 <<-\EOF
140 *-. 11_octopus
141 |\ \
142 | | * 13_A
143 | * 12_A
144 * 11_A
145 EOF
146 '
147
148 # The last parent of a merge can be indented if nothing related to it needs to
149 # be rendered after, if it's another visual root, merge parent must not get
150 # indented but rather activate cascading.
151 test_expect_success 'merge then unrelated visual root and unrelated branch' '
152 create_orphan _16 && test_commit 16_A && test_commit 16_B &&
153 create_orphan _17 && test_commit 17_A &&
154 create_orphan _18 && test_commit 18_A &&
155 create_orphan _19 && test_commit 19_A &&
156 create_orphan _20 && test_commit 20_A &&
157 git checkout _18 &&
158 TREE=$(git write-tree) &&
159 MERGE=$(git commit-tree $TREE -p _18 -p _19 -p _20 -m 18_octopus) &&
160 git reset --hard $MERGE &&
161 lib_test_check_graph _18 _17 _16 <<-\EOF
162 *-. 18_octopus
163 |\ \
164 | | * 20_A
165 | * 19_A
166 * 18_A
167 * 17_A
168 * 16_B
169 * 16_A
170 EOF
171 '
172
173 # The last commit root does not get indented, if the next thing after the root
174 # merge parent is the last commit, indent the merge parent.
175 test_expect_success 'merge then unrelated root indents merge parent' '
176 lib_test_check_graph _18 _17 <<-\EOF
177 *-. 18_octopus
178 |\ \
179 | | * 20_A
180 | * 19_A
181 \
182 * 18_A
183 * 17_A
184 EOF
185 '
186
187 test_expect_success 'merge then unrelated branch indents merge parent' '
188 lib_test_check_graph _18 _16 <<-\EOF
189 *-. 18_octopus
190 |\ \
191 | | * 20_A
192 | * 19_A
193 \
194 * 18_A
195 * 16_B
196 * 16_A
197 EOF
198 '
199
200 test_expect_success 'two-parent merge of orphans' '
201 create_orphan _21 && test_commit 21_A &&
202 create_orphan _22 && test_commit 22_A &&
203 git checkout _21 &&
204 TREE=$(git write-tree) &&
205 MERGE=$(git commit-tree $TREE -p _21 -p _22 -m 21_merge) &&
206 git reset --hard $MERGE &&
207 lib_test_check_graph _21 <<-\EOF
208 * 21_merge
209 |\
210 | * 22_A
211 * 21_A
212 EOF
213 '
214
215 test_expect_success 'commit with filtered parent becomes a visual root' '
216 create_orphan _23 &&
217 echo test >other.txt &&
218 git add other.txt &&
219 git commit -m "23_A" &&
220 echo test >foo.txt &&
221 git add foo.txt &&
222 git commit -m "23_B" &&
223 create_orphan _24 &&
224 echo test >foo.txt &&
225 git add foo.txt &&
226 git commit -m "24_A" &&
227 lib_test_check_graph _23 _24 -- foo.txt <<-\EOF
228 * 23_B
229 * 24_A
230 EOF
231 '
232
233 test_expect_success 'filtered parent cascading edge case' '
234 create_orphan _27 &&
235 echo test >foo.txt &&
236 git add foo.txt &&
237 test_tick &&
238 git commit -m "D (last)" &&
239
240 create_orphan _25 &&
241 echo test >other.txt &&
242 git add other.txt &&
243 test_tick &&
244 git commit -m "C-filtered" &&
245
246 echo test >foo.txt &&
247 git add foo.txt &&
248 test_tick &&
249 git commit -m "B (child of filtered)" &&
250
251 create_orphan _26 &&
252 echo test >foo.txt &&
253 git add foo.txt &&
254 test_tick &&
255 git commit -m "A (visual root)" &&
256
257 lib_test_check_graph _25 _26 _27 -- foo.txt <<-\EOF
258 * A (visual root)
259 * B (child of filtered)
260 * D (last)
261 EOF
262 '
263
264 test_expect_success 'multiple filtered parents in sequence' '
265 create_orphan _44 &&
266 echo a >other.txt && git add other.txt && git commit -m "44_F" &&
267 echo b >foo.txt && git add foo.txt && git commit -m "44_C" &&
268
269 create_orphan _45 &&
270 echo c >other.txt && git add other.txt && git commit -m "45_F" &&
271 echo d >foo.txt && git add foo.txt && git commit -m "45_C" &&
272
273 create_orphan _46 &&
274 echo e >foo.txt && git add foo.txt && git commit -m "46_A" &&
275
276 lib_test_check_graph _44 _45 _46 -- foo.txt <<-\EOF
277 * 44_C
278 * 45_C
279 * 46_A
280 EOF
281 '
282
283 # These tests prove why there is no need to have indentation for boundary
284 # commits.
285 #
286 # Boundary commits rather than starting a column they 'inherit' the one of
287 # its child so there will always be an edge that connects it removing the
288 # ambiguity.
289 test_expect_success 'unrelated boundaries are not ambiguous' '
290 create_orphan _28 && test_commit 28_A && test_commit 28_B &&
291 test_commit 28_C &&
292 create_orphan _29 && test_commit 29_A && test_commit 29_B &&
293 lib_test_check_graph --boundary 28_A.._28 29_A.._29 <<-\EOF
294 * 29_B
295 | * 28_C
296 | * 28_B
297 | o 28_A
298 o 29_A
299 EOF
300 '
301
302 # Same structure as t6016
303 test_expect_success 'boundary commits big test' '
304 # 3 commits on branch _30
305 create_orphan _30 &&
306 test_commit 30_A &&
307 test_commit 30_B &&
308 test_commit 30_C &&
309
310 # 2 commits on branch _31, started from 30_A
311 git checkout -b _31 30_A &&
312 test_commit 31_A &&
313 test_commit 31_B &&
314
315 # 2 commits on branch _32, started from 30_B
316 git checkout -b _32 30_B &&
317 test_commit 32_A &&
318 test_commit 32_B &&
319
320 # Octopus merge _31 and _32 into -30
321 git checkout _30 &&
322 git merge _31 _32 -m 30_D &&
323 git tag 30_D &&
324 test_commit 30_E &&
325
326 # More commits on _32, then merge _32 into _30
327 git checkout _32 &&
328 test_commit 32_C &&
329 test_commit 32_D &&
330 git checkout _30 &&
331 git merge -s ours _32 -m 30_F &&
332 git tag 30_F &&
333 test_commit 30_G &&
334 lib_test_check_graph --boundary _30 _31 _32 ^32_C <<-\EOF
335 * 30_G
336 * 30_F
337 |\
338 | * 32_D
339 * | 30_E
340 | |
341 | \
342 *-. \ 30_D
343 |\ \ \
344 | * | | 31_B
345 | * | | 31_A
346 * | | | 30_C
347 o | | | 30_B
348 |/ / /
349 o / / 30_A
350 / /
351 | o 32_C
352 |/
353 o 32_B
354 EOF
355 '
356
357 # Filter by --first-parent and then forcing the filtered parents to be shown.
358 test_expect_success '--first-parent flag with the filtered parents' '
359 (
360 unset_commit_graph &&
361 create_orphan _35 && test_commit 35_A && test_commit 35_B &&
362 create_orphan _36 && test_commit 36_A &&
363 create_orphan _37 && test_commit 37_A &&
364 git checkout _35 &&
365 TREE=$(git write-tree) &&
366 MERGE=$(git commit-tree $TREE -p _35 -p _36 -p _37 -m 35_octopus) &&
367 git reset --hard $MERGE &&
368 lib_test_check_graph --first-parent _35 _36 _37 <<-\EOF
369 * 35_octopus
370 | * 37_A
371 | * 36_A
372 * 35_B
373 * 35_A
374 EOF
375 )
376 '
377
378 test_expect_success '--first-parent with filtered parents but one has a child' '
379 (
380 unset_commit_graph &&
381 create_orphan _38 && test_commit 38_A && test_commit 38_B &&
382 create_orphan _39 && test_commit 39_A &&
383 create_orphan _40 && test_commit 40_A && test_commit 40_B &&
384 git checkout _38 &&
385 TREE=$(git write-tree) &&
386 MERGE=$(git commit-tree $TREE -p _38 -p _39 -p _40 -m 38_octopus) &&
387 git reset --hard $MERGE &&
388 lib_test_check_graph --first-parent _38 _39 _40 <<-\EOF
389 * 38_octopus
390 | * 40_B
391 | * 40_A
392 | * 39_A
393 * 38_B
394 * 38_A
395 EOF
396 )
397 '
398
399 test_expect_success '--first-parent with filtered parents but both have children' '
400 (
401 unset_commit_graph &&
402 create_orphan _41 && test_commit 41_A && test_commit 41_B &&
403 create_orphan _42 && test_commit 42_A && test_commit 42_B &&
404 create_orphan _43 && test_commit 43_A && test_commit 43_B &&
405 git checkout _41 &&
406 TREE=$(git write-tree) &&
407 MERGE=$(git commit-tree $TREE -p _41 -p _42 -p _43 -m 41_octopus) &&
408 git reset --hard $MERGE &&
409 lib_test_check_graph --first-parent _41 _42 _43 <<-\EOF
410 * 41_octopus
411 | * 43_B
412 | \
413 | * 43_A
414 | * 42_B
415 | * 42_A
416 * 41_B
417 * 41_A
418 EOF
419 )
420 '
421
422 test_expect_success 'two unrelated merges' '
423 create_orphan _50 && test_commit 50_A &&
424 git checkout -b _51 &&
425 test_commit 51_A && test_commit 51_B &&
426 git checkout _50 &&
427 git merge --no-ff _51 -m 50_B &&
428
429 create_orphan _52 && test_commit 52_A &&
430 git checkout -b _53 &&
431 test_commit 53_A && test_commit 53_B &&
432 git checkout _52 &&
433 git merge --no-ff _53 -m 52_B &&
434
435 lib_test_check_graph _52 _50 <<-\EOF
436 * 52_B
437 |\
438 | * 53_B
439 | * 53_A
440 |/
441 \
442 * 52_A
443 * 50_B
444 |\
445 | * 51_B
446 | * 51_A
447 |/
448 * 50_A
449 EOF
450 '
451
452 test_expect_success '--max-count treats the last visible commit as the last commit' '
453 lib_test_check_graph --max-count=2 _8 _9 _10 <<-\EOF
454 * 10_A
455 * 9_A
456 EOF
457 '
458
459 test_expect_success '--max-count=1 shows a single root without indentation' '
460 lib_test_check_graph --max-count=1 _8 _9 _10 <<-\EOF
461 * 10_A
462 EOF
463 '
464
465 test_expect_success '--max-count-oldest indents visual roots' '
466 lib_test_check_graph --max-count-oldest=3 _8 _9 _10 <<-\EOF
467 * 10_A
468 * 9_A
469 * 8_A
470 EOF
471 '
472
473 # when the graph commits are filtered with regex options like --author, the
474 # commit parents do not come NULL so it is needed to check if the parents are
475 # interesting.
476 test_expect_success '--author skipped parent makes a visual root' '
477 create_orphan _55 &&
478 test_tick &&
479 git commit --allow-empty -m 55_A &&
480 create_orphan _54 &&
481 test_tick &&
482 git commit --allow-empty --author="Other <other@example.com>" -m 54_A &&
483 test_tick &&
484 git commit --allow-empty -m 54_B &&
485 test_tick &&
486 git commit --allow-empty -m 54_C &&
487 lib_test_check_graph --author="A U Thor" _54 _55 <<-\EOF
488 * 54_C
489 \
490 * 54_B
491 * 55_A
492 EOF
493 '
494
495 test_expect_success '--grep skipped parent makes a visual root' '
496 create_orphan _57 &&
497 test_tick &&
498 git commit --allow-empty -m 57_keep_A &&
499 create_orphan _56 &&
500 test_tick &&
501 git commit --allow-empty -m 56_skip &&
502 test_tick &&
503 git commit --allow-empty -m 56_keep_A &&
504 test_tick &&
505 git commit --allow-empty -m 56_keep_B &&
506 lib_test_check_graph --grep=keep _56 _57 <<-\EOF
507 * 56_keep_B
508 \
509 * 56_keep_A
510 * 57_keep_A
511 EOF
512 '
513
514 # The cascading wraps after 4 columns and when wraping (column % 4 == 0) if the
515 # next is a non visual-root, force indentation to avoid an ambiguous graph
516 # (commit 59_A is forcefully indented)
517 test_expect_success 'visual root cascading gets wrapped after 4 columns' '
518 create_orphan _58 && test_commit 58_A && test_commit 58_B &&
519 create_orphan _59 && test_commit 59_A &&
520 create_orphan _60 && test_commit 60_A &&
521 create_orphan _61 && test_commit 61_A &&
522 create_orphan _62 && test_commit 62_A &&
523 create_orphan _63 && test_commit 63_A &&
524 create_orphan _64 && test_commit 64_A &&
525 create_orphan _65 && test_commit 65_A &&
526 create_orphan _66 && test_commit 66_A &&
527 create_orphan _67 && test_commit 67_A &&
528 lib_test_check_graph _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
529 * 67_A
530 * 66_A
531 * 65_A
532 * 64_A
533 * 63_A
534 * 62_A
535 * 61_A
536 * 60_A
537 * 59_A
538 * 58_B
539 * 58_A
540 EOF
541 '
542
543 test_expect_success '--no-graph-indent disables indentation' '
544 lib_test_check_graph --no-graph-indent _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
545 * 67_A
546 * 66_A
547 * 65_A
548 * 64_A
549 * 63_A
550 * 62_A
551 * 61_A
552 * 60_A
553 * 59_A
554 * 58_B
555 * 58_A
556 EOF
557 '
558
559 test_expect_success 'log.graphIndent config disables indentation' '
560 test_config log.graphIndent false &&
561 lib_test_check_graph _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
562 * 67_A
563 * 66_A
564 * 65_A
565 * 64_A
566 * 63_A
567 * 62_A
568 * 61_A
569 * 60_A
570 * 59_A
571 * 58_B
572 * 58_A
573 EOF
574 '
575
576 test_expect_success '--graph-indent forces indentation when graph.indent is unset' '
577 test_config log.graphIndent false &&
578 lib_test_check_graph --graph-indent _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
579 * 67_A
580 * 66_A
581 * 65_A
582 * 64_A
583 * 63_A
584 * 62_A
585 * 61_A
586 * 60_A
587 * 59_A
588 * 58_B
589 * 58_A
590 EOF
591 '
592
593 # log.graphIndent unset and no --option (which activates graph indentation) is
594 # the default state.
595
596 test_done