1#!/bin/sh
2#
3# Copyright (c) 2005 Jon Seymour
4#
5
6test_description='Tests git-rev-list --merge-order functionality'
7
8. ./test-lib.sh
9. ../t6000lib.sh # t6xxx specific functions
10
11# test-case specific test function
12check_adjacency()
13{
14 read previous
15 echo "= $previous"
16 while read next
17 do
18 if ! (git-cat-file commit $previous | grep "^parent $next" >/dev/null)
19 then
20 echo "^ $next"
21 else
22 echo "| $next"
23 fi
24 previous=$next
25 done
26}
27
28list_duplicates()
29{
30 "$@" | sort | uniq -d
31}
32
33grep_stderr()
34{
35 args=$1
36 shift 1
37 "$@" 2>&1 | grep "$args"
38}
39
40date >path0
41git-update-cache --add path0
42save_tag tree git-write-tree
43on_committer_date "1971-08-16 00:00:00" hide_error save_tag root unique_commit root tree
44on_committer_date "1971-08-16 00:00:01" save_tag l0 unique_commit l0 tree -p root
45on_committer_date "1971-08-16 00:00:02" save_tag l1 unique_commit l1 tree -p l0
46on_committer_date "1971-08-16 00:00:03" save_tag l2 unique_commit l2 tree -p l1
47on_committer_date "1971-08-16 00:00:04" save_tag a0 unique_commit a0 tree -p l2
48on_committer_date "1971-08-16 00:00:05" save_tag a1 unique_commit a1 tree -p a0
49on_committer_date "1971-08-16 00:00:06" save_tag b1 unique_commit b1 tree -p a0
50on_committer_date "1971-08-16 00:00:07" save_tag c1 unique_commit c1 tree -p b1
51on_committer_date "1971-08-16 00:00:08" as_author foobar@example.com save_tag b2 unique_commit b2 tree -p b1
52on_committer_date "1971-08-16 00:00:09" save_tag b3 unique_commit b2 tree -p b2
53on_committer_date "1971-08-16 00:00:10" save_tag c2 unique_commit c2 tree -p c1 -p b2
54on_committer_date "1971-08-16 00:00:11" save_tag c3 unique_commit c3 tree -p c2
55on_committer_date "1971-08-16 00:00:12" save_tag a2 unique_commit a2 tree -p a1
56on_committer_date "1971-08-16 00:00:13" save_tag a3 unique_commit a3 tree -p a2
57on_committer_date "1971-08-16 00:00:14" save_tag b4 unique_commit b4 tree -p b3 -p a3
58on_committer_date "1971-08-16 00:00:15" save_tag a4 unique_commit a4 tree -p a3 -p b4 -p c3
59on_committer_date "1971-08-16 00:00:16" save_tag l3 unique_commit l3 tree -p a4
60on_committer_date "1971-08-16 00:00:17" save_tag l4 unique_commit l4 tree -p l3
61on_committer_date "1971-08-16 00:00:18" save_tag l5 unique_commit l5 tree -p l4
62on_committer_date "1971-08-16 00:00:19" save_tag m1 unique_commit m1 tree -p a4 -p c3
63on_committer_date "1971-08-16 00:00:20" save_tag m2 unique_commit m2 tree -p c3 -p a4
64on_committer_date "1971-08-16 00:00:21" hide_error save_tag alt_root unique_commit alt_root tree
65on_committer_date "1971-08-16 00:00:22" save_tag r0 unique_commit r0 tree -p alt_root
66on_committer_date "1971-08-16 00:00:23" save_tag r1 unique_commit r1 tree -p r0
67on_committer_date "1971-08-16 00:00:24" save_tag l5r1 unique_commit l5r1 tree -p l5 -p r1
68on_committer_date "1971-08-16 00:00:25" save_tag r1l5 unique_commit r1l5 tree -p r1 -p l5
69
70
71#
72# note: as of 20/6, it isn't possible to create duplicate parents, so this
73# can't be tested.
74#
75#on_committer_date "1971-08-16 00:00:20" save_tag m3 unique_commit m3 tree -p c3 -p a4 -p c3
76hide_error save_tag e1 as_author e@example.com unique_commit e1 tree
77save_tag e2 as_author e@example.com unique_commit e2 tree -p e1
78save_tag f1 as_author f@example.com unique_commit f1 tree -p e1
79save_tag e3 as_author e@example.com unique_commit e3 tree -p e2
80save_tag f2 as_author f@example.com unique_commit f2 tree -p f1
81save_tag e4 as_author e@example.com unique_commit e4 tree -p e3 -p f2
82save_tag e5 as_author e@example.com unique_commit e5 tree -p e4
83save_tag f3 as_author f@example.com unique_commit f3 tree -p f2
84save_tag f4 as_author f@example.com unique_commit f4 tree -p f3
85save_tag e6 as_author e@example.com unique_commit e6 tree -p e5 -p f4
86save_tag f5 as_author f@example.com unique_commit f5 tree -p f4
87save_tag f6 as_author f@example.com unique_commit f6 tree -p f5 -p e6
88save_tag e7 as_author e@example.com unique_commit e7 tree -p e6
89save_tag e8 as_author e@example.com unique_commit e8 tree -p e7
90save_tag e9 as_author e@example.com unique_commit e9 tree -p e8
91save_tag f7 as_author f@example.com unique_commit f7 tree -p f6
92save_tag f8 as_author f@example.com unique_commit f8 tree -p f7
93save_tag f9 as_author f@example.com unique_commit f9 tree -p f8
94save_tag e10 as_author e@example.com unique_commit e1 tree -p e9 -p f8
95
96hide_error save_tag g0 unique_commit g0 tree
97save_tag g1 unique_commit g1 tree -p g0
98save_tag h1 unique_commit g2 tree -p g0
99save_tag g2 unique_commit g3 tree -p g1 -p h1
100save_tag h2 unique_commit g4 tree -p g2
101save_tag g3 unique_commit g5 tree -p g2
102save_tag g4 unique_commit g6 tree -p g3 -p h2
103
104tag l5 > .git/HEAD
105
106test_expect_success 'rev-list has correct number of entries' 'git-rev-list HEAD | wc -l | tr -s " "' <<EOF
10719
108EOF
109
110normal_adjacency_count=$(git-rev-list HEAD | check_adjacency | grep -c "\^" | tr -d ' ')
111merge_order_adjacency_count=$(git-rev-list --merge-order HEAD | check_adjacency | grep -c "\^" | tr -d ' ')
112test_expect_success '--merge-order produces as many or fewer discontinuities' '[ $merge_order_adjacency_count -le $normal_adjacency_count ]'
113test_output_expect_success 'simple merge order' 'git-rev-list --merge-order --show-breaks HEAD' <<EOF
114= l5
115| l4
116| l3
117= a4
118| c3
119| c2
120| c1
121^ b4
122| b3
123| b2
124| b1
125^ a3
126| a2
127| a1
128= a0
129| l2
130| l1
131| l0
132= root
133EOF
134
135test_output_expect_success 'two diamonds merge order (g6)' 'git-rev-list --merge-order --show-breaks g4' <<EOF
136= g4
137| h2
138^ g3
139= g2
140| h1
141^ g1
142= g0
143EOF
144
145test_output_expect_success 'multiple heads' 'git-rev-list --merge-order a3 b3 c3' <<EOF
146c3
147c2
148c1
149b3
150b2
151b1
152a3
153a2
154a1
155a0
156l2
157l1
158l0
159root
160EOF
161
162test_output_expect_success 'multiple heads, prune at a1' 'git-rev-list --merge-order a3 b3 c3 ^a1' <<EOF
163c3
164c2
165c1
166b3
167b2
168b1
169a3
170a2
171EOF
172
173test_output_expect_success 'multiple heads, prune at l1' 'git-rev-list --merge-order a3 b3 c3 ^l1' <<EOF
174c3
175c2
176c1
177b3
178b2
179b1
180a3
181a2
182a1
183a0
184l2
185EOF
186
187test_output_expect_success 'cross-epoch, head at l5, prune at l1' 'git-rev-list --merge-order l5 ^l1' <<EOF
188l5
189l4
190l3
191a4
192c3
193c2
194c1
195b4
196b3
197b2
198b1
199a3
200a2
201a1
202a0
203l2
204EOF
205
206test_output_expect_success 'duplicated head arguments' 'git-rev-list --merge-order l5 l5 ^l1' <<EOF
207l5
208l4
209l3
210a4
211c3
212c2
213c1
214b4
215b3
216b2
217b1
218a3
219a2
220a1
221a0
222l2
223EOF
224
225test_output_expect_success 'prune near merge' 'git-rev-list --merge-order a4 ^c3' <<EOF
226a4
227b4
228b3
229a3
230a2
231a1
232EOF
233
234test_output_expect_success "head has no parent" 'git-rev-list --merge-order --show-breaks root' <<EOF
235= root
236EOF
237
238test_output_expect_success "two nodes - one head, one base" 'git-rev-list --merge-order --show-breaks l0' <<EOF
239= l0
240= root
241EOF
242
243test_output_expect_success "three nodes one head, one internal, one base" 'git-rev-list --merge-order --show-breaks l1' <<EOF
244= l1
245| l0
246= root
247EOF
248
249test_output_expect_success "linear prune l2 ^root" 'git-rev-list --merge-order --show-breaks l2 ^root' <<EOF
250^ l2
251| l1
252| l0
253EOF
254
255test_output_expect_success "linear prune l2 ^l0" 'git-rev-list --merge-order --show-breaks l2 ^l0' <<EOF
256^ l2
257| l1
258EOF
259
260test_output_expect_success "linear prune l2 ^l1" 'git-rev-list --merge-order --show-breaks l2 ^l1' <<EOF
261^ l2
262EOF
263
264test_output_expect_success "linear prune l5 ^a4" 'git-rev-list --merge-order --show-breaks l5 ^a4' <<EOF
265^ l5
266| l4
267| l3
268EOF
269
270test_output_expect_success "linear prune l5 ^l3" 'git-rev-list --merge-order --show-breaks l5 ^l3' <<EOF
271^ l5
272| l4
273EOF
274
275test_output_expect_success "linear prune l5 ^l4" 'git-rev-list --merge-order --show-breaks l5 ^l4' <<EOF
276^ l5
277EOF
278
279test_output_expect_success "max-count 10 - merge order" 'git-rev-list --merge-order --show-breaks --max-count=10 l5' <<EOF
280= l5
281| l4
282| l3
283= a4
284| c3
285| c2
286| c1
287^ b4
288| b3
289| b2
290EOF
291
292test_output_expect_success "max-count 10 - non merge order" 'git-rev-list --max-count=10 l5' <<EOF
293l5
294l4
295l3
296a4
297b4
298a3
299a2
300c3
301c2
302b3
303EOF
304
305test_output_expect_success '--max-age=c3, no --merge-order' "git-rev-list --max-age=$(commit_date c3) l5" <<EOF
306l5
307l4
308l3
309a4
310b4
311a3
312a2
313c3
314EOF
315
316test_output_expect_success '--max-age=c3, --merge-order' "git-rev-list --merge-order --max-age=$(commit_date c3) l5" <<EOF
317l5
318l4
319l3
320a4
321c3
322b4
323a3
324a2
325EOF
326
327test_output_expect_success 'one specified head reachable from another a4, c3, --merge-order' "list_duplicates git-rev-list --merge-order a4 c3" <<EOF
328EOF
329
330test_output_expect_success 'one specified head reachable from another c3, a4, --merge-order' "list_duplicates git-rev-list --merge-order c3 a4" <<EOF
331EOF
332
333test_output_expect_success 'one specified head reachable from another a4, c3, no --merge-order' "list_duplicates git-rev-list a4 c3" <<EOF
334EOF
335
336test_output_expect_success 'one specified head reachable from another c3, a4, no --merge-order' "list_duplicates git-rev-list c3 a4" <<EOF
337EOF
338
339test_output_expect_success 'graph with c3 and a4 parents of head' "list_duplicates git-rev-list m1" <<EOF
340EOF
341
342test_output_expect_success 'graph with a4 and c3 parents of head' "list_duplicates git-rev-list m2" <<EOF
343EOF
344
345test_expect_success "head ^head --merge-order" 'git-rev-list --merge-order --show-breaks a3 ^a3' <<EOF
346EOF
347
348#
349# can't test this now - duplicate parents can't be created
350#
351#test_output_expect_success 'duplicate parents' 'git-rev-list --parents --merge-order --show-breaks m3' <<EOF
352#= m3 c3 a4 c3
353#| a4 c3 b4 a3
354#| b4 a3 b3
355#| b3 b2
356#^ a3 a2
357#| a2 a1
358#| a1 a0
359#^ c3 c2
360#| c2 b2 c1
361#| b2 b1
362#^ c1 b1
363#| b1 a0
364#= a0 l2
365#| l2 l1
366#| l1 l0
367#| l0 root
368#= root
369#EOF
370
371test_expect_success "head ^head no --merge-order" 'git-rev-list a3 ^a3' <<EOF
372EOF
373
374test_output_expect_success 'simple merge order (l5r1)' 'git-rev-list --merge-order --show-breaks l5r1' <<EOF
375= l5r1
376| r1
377| r0
378| alt_root
379^ l5
380| l4
381| l3
382| a4
383| c3
384| c2
385| c1
386^ b4
387| b3
388| b2
389| b1
390^ a3
391| a2
392| a1
393| a0
394| l2
395| l1
396| l0
397= root
398EOF
399
400test_output_expect_success 'simple merge order (r1l5)' 'git-rev-list --merge-order --show-breaks r1l5' <<EOF
401= r1l5
402| l5
403| l4
404| l3
405| a4
406| c3
407| c2
408| c1
409^ b4
410| b3
411| b2
412| b1
413^ a3
414| a2
415| a1
416| a0
417| l2
418| l1
419| l0
420| root
421^ r1
422| r0
423= alt_root
424EOF
425
426test_output_expect_success "don't print things unreachable from one branch" "git-rev-list a3 ^b3 --merge-order" <<EOF
427a3
428a2
429a1
430EOF
431
432test_output_expect_success "--merge-order a4 l3" "git-rev-list --merge-order a4 l3" <<EOF
433l3
434a4
435c3
436c2
437c1
438b4
439b3
440b2
441b1
442a3
443a2
444a1
445a0
446l2
447l1
448l0
449root
450EOF
451
452#
453#
454
455test_done