1#!/bin/sh
2
3test_description='basic commit reachability tests'
4
5. ./test-lib.sh
6
7# Construct a grid-like commit graph with points (x,y)
8# with 1 <= x <= 10, 1 <= y <= 10, where (x,y) has
9# parents (x-1, y) and (x, y-1), keeping in mind that
10# we drop a parent if a coordinate is nonpositive.
11#
12# (10,10)
13# / \
14# (10,9) (9,10)
15# / \ / \
16# (10,8) (9,9) (8,10)
17# / \ / \ / \
18# ( continued...)
19# \ / \ / \ /
20# (3,1) (2,2) (1,3)
21# \ / \ /
22# (2,1) (2,1)
23# \ /
24# (1,1)
25#
26# We use branch 'commit-x-y' to refer to (x,y).
27# This grid allows interesting reachability and
28# non-reachability queries: (x,y) can reach (x',y')
29# if and only if x' <= x and y' <= y.
30test_expect_success 'setup' '
31 for i in $(test_seq 1 10)
32 do
33 test_commit "1-$i" &&
34 git branch -f commit-1-$i &&
35 git tag -a -m "1-$i" tag-1-$i commit-1-$i
36 done &&
37 for j in $(test_seq 1 9)
38 do
39 git reset --hard commit-$j-1 &&
40 x=$(($j + 1)) &&
41 test_commit "$x-1" &&
42 git branch -f commit-$x-1 &&
43 git tag -a -m "$x-1" tag-$x-1 commit-$x-1 &&
44
45 for i in $(test_seq 2 10)
46 do
47 git merge commit-$j-$i -m "$x-$i" &&
48 git branch -f commit-$x-$i &&
49 git tag -a -m "$x-$i" tag-$x-$i commit-$x-$i
50 done
51 done &&
52 git commit-graph write --reachable &&
53 mv .git/objects/info/commit-graph commit-graph-full &&
54 git show-ref -s commit-5-5 | git commit-graph write --stdin-commits &&
55 mv .git/objects/info/commit-graph commit-graph-half &&
56 git config core.commitGraph true
57'
58
59run_three_modes () {
60 test_when_finished rm -rf .git/objects/info/commit-graph &&
61 "$@" <input >actual &&
62 test_cmp expect actual &&
63 cp commit-graph-full .git/objects/info/commit-graph &&
64 "$@" <input >actual &&
65 test_cmp expect actual &&
66 cp commit-graph-half .git/objects/info/commit-graph &&
67 "$@" <input >actual &&
68 test_cmp expect actual
69}
70
71test_three_modes () {
72 run_three_modes test-tool reach "$@"
73}
74
75test_expect_success 'ref_newer:miss' '
76 cat >input <<-\EOF &&
77 A:commit-5-7
78 B:commit-4-9
79 EOF
80 echo "ref_newer(A,B):0" >expect &&
81 test_three_modes ref_newer
82'
83
84test_expect_success 'ref_newer:hit' '
85 cat >input <<-\EOF &&
86 A:commit-5-7
87 B:commit-2-3
88 EOF
89 echo "ref_newer(A,B):1" >expect &&
90 test_three_modes ref_newer
91'
92
93test_expect_success 'in_merge_bases:hit' '
94 cat >input <<-\EOF &&
95 A:commit-5-7
96 B:commit-8-8
97 EOF
98 echo "in_merge_bases(A,B):1" >expect &&
99 test_three_modes in_merge_bases
100'
101
102test_expect_success 'in_merge_bases:miss' '
103 cat >input <<-\EOF &&
104 A:commit-6-8
105 B:commit-5-9
106 EOF
107 echo "in_merge_bases(A,B):0" >expect &&
108 test_three_modes in_merge_bases
109'
110
111test_expect_success 'is_descendant_of:hit' '
112 cat >input <<-\EOF &&
113 A:commit-5-7
114 X:commit-4-8
115 X:commit-6-6
116 X:commit-1-1
117 EOF
118 echo "is_descendant_of(A,X):1" >expect &&
119 test_three_modes is_descendant_of
120'
121
122test_expect_success 'is_descendant_of:miss' '
123 cat >input <<-\EOF &&
124 A:commit-6-8
125 X:commit-5-9
126 X:commit-4-10
127 X:commit-7-6
128 EOF
129 echo "is_descendant_of(A,X):0" >expect &&
130 test_three_modes is_descendant_of
131'
132
133test_expect_success 'get_merge_bases_many' '
134 cat >input <<-\EOF &&
135 A:commit-5-7
136 X:commit-4-8
137 X:commit-6-6
138 X:commit-8-3
139 EOF
140 {
141 echo "get_merge_bases_many(A,X):" &&
142 git rev-parse commit-5-6 \
143 commit-4-7 | sort
144 } >expect &&
145 test_three_modes get_merge_bases_many
146'
147
148test_expect_success 'reduce_heads' '
149 cat >input <<-\EOF &&
150 X:commit-1-10
151 X:commit-2-8
152 X:commit-3-6
153 X:commit-4-4
154 X:commit-1-7
155 X:commit-2-5
156 X:commit-3-3
157 X:commit-5-1
158 EOF
159 {
160 echo "reduce_heads(X):" &&
161 git rev-parse commit-5-1 \
162 commit-4-4 \
163 commit-3-6 \
164 commit-2-8 \
165 commit-1-10 | sort
166 } >expect &&
167 test_three_modes reduce_heads
168'
169
170test_expect_success 'can_all_from_reach:hit' '
171 cat >input <<-\EOF &&
172 X:commit-2-10
173 X:commit-3-9
174 X:commit-4-8
175 X:commit-5-7
176 X:commit-6-6
177 X:commit-7-5
178 X:commit-8-4
179 X:commit-9-3
180 Y:commit-1-9
181 Y:commit-2-8
182 Y:commit-3-7
183 Y:commit-4-6
184 Y:commit-5-5
185 Y:commit-6-4
186 Y:commit-7-3
187 Y:commit-8-1
188 EOF
189 echo "can_all_from_reach(X,Y):1" >expect &&
190 test_three_modes can_all_from_reach
191'
192
193test_expect_success 'can_all_from_reach:miss' '
194 cat >input <<-\EOF &&
195 X:commit-2-10
196 X:commit-3-9
197 X:commit-4-8
198 X:commit-5-7
199 X:commit-6-6
200 X:commit-7-5
201 X:commit-8-4
202 X:commit-9-3
203 Y:commit-1-9
204 Y:commit-2-8
205 Y:commit-3-7
206 Y:commit-4-6
207 Y:commit-5-5
208 Y:commit-6-4
209 Y:commit-8-5
210 EOF
211 echo "can_all_from_reach(X,Y):0" >expect &&
212 test_three_modes can_all_from_reach
213'
214
215test_expect_success 'can_all_from_reach_with_flag: tags case' '
216 cat >input <<-\EOF &&
217 X:tag-2-10
218 X:tag-3-9
219 X:tag-4-8
220 X:commit-5-7
221 X:commit-6-6
222 X:commit-7-5
223 X:commit-8-4
224 X:commit-9-3
225 Y:tag-1-9
226 Y:tag-2-8
227 Y:tag-3-7
228 Y:commit-4-6
229 Y:commit-5-5
230 Y:commit-6-4
231 Y:commit-7-3
232 Y:commit-8-1
233 EOF
234 echo "can_all_from_reach_with_flag(X,_,_,0,0):1" >expect &&
235 test_three_modes can_all_from_reach_with_flag
236'
237
238test_expect_success 'commit_contains:hit' '
239 cat >input <<-\EOF &&
240 A:commit-7-7
241 X:commit-2-10
242 X:commit-3-9
243 X:commit-4-8
244 X:commit-5-7
245 X:commit-6-6
246 X:commit-7-5
247 X:commit-8-4
248 X:commit-9-3
249 EOF
250 echo "commit_contains(_,A,X,_):1" >expect &&
251 test_three_modes commit_contains &&
252 test_three_modes commit_contains --tag
253'
254
255test_expect_success 'commit_contains:miss' '
256 cat >input <<-\EOF &&
257 A:commit-6-5
258 X:commit-2-10
259 X:commit-3-9
260 X:commit-4-8
261 X:commit-5-7
262 X:commit-6-6
263 X:commit-7-5
264 X:commit-8-4
265 X:commit-9-3
266 EOF
267 echo "commit_contains(_,A,X,_):0" >expect &&
268 test_three_modes commit_contains &&
269 test_three_modes commit_contains --tag
270'
271
272test_expect_success 'rev-list: basic topo-order' '
273 git rev-parse \
274 commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
275 commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
276 commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
277 commit-6-3 commit-5-3 commit-4-3 commit-3-3 commit-2-3 commit-1-3 \
278 commit-6-2 commit-5-2 commit-4-2 commit-3-2 commit-2-2 commit-1-2 \
279 commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
280 >expect &&
281 run_three_modes git rev-list --topo-order commit-6-6
282'
283
284test_expect_success 'rev-list: first-parent topo-order' '
285 git rev-parse \
286 commit-6-6 \
287 commit-6-5 \
288 commit-6-4 \
289 commit-6-3 \
290 commit-6-2 \
291 commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
292 >expect &&
293 run_three_modes git rev-list --first-parent --topo-order commit-6-6
294'
295
296test_expect_success 'rev-list: range topo-order' '
297 git rev-parse \
298 commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
299 commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
300 commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
301 commit-6-3 commit-5-3 commit-4-3 \
302 commit-6-2 commit-5-2 commit-4-2 \
303 commit-6-1 commit-5-1 commit-4-1 \
304 >expect &&
305 run_three_modes git rev-list --topo-order commit-3-3..commit-6-6
306'
307
308test_expect_success 'rev-list: range topo-order' '
309 git rev-parse \
310 commit-6-6 commit-5-6 commit-4-6 \
311 commit-6-5 commit-5-5 commit-4-5 \
312 commit-6-4 commit-5-4 commit-4-4 \
313 commit-6-3 commit-5-3 commit-4-3 \
314 commit-6-2 commit-5-2 commit-4-2 \
315 commit-6-1 commit-5-1 commit-4-1 \
316 >expect &&
317 run_three_modes git rev-list --topo-order commit-3-8..commit-6-6
318'
319
320test_expect_success 'rev-list: first-parent range topo-order' '
321 git rev-parse \
322 commit-6-6 \
323 commit-6-5 \
324 commit-6-4 \
325 commit-6-3 \
326 commit-6-2 \
327 commit-6-1 commit-5-1 commit-4-1 \
328 >expect &&
329 run_three_modes git rev-list --first-parent --topo-order commit-3-8..commit-6-6
330'
331
332test_expect_success 'rev-list: ancestry-path topo-order' '
333 git rev-parse \
334 commit-6-6 commit-5-6 commit-4-6 commit-3-6 \
335 commit-6-5 commit-5-5 commit-4-5 commit-3-5 \
336 commit-6-4 commit-5-4 commit-4-4 commit-3-4 \
337 commit-6-3 commit-5-3 commit-4-3 \
338 >expect &&
339 run_three_modes git rev-list --topo-order --ancestry-path commit-3-3..commit-6-6
340'
341
342test_expect_success 'rev-list: symmetric difference topo-order' '
343 git rev-parse \
344 commit-6-6 commit-5-6 commit-4-6 \
345 commit-6-5 commit-5-5 commit-4-5 \
346 commit-6-4 commit-5-4 commit-4-4 \
347 commit-6-3 commit-5-3 commit-4-3 \
348 commit-6-2 commit-5-2 commit-4-2 \
349 commit-6-1 commit-5-1 commit-4-1 \
350 commit-3-8 commit-2-8 commit-1-8 \
351 commit-3-7 commit-2-7 commit-1-7 \
352 >expect &&
353 run_three_modes git rev-list --topo-order commit-3-8...commit-6-6
354'
355
356test_expect_success 'get_reachable_subset:all' '
357 cat >input <<-\EOF &&
358 X:commit-9-1
359 X:commit-8-3
360 X:commit-7-5
361 X:commit-6-6
362 X:commit-1-7
363 Y:commit-3-3
364 Y:commit-1-7
365 Y:commit-5-6
366 EOF
367 (
368 echo "get_reachable_subset(X,Y)" &&
369 git rev-parse commit-3-3 \
370 commit-1-7 \
371 commit-5-6 | sort
372 ) >expect &&
373 test_three_modes get_reachable_subset
374'
375
376test_expect_success 'get_reachable_subset:some' '
377 cat >input <<-\EOF &&
378 X:commit-9-1
379 X:commit-8-3
380 X:commit-7-5
381 X:commit-1-7
382 Y:commit-3-3
383 Y:commit-1-7
384 Y:commit-5-6
385 EOF
386 (
387 echo "get_reachable_subset(X,Y)" &&
388 git rev-parse commit-3-3 \
389 commit-1-7 | sort
390 ) >expect &&
391 test_three_modes get_reachable_subset
392'
393
394test_expect_success 'get_reachable_subset:none' '
395 cat >input <<-\EOF &&
396 X:commit-9-1
397 X:commit-8-3
398 X:commit-7-5
399 X:commit-1-7
400 Y:commit-9-3
401 Y:commit-7-6
402 Y:commit-2-8
403 EOF
404 echo "get_reachable_subset(X,Y)" >expect &&
405 test_three_modes get_reachable_subset
406'
407
408test_done