Fourth batch for 2.17
[git] / t / t6010-merge-base.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='Merge base and parent list computation.
7 '
8
9 . ./test-lib.sh
10
11 M=1130000000
12 Z=+0000
13
14 GIT_COMMITTER_EMAIL=git@comm.iter.xz
15 GIT_COMMITTER_NAME='C O Mmiter'
16 GIT_AUTHOR_NAME='A U Thor'
17 GIT_AUTHOR_EMAIL=git@au.thor.xz
18 export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
19
20 doit () {
21         OFFSET=$1 &&
22         NAME=$2 &&
23         shift 2 &&
24
25         PARENTS= &&
26         for P
27         do
28                 PARENTS="${PARENTS}-p $P "
29         done &&
30
31         GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" &&
32         GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE &&
33         export GIT_COMMITTER_DATE GIT_AUTHOR_DATE &&
34
35         commit=$(echo $NAME | git commit-tree $T $PARENTS) &&
36
37         echo $commit >.git/refs/tags/$NAME &&
38         echo $commit
39 }
40
41 test_expect_success 'setup' '
42         T=$(git mktree </dev/null)
43 '
44
45 test_expect_success 'set up G and H' '
46         # E---D---C---B---A
47         # \"-_         \   \
48         #  \  `---------G   \
49         #   \                \
50         #    F----------------H
51         E=$(doit 5 E) &&
52         D=$(doit 4 D $E) &&
53         F=$(doit 6 F $E) &&
54         C=$(doit 3 C $D) &&
55         B=$(doit 2 B $C) &&
56         A=$(doit 1 A $B) &&
57         G=$(doit 7 G $B $E) &&
58         H=$(doit 8 H $A $F)
59 '
60
61 test_expect_success 'merge-base G H' '
62         git name-rev $B >expected &&
63
64         MB=$(git merge-base G H) &&
65         git name-rev "$MB" >actual.single &&
66
67         MB=$(git merge-base --all G H) &&
68         git name-rev "$MB" >actual.all &&
69
70         MB=$(git show-branch --merge-base G H) &&
71         git name-rev "$MB" >actual.sb &&
72
73         test_cmp expected actual.single &&
74         test_cmp expected actual.all &&
75         test_cmp expected actual.sb
76 '
77
78 test_expect_success 'merge-base/show-branch --independent' '
79         git name-rev "$H" >expected1 &&
80         git name-rev "$H" "$G" >expected2 &&
81
82         parents=$(git merge-base --independent H) &&
83         git name-rev $parents >actual1.mb &&
84         parents=$(git merge-base --independent A H G) &&
85         git name-rev $parents >actual2.mb &&
86
87         parents=$(git show-branch --independent H) &&
88         git name-rev $parents >actual1.sb &&
89         parents=$(git show-branch --independent A H G) &&
90         git name-rev $parents >actual2.sb &&
91
92         test_cmp expected1 actual1.mb &&
93         test_cmp expected2 actual2.mb &&
94         test_cmp expected1 actual1.sb &&
95         test_cmp expected2 actual2.sb
96 '
97
98 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.
118
119         S=$(doit  0 S) &&
120
121         C0=$(doit -3 C0 $S) &&
122         C1=$(doit -2 C1 $C0) &&
123         C2=$(doit -1 C2 $C1) &&
124
125         L0=$(doit  1 L0 $S) &&
126         L1=$(doit  2 L1 $L0) &&
127         L2=$(doit  3 L2 $L1) &&
128
129         R0=$(doit  1 R0 $S) &&
130         R1=$(doit  2 R1 $R0) &&
131         R2=$(doit  3 R2 $R1) &&
132
133         PL=$(doit  4 PL $L2 $C2) &&
134         PR=$(doit  4 PR $C2 $R2) &&
135
136         git name-rev $C2 >expected &&
137
138         MB=$(git merge-base PL PR) &&
139         git name-rev "$MB" >actual.single &&
140
141         MB=$(git merge-base --all PL PR) &&
142         git name-rev "$MB" >actual.all &&
143
144         test_cmp expected actual.single &&
145         test_cmp expected actual.all
146 '
147
148 test_expect_success '--independent with unsynchronized clocks' '
149         IB=$(doit 0 IB) &&
150         I1=$(doit -10 I1 $IB) &&
151         I2=$(doit  -9 I2 $I1) &&
152         I3=$(doit  -8 I3 $I2) &&
153         I4=$(doit  -7 I4 $I3) &&
154         I5=$(doit  -6 I5 $I4) &&
155         I6=$(doit  -5 I6 $I5) &&
156         I7=$(doit  -4 I7 $I6) &&
157         I8=$(doit  -3 I8 $I7) &&
158         IH=$(doit  -2 IH $I8) &&
159
160         echo $IH >expected &&
161         git merge-base --independent IB IH >actual &&
162         test_cmp expected actual
163 '
164
165 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)
179
180         test_commit MMR &&
181         test_commit MM1 &&
182         test_commit MM-o &&
183         test_commit MM-p &&
184         test_commit MM-q &&
185         test_commit MMA &&
186         git checkout MM1 &&
187         test_commit MM-r &&
188         test_commit MM-s &&
189         test_commit MM-t &&
190         test_commit MMB &&
191         git checkout MMR &&
192         test_commit MM-u &&
193         test_commit MM-v &&
194         test_commit MM-w &&
195         test_commit MM-x &&
196         test_commit MMC
197 '
198
199 test_expect_success 'merge-base A B C' '
200         git rev-parse --verify MM1 >expected &&
201         git rev-parse --verify MMR >expected.sb &&
202
203         git merge-base --all MMA MMB MMC >actual &&
204         git merge-base --all --octopus MMA MMB MMC >actual.common &&
205         git show-branch --merge-base MMA MMB MMC >actual.sb &&
206
207         test_cmp expected actual &&
208         test_cmp expected.sb actual.common &&
209         test_cmp expected.sb actual.sb
210 '
211
212 test_expect_success 'criss-cross merge-base for octopus-step' '
213         git reset --hard MMR &&
214         test_commit CC1 &&
215         git reset --hard E &&
216         test_commit CC2 &&
217         test_tick &&
218         # E is a root commit unrelated to MMR root on which CC1 is based
219         git merge -s ours --allow-unrelated-histories CC1 &&
220         test_commit CC-o &&
221         test_commit CCB &&
222         git reset --hard CC1 &&
223         # E is a root commit unrelated to MMR root on which CC1 is based
224         git merge -s ours --allow-unrelated-histories CC2 &&
225         test_commit CCA &&
226
227         git rev-parse CC1 CC2 >expected &&
228         git merge-base --all CCB CCA^^ CCA^^2 >actual &&
229
230         sort expected >expected.sorted &&
231         sort actual >actual.sorted &&
232         test_cmp expected.sorted actual.sorted
233 '
234
235 test_expect_success 'using reflog to find the fork point' '
236         git reset --hard &&
237         git checkout -b base $E &&
238
239         (
240                 for count in 1 2 3
241                 do
242                         git commit --allow-empty -m "Base commit #$count" &&
243                         git rev-parse HEAD >expect$count &&
244                         git checkout -B derived &&
245                         git commit --allow-empty -m "Derived #$count" &&
246                         git rev-parse HEAD >derived$count &&
247                         git checkout -B base $E || exit 1
248                 done
249
250                 for count in 1 2 3
251                 do
252                         git merge-base --fork-point base $(cat derived$count) >actual &&
253                         test_cmp expect$count actual || exit 1
254                 done
255
256         ) &&
257         # check that we correctly default to HEAD
258         git checkout derived &&
259         git merge-base --fork-point base >actual &&
260         test_cmp expect3 actual
261 '
262
263 test_expect_success '--fork-point works with empty reflog' '
264         git -c core.logallrefupdates=false branch no-reflog base &&
265         git merge-base --fork-point no-reflog derived &&
266         test_cmp expect3 actual
267 '
268
269 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
288         test_commit J &&
289         test_commit JB &&
290         git reset --hard J &&
291         test_commit JC &&
292         git reset --hard J &&
293         test_commit JTEMP1 &&
294         test_merge JA JB &&
295         test_merge JAA JC &&
296         git reset --hard J &&
297         test_commit JTEMP2 &&
298         test_merge JD JB &&
299         test_merge JDD JC &&
300         git reset --hard J &&
301         test_commit JTEMP3 &&
302         test_merge JE JC &&
303         git rev-parse JC >expected &&
304         git merge-base --all --octopus JAA JDD JE >actual &&
305         test_cmp expected actual
306 '
307
308 test_done