Merge branch 'jk/allow-fetch-onelevel-refname'
[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         git merge -s ours CC1 &&
219         test_commit CC-o &&
220         test_commit CCB &&
221         git reset --hard CC1 &&
222         git merge -s ours CC2 &&
223         test_commit CCA &&
224
225         git rev-parse CC1 CC2 >expected &&
226         git merge-base --all CCB CCA^^ CCA^^2 >actual &&
227
228         sort expected >expected.sorted &&
229         sort actual >actual.sorted &&
230         test_cmp expected.sorted actual.sorted
231 '
232
233 test_expect_success 'using reflog to find the fork point' '
234         git reset --hard &&
235         git checkout -b base $E &&
236
237         (
238                 for count in 1 2 3
239                 do
240                         git commit --allow-empty -m "Base commit #$count" &&
241                         git rev-parse HEAD >expect$count &&
242                         git checkout -B derived &&
243                         git commit --allow-empty -m "Derived #$count" &&
244                         git rev-parse HEAD >derived$count &&
245                         git checkout -B base $E || exit 1
246                 done
247
248                 for count in 1 2 3
249                 do
250                         git merge-base --fork-point base $(cat derived$count) >actual &&
251                         test_cmp expect$count actual || exit 1
252                 done
253
254         ) &&
255         # check that we correctly default to HEAD
256         git checkout derived &&
257         git merge-base --fork-point base >actual &&
258         test_cmp expect3 actual
259 '
260
261 test_expect_success 'merge-base --octopus --all for complex tree' '
262         # Best common ancestor for JE, JAA and JDD is JC
263         #             JE
264         #            / |
265         #           /  |
266         #          /   |
267         #  JAA    /    |
268         #   |\   /     |
269         #   | \  | JDD |
270         #   |  \ |/ |  |
271         #   |   JC JD  |
272         #   |    | /|  |
273         #   |    |/ |  |
274         #  JA    |  |  |
275         #   |\  /|  |  |
276         #   X JB |  X  X
277         #   \  \ | /   /
278         #    \__\|/___/
279         #        J
280         test_commit J &&
281         test_commit JB &&
282         git reset --hard J &&
283         test_commit JC &&
284         git reset --hard J &&
285         test_commit JTEMP1 &&
286         test_merge JA JB &&
287         test_merge JAA JC &&
288         git reset --hard J &&
289         test_commit JTEMP2 &&
290         test_merge JD JB &&
291         test_merge JDD JC &&
292         git reset --hard J &&
293         test_commit JTEMP3 &&
294         test_merge JE JC &&
295         git rev-parse JC >expected &&
296         git merge-base --all --octopus JAA JDD JE >actual &&
297         test_cmp expected actual
298 '
299
300 test_done