1#!/bin/sh
2#
3# Copyright (c) 2005 Junio C Hamano
4#
56
test_description='Merge base and parent list computation.
7'
89
. ./test-lib.sh
1011
M=1130000000
12Z=+0000
1314
GIT_COMMITTER_EMAIL=git@comm.iter.xz
15GIT_COMMITTER_NAME='C O Mmiter'
16GIT_AUTHOR_NAME='A U Thor'
17GIT_AUTHOR_EMAIL=git@au.thor.xz
18export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
1920
doit () {
21OFFSET=$1 &&
22NAME=$2 &&
23shift 2 &&
2425
PARENTS= &&
26for P
27do
28PARENTS="${PARENTS}-p $P "
29done &&
3031
GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" &&
32GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE &&
33export GIT_COMMITTER_DATE GIT_AUTHOR_DATE &&
3435
commit=$(echo $NAME | git commit-tree $T $PARENTS) &&
3637
git update-ref "refs/tags/$NAME" "$commit" &&
38echo $commit
39}
4041
test_expect_success 'setup' '
42T=$(git mktree </dev/null)
43'
4445
test_expect_success 'set up G and H' '
46# E---D---C---B---A
47# \"-_ \ \
48# \ `---------G \
49# \ \
50# F----------------H
51E=$(doit 5 E) &&
52D=$(doit 4 D $E) &&
53F=$(doit 6 F $E) &&
54C=$(doit 3 C $D) &&
55B=$(doit 2 B $C) &&
56A=$(doit 1 A $B) &&
57G=$(doit 7 G $B $E) &&
58H=$(doit 8 H $A $F)
59'
6061
test_expect_success 'merge-base G H' '
62git name-rev $B >expected &&
6364
MB=$(git merge-base G H) &&
65git name-rev "$MB" >actual.single &&
6667
MB=$(git merge-base --all G H) &&
68git name-rev "$MB" >actual.all &&
6970
MB=$(git show-branch --merge-base G H) &&
71git name-rev "$MB" >actual.sb &&
7273
test_cmp expected actual.single &&
74test_cmp expected actual.all &&
75test_cmp expected actual.sb
76'
7778
test_expect_success 'merge-base/show-branch --independent' '
79git name-rev "$H" >expected1 &&
80git name-rev "$H" "$G" >expected2 &&
8182
parents=$(git merge-base --independent H) &&
83git name-rev $parents >actual1.mb &&
84parents=$(git merge-base --independent A H G) &&
85git name-rev $parents >actual2.mb &&
8687
parents=$(git show-branch --independent H) &&
88git name-rev $parents >actual1.sb &&
89parents=$(git show-branch --independent A H G) &&
90git name-rev $parents >actual2.sb &&
9192
test_cmp expected1 actual1.mb &&
93test_cmp expected2 actual2.mb &&
94test_cmp expected1 actual1.sb &&
95test_cmp expected2 actual2.sb
96'
9798
test_expect_success 'unsynchronized clocks' '
99# This test is to demonstrate that relying on timestamps in a distributed
100# SCM to provide a _consistent_ partial ordering of commits leads to
101# insanity.
102#
103# Relative
104# Structure timestamps
105#
106# PL PR +4 +4
107# / \/ \ / \/ \
108# L2 C2 R2 +3 -1 +3
109# | | | | | |
110# L1 C1 R1 +2 -2 +2
111# | | | | | |
112# L0 C0 R0 +1 -3 +1
113# \ | / \ | /
114# S 0
115#
116# The left and right chains of commits can be of any length and complexity as
117# long as all of the timestamps are greater than that of S.
118119
S=$(doit 0 S) &&
120121
C0=$(doit -3 C0 $S) &&
122C1=$(doit -2 C1 $C0) &&
123C2=$(doit -1 C2 $C1) &&
124125
L0=$(doit 1 L0 $S) &&
126L1=$(doit 2 L1 $L0) &&
127L2=$(doit 3 L2 $L1) &&
128129
R0=$(doit 1 R0 $S) &&
130R1=$(doit 2 R1 $R0) &&
131R2=$(doit 3 R2 $R1) &&
132133
PL=$(doit 4 PL $L2 $C2) &&
134PR=$(doit 4 PR $C2 $R2) &&
135136
git name-rev $C2 >expected &&
137138
MB=$(git merge-base PL PR) &&
139git name-rev "$MB" >actual.single &&
140141
MB=$(git merge-base --all PL PR) &&
142git name-rev "$MB" >actual.all &&
143144
test_cmp expected actual.single &&
145test_cmp expected actual.all
146'
147148
test_expect_success '--independent with unsynchronized clocks' '
149IB=$(doit 0 IB) &&
150I1=$(doit -10 I1 $IB) &&
151I2=$(doit -9 I2 $I1) &&
152I3=$(doit -8 I3 $I2) &&
153I4=$(doit -7 I4 $I3) &&
154I5=$(doit -6 I5 $I4) &&
155I6=$(doit -5 I6 $I5) &&
156I7=$(doit -4 I7 $I6) &&
157I8=$(doit -3 I8 $I7) &&
158IH=$(doit -2 IH $I8) &&
159160
echo $IH >expected &&
161git merge-base --independent IB IH >actual &&
162test_cmp expected actual
163'
164165
test_expect_success 'merge-base for octopus-step (setup)' '
166# Another set to demonstrate base between one commit and a merge
167# in the documentation.
168#
169# * C (MMC) * B (MMB) * A (MMA)
170# * o * o * o
171# * o * o * o
172# * o * o * o
173# * o | _______/
174# | |/
175# | * 1 (MM1)
176# | _______/
177# |/
178# * root (MMR)
179180
test_commit MMR &&
181test_commit MM1 &&
182test_commit MM-o &&
183test_commit MM-p &&
184test_commit MM-q &&
185test_commit MMA &&
186git checkout MM1 &&
187test_commit MM-r &&
188test_commit MM-s &&
189test_commit MM-t &&
190test_commit MMB &&
191git checkout MMR &&
192test_commit MM-u &&
193test_commit MM-v &&
194test_commit MM-w &&
195test_commit MM-x &&
196test_commit MMC
197'
198199
test_expect_success 'merge-base A B C' '
200git rev-parse --verify MM1 >expected &&
201git rev-parse --verify MMR >expected.sb &&
202203
git merge-base --all MMA MMB MMC >actual &&
204git merge-base --all --octopus MMA MMB MMC >actual.common &&
205git show-branch --merge-base MMA MMB MMC >actual.sb &&
206207
test_cmp expected actual &&
208test_cmp expected.sb actual.common &&
209test_cmp expected.sb actual.sb
210'
211212
test_expect_success 'criss-cross merge-base for octopus-step' '
213git reset --hard MMR &&
214test_commit CC1 &&
215git reset --hard E &&
216test_commit CC2 &&
217test_tick &&
218# E is a root commit unrelated to MMR root on which CC1 is based
219git merge -s ours --allow-unrelated-histories CC1 &&
220test_commit CC-o &&
221test_commit CCB &&
222git reset --hard CC1 &&
223# E is a root commit unrelated to MMR root on which CC1 is based
224git merge -s ours --allow-unrelated-histories CC2 &&
225test_commit CCA &&
226227
git rev-parse CC1 CC2 >expected &&
228git merge-base --all CCB CCA^^ CCA^^2 >actual &&
229230
sort expected >expected.sorted &&
231sort actual >actual.sorted &&
232test_cmp expected.sorted actual.sorted
233'
234235
test_expect_success 'using reflog to find the fork point' '
236git reset --hard &&
237git checkout -b base $E &&
238239
(
240for count in 1 2 3
241do
242git commit --allow-empty -m "Base commit #$count" &&
243git rev-parse HEAD >expect$count &&
244git checkout -B derived &&
245git commit --allow-empty -m "Derived #$count" &&
246git rev-parse HEAD >derived$count &&
247git checkout -B base $E || exit 1
248done
249250
for count in 1 2 3
251do
252git merge-base --fork-point base $(cat derived$count) >actual &&
253test_cmp expect$count actual || exit 1
254done
255256
) &&
257# check that we correctly default to HEAD
258git checkout derived &&
259git merge-base --fork-point base >actual &&
260test_cmp expect3 actual
261'
262263
test_expect_success '--fork-point works with empty reflog' '
264git -c core.logallrefupdates=false branch no-reflog base &&
265git merge-base --fork-point no-reflog derived &&
266test_cmp expect3 actual
267'
268269
test_expect_success 'merge-base --octopus --all for complex tree' '
270# Best common ancestor for JE, JAA and JDD is JC
271# JE
272# / |
273# / |
274# / |
275# JAA / |
276# |\ / |
277# | \ | JDD |
278# | \ |/ | |
279# | JC JD |
280# | | /| |
281# | |/ | |
282# JA | | |
283# |\ /| | |
284# X JB | X X
285# \ \ | / /
286# \__\|/___/
287# J
288test_commit J &&
289test_commit JB &&
290git reset --hard J &&
291test_commit JC &&
292git reset --hard J &&
293test_commit JTEMP1 &&
294test_merge JA JB &&
295test_merge JAA JC &&
296git reset --hard J &&
297test_commit JTEMP2 &&
298test_merge JD JB &&
299test_merge JDD JC &&
300git reset --hard J &&
301test_commit JTEMP3 &&
302test_merge JE JC &&
303git rev-parse JC >expected &&
304git merge-base --all --octopus JAA JDD JE >actual &&
305test_cmp expected actual
306'
307308
test_done