describe: teach --match to handle branches and remotes
[git] / t / t1000-read-tree-m-3way.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='Three way merge with read-tree -m
7
8 This test tries three-way merge with read-tree -m
9
10 There is one ancestor (called O for Original) and two branches A
11 and B derived from it.  We want to do a 3-way merge between A and
12 B, using O as the common ancestor.
13
14     merge A O B
15
16 Decisions are made by comparing contents of O, A and B pathname
17 by pathname.  The result is determined by the following guiding
18 principle:
19
20  - If only A does something to it and B does not touch it, take
21    whatever A does.
22
23  - If only B does something to it and A does not touch it, take
24    whatever B does.
25
26  - If both A and B does something but in the same way, take
27    whatever they do.
28
29  - If A and B does something but different things, we need a
30    3-way merge:
31
32    - We cannot do anything about the following cases:
33
34      * O does not have it.  A and B both must be adding to the
35        same path independently.
36
37      * A deletes it.  B must be modifying.
38
39    - Otherwise, A and B are modifying.  Run 3-way merge.
40
41 First, the case matrix.
42
43  - Vertical axis is for A'\''s actions.
44  - Horizontal axis is for B'\''s actions.
45
46 .----------------------------------------------------------------.
47 | A        B | No Action  |   Delete   |   Modify   |    Add     |
48 |------------+------------+------------+------------+------------|
49 | No Action  |            |            |            |            |
50 |            | select O   | delete     | select B   | select B   |
51 |            |            |            |            |            |
52 |------------+------------+------------+------------+------------|
53 | Delete     |            |            | ********** |    can     |
54 |            | delete     | delete     | merge      |    not     |
55 |            |            |            |            |  happen    |
56 |------------+------------+------------+------------+------------|
57 | Modify     |            | ********** | ?????????? |    can     |
58 |            | select A   | merge      | select A=B |    not     |
59 |            |            |            | merge      |  happen    |
60 |------------+------------+------------+------------+------------|
61 | Add        |            |    can     |    can     | ?????????? |
62 |            | select A   |    not     |    not     | select A=B |
63 |            |            |  happen    |  happen    | merge      |
64 .----------------------------------------------------------------.
65
66 In addition:
67
68  SS: a special case of MM, where A and B makes the same modification.
69  LL: a special case of AA, where A and B creates the same file.
70  TT: a special case of MM, where A and B makes mergeable changes.
71  DF: a special case, where A makes a directory and B makes a file.
72
73 '
74 . ./test-lib.sh
75 . "$TEST_DIRECTORY"/lib-read-tree.sh
76 . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh
77
78 ################################################################
79 # Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT
80 # and #5ALT trivial merges.
81
82 cat >expected <<\EOF
83 100644 X 2      AA
84 100644 X 3      AA
85 100644 X 0      AN
86 100644 X 1      DD
87 100644 X 3      DF
88 100644 X 2      DF/DF
89 100644 X 1      DM
90 100644 X 3      DM
91 100644 X 1      DN
92 100644 X 3      DN
93 100644 X 0      LL
94 100644 X 1      MD
95 100644 X 2      MD
96 100644 X 1      MM
97 100644 X 2      MM
98 100644 X 3      MM
99 100644 X 0      MN
100 100644 X 0      NA
101 100644 X 1      ND
102 100644 X 2      ND
103 100644 X 0      NM
104 100644 X 0      NN
105 100644 X 0      SS
106 100644 X 1      TT
107 100644 X 2      TT
108 100644 X 3      TT
109 100644 X 2      Z/AA
110 100644 X 3      Z/AA
111 100644 X 0      Z/AN
112 100644 X 1      Z/DD
113 100644 X 1      Z/DM
114 100644 X 3      Z/DM
115 100644 X 1      Z/DN
116 100644 X 3      Z/DN
117 100644 X 1      Z/MD
118 100644 X 2      Z/MD
119 100644 X 1      Z/MM
120 100644 X 2      Z/MM
121 100644 X 3      Z/MM
122 100644 X 0      Z/MN
123 100644 X 0      Z/NA
124 100644 X 1      Z/ND
125 100644 X 2      Z/ND
126 100644 X 0      Z/NM
127 100644 X 0      Z/NN
128 EOF
129
130 check_result () {
131         git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current &&
132         test_cmp expected current
133 }
134
135 # This is done on an empty work directory, which is the normal
136 # merge person behaviour.
137 test_expect_success '3-way merge with git read-tree -m, empty cache' '
138         rm -fr [NDMALTS][NDMALTSF] Z &&
139         rm .git/index &&
140         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
141         check_result
142 '
143
144 # This starts out with the first head, which is the normal
145 # patch submitter behaviour.
146 test_expect_success '3-way merge with git read-tree -m, match H' '
147         rm -fr [NDMALTS][NDMALTSF] Z &&
148         rm .git/index &&
149         read_tree_must_succeed $tree_A &&
150         git checkout-index -f -u -a &&
151         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
152         check_result
153 '
154
155 : <<\END_OF_CASE_TABLE
156
157 We have so far tested only empty index and clean-and-matching-A index
158 case which are trivial.  Make sure index requirements are also
159 checked.
160
161 "git read-tree -m O A B"
162
163      O       A       B         result      index requirements
164 -------------------------------------------------------------------
165   1  missing missing missing   -           must not exist.
166  ------------------------------------------------------------------
167   2  missing missing exists    take B*     must match B, if exists.
168  ------------------------------------------------------------------
169   3  missing exists  missing   take A*     must match A, if exists.
170  ------------------------------------------------------------------
171   4  missing exists  A!=B      no merge    must match A and be
172                                            up-to-date, if exists.
173  ------------------------------------------------------------------
174   5  missing exists  A==B      take A      must match A, if exists.
175  ------------------------------------------------------------------
176   6  exists  missing missing   remove      must not exist.
177  ------------------------------------------------------------------
178   7  exists  missing O!=B      no merge    must not exist.
179  ------------------------------------------------------------------
180   8  exists  missing O==B      remove      must not exist.
181  ------------------------------------------------------------------
182   9  exists  O!=A    missing   no merge    must match A and be
183                                            up-to-date, if exists.
184  ------------------------------------------------------------------
185  10  exists  O==A    missing   no merge    must match A
186  ------------------------------------------------------------------
187  11  exists  O!=A    O!=B      no merge    must match A and be
188                      A!=B                  up-to-date, if exists.
189  ------------------------------------------------------------------
190  12  exists  O!=A    O!=B      take A      must match A, if exists.
191                      A==B
192  ------------------------------------------------------------------
193  13  exists  O!=A    O==B      take A      must match A, if exists.
194  ------------------------------------------------------------------
195  14  exists  O==A    O!=B      take B      if exists, must either (1)
196                                            match A and be up-to-date,
197                                            or (2) match B.
198  ------------------------------------------------------------------
199  15  exists  O==A    O==B      take B      must match A if exists.
200  ------------------------------------------------------------------
201  16  exists  O==A    O==B      barf        must match A if exists.
202      *multi* in one  in another
203 -------------------------------------------------------------------
204
205 Note: we need to be careful in case 2 and 3.  The tree A may contain
206 DF (file) when tree B require DF to be a directory by having DF/DF
207 (file).
208
209 END_OF_CASE_TABLE
210
211 test_expect_success '1 - must not have an entry not in A.' '
212         rm -f .git/index XX &&
213         echo XX >XX &&
214         git update-index --add XX &&
215         read_tree_must_fail -m $tree_O $tree_A $tree_B
216 '
217
218 test_expect_success '2 - must match B in !O && !A && B case.' '
219         rm -f .git/index NA &&
220         cp .orig-B/NA NA &&
221         git update-index --add NA &&
222         read_tree_must_succeed -m $tree_O $tree_A $tree_B
223 '
224
225 test_expect_success '2 - matching B alone is OK in !O && !A && B case.' '
226         rm -f .git/index NA &&
227         cp .orig-B/NA NA &&
228         git update-index --add NA &&
229         echo extra >>NA &&
230         read_tree_must_succeed -m $tree_O $tree_A $tree_B
231 '
232
233 test_expect_success '3 - must match A in !O && A && !B case.' '
234         rm -f .git/index AN &&
235         cp .orig-A/AN AN &&
236         git update-index --add AN &&
237         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
238         check_result
239 '
240
241 test_expect_success '3 - matching A alone is OK in !O && A && !B case.' '
242         rm -f .git/index AN &&
243         cp .orig-A/AN AN &&
244         git update-index --add AN &&
245         echo extra >>AN &&
246         read_tree_must_succeed -m $tree_O $tree_A $tree_B
247 '
248
249 test_expect_success '3 (fail) - must match A in !O && A && !B case.' '
250         rm -f .git/index AN &&
251         cp .orig-A/AN AN &&
252         echo extra >>AN &&
253         git update-index --add AN &&
254         read_tree_must_fail -m $tree_O $tree_A $tree_B
255 '
256
257 test_expect_success '4 - must match and be up-to-date in !O && A && B && A!=B case.' '
258         rm -f .git/index AA &&
259         cp .orig-A/AA AA &&
260         git update-index --add AA &&
261         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
262         check_result
263 '
264
265 test_expect_success '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' '
266         rm -f .git/index AA &&
267         cp .orig-A/AA AA &&
268         git update-index --add AA &&
269         echo extra >>AA &&
270         read_tree_must_fail -m $tree_O $tree_A $tree_B
271 '
272
273 test_expect_success '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' '
274         rm -f .git/index AA &&
275         cp .orig-A/AA AA &&
276         echo extra >>AA &&
277         git update-index --add AA &&
278         read_tree_must_fail -m $tree_O $tree_A $tree_B
279 '
280
281 test_expect_success '5 - must match in !O && A && B && A==B case.' '
282         rm -f .git/index LL &&
283         cp .orig-A/LL LL &&
284         git update-index --add LL &&
285         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
286         check_result
287 '
288
289 test_expect_success '5 - must match in !O && A && B && A==B case.' '
290         rm -f .git/index LL &&
291         cp .orig-A/LL LL &&
292         git update-index --add LL &&
293         echo extra >>LL &&
294         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
295         check_result
296 '
297
298 test_expect_success '5 (fail) - must match A in !O && A && B && A==B case.' '
299         rm -f .git/index LL &&
300         cp .orig-A/LL LL &&
301         echo extra >>LL &&
302         git update-index --add LL &&
303         read_tree_must_fail -m $tree_O $tree_A $tree_B
304 '
305
306 test_expect_success '6 - must not exist in O && !A && !B case' '
307         rm -f .git/index DD &&
308         echo DD >DD &&
309         git update-index --add DD &&
310         read_tree_must_fail -m $tree_O $tree_A $tree_B
311 '
312
313 test_expect_success '7 - must not exist in O && !A && B && O!=B case' '
314         rm -f .git/index DM &&
315         cp .orig-B/DM DM &&
316         git update-index --add DM &&
317         read_tree_must_fail -m $tree_O $tree_A $tree_B
318 '
319
320 test_expect_success '8 - must not exist in O && !A && B && O==B case' '
321         rm -f .git/index DN &&
322         cp .orig-B/DN DN &&
323         git update-index --add DN &&
324         read_tree_must_fail -m $tree_O $tree_A $tree_B
325 '
326
327 test_expect_success '9 - must match and be up-to-date in O && A && !B && O!=A case' '
328         rm -f .git/index MD &&
329         cp .orig-A/MD MD &&
330         git update-index --add MD &&
331         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
332         check_result
333 '
334
335 test_expect_success '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' '
336         rm -f .git/index MD &&
337         cp .orig-A/MD MD &&
338         git update-index --add MD &&
339         echo extra >>MD &&
340         read_tree_must_fail -m $tree_O $tree_A $tree_B
341 '
342
343 test_expect_success '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' '
344         rm -f .git/index MD &&
345         cp .orig-A/MD MD &&
346         echo extra >>MD &&
347         git update-index --add MD &&
348         read_tree_must_fail -m $tree_O $tree_A $tree_B
349 '
350
351 test_expect_success '10 - must match and be up-to-date in O && A && !B && O==A case' '
352         rm -f .git/index ND &&
353         cp .orig-A/ND ND &&
354         git update-index --add ND &&
355         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
356         check_result
357 '
358
359 test_expect_success '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' '
360         rm -f .git/index ND &&
361         cp .orig-A/ND ND &&
362         git update-index --add ND &&
363         echo extra >>ND &&
364         read_tree_must_fail -m $tree_O $tree_A $tree_B
365 '
366
367 test_expect_success '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' '
368         rm -f .git/index ND &&
369         cp .orig-A/ND ND &&
370         echo extra >>ND &&
371         git update-index --add ND &&
372         read_tree_must_fail -m $tree_O $tree_A $tree_B
373 '
374
375 test_expect_success '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' '
376         rm -f .git/index MM &&
377         cp .orig-A/MM MM &&
378         git update-index --add MM &&
379         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
380         check_result
381 '
382
383 test_expect_success '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' '
384         rm -f .git/index MM &&
385         cp .orig-A/MM MM &&
386         git update-index --add MM &&
387         echo extra >>MM &&
388         read_tree_must_fail -m $tree_O $tree_A $tree_B
389 '
390
391 test_expect_success '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' '
392         rm -f .git/index MM &&
393         cp .orig-A/MM MM &&
394         echo extra >>MM &&
395         git update-index --add MM &&
396         read_tree_must_fail -m $tree_O $tree_A $tree_B
397 '
398
399 test_expect_success '12 - must match A in O && A && B && O!=A && A==B case' '
400         rm -f .git/index SS &&
401         cp .orig-A/SS SS &&
402         git update-index --add SS &&
403         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
404         check_result
405 '
406
407 test_expect_success '12 - must match A in O && A && B && O!=A && A==B case' '
408         rm -f .git/index SS &&
409         cp .orig-A/SS SS &&
410         git update-index --add SS &&
411         echo extra >>SS &&
412         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
413         check_result
414 '
415
416 test_expect_success '12 (fail) - must match A in O && A && B && O!=A && A==B case' '
417         rm -f .git/index SS &&
418         cp .orig-A/SS SS &&
419         echo extra >>SS &&
420         git update-index --add SS &&
421         read_tree_must_fail -m $tree_O $tree_A $tree_B
422 '
423
424 test_expect_success '13 - must match A in O && A && B && O!=A && O==B case' '
425         rm -f .git/index MN &&
426         cp .orig-A/MN MN &&
427         git update-index --add MN &&
428         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
429         check_result
430 '
431
432 test_expect_success '13 - must match A in O && A && B && O!=A && O==B case' '
433         rm -f .git/index MN &&
434         cp .orig-A/MN MN &&
435         git update-index --add MN &&
436         echo extra >>MN &&
437         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
438         check_result
439 '
440
441 test_expect_success '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' '
442         rm -f .git/index NM &&
443         cp .orig-A/NM NM &&
444         git update-index --add NM &&
445         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
446         check_result
447 '
448
449 test_expect_success '14 - may match B in O && A && B && O==A && O!=B case' '
450         rm -f .git/index NM &&
451         cp .orig-B/NM NM &&
452         git update-index --add NM &&
453         echo extra >>NM &&
454         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
455         check_result
456 '
457
458 test_expect_success '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' '
459         rm -f .git/index NM &&
460         cp .orig-A/NM NM &&
461         git update-index --add NM &&
462         echo extra >>NM &&
463         read_tree_must_fail -m $tree_O $tree_A $tree_B
464 '
465
466 test_expect_success '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' '
467         rm -f .git/index NM &&
468         cp .orig-A/NM NM &&
469         echo extra >>NM &&
470         git update-index --add NM &&
471         read_tree_must_fail -m $tree_O $tree_A $tree_B
472 '
473
474 test_expect_success '15 - must match A in O && A && B && O==A && O==B case' '
475         rm -f .git/index NN &&
476         cp .orig-A/NN NN &&
477         git update-index --add NN &&
478         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
479         check_result
480 '
481
482 test_expect_success '15 - must match A in O && A && B && O==A && O==B case' '
483         rm -f .git/index NN &&
484         cp .orig-A/NN NN &&
485         git update-index --add NN &&
486         echo extra >>NN &&
487         read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
488         check_result
489 '
490
491 test_expect_success '15 (fail) - must match A in O && A && B && O==A && O==B case' '
492         rm -f .git/index NN &&
493         cp .orig-A/NN NN &&
494         echo extra >>NN &&
495         git update-index --add NN &&
496         read_tree_must_fail -m $tree_O $tree_A $tree_B
497 '
498
499 test_expect_success '16 - A matches in one and B matches in another.' '
500         rm -f .git/index F16 &&
501         echo F16 >F16 &&
502         git update-index --add F16 &&
503         tree0=$(git write-tree) &&
504         echo E16 >F16 &&
505         git update-index F16 &&
506         tree1=$(git write-tree) &&
507         read_tree_must_succeed -m $tree0 $tree1 $tree1 $tree0 &&
508         git ls-files --stage
509 '
510
511 test_done