log -L: store the path instead of a diff_filespec
[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 \
138     '3-way merge with git read-tree -m, empty cache' \
139     "rm -fr [NDMALTS][NDMALTSF] Z &&
140      rm .git/index &&
141      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
142      check_result"
143
144 # This starts out with the first head, which is the normal
145 # patch submitter behaviour.
146 test_expect_success \
147     '3-way merge with git read-tree -m, match H' \
148     "rm -fr [NDMALTS][NDMALTSF] Z &&
149      rm .git/index &&
150      read_tree_must_succeed $tree_A &&
151      git checkout-index -f -u -a &&
152      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
153      check_result"
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 \
219     '2 - must match B in !O && !A && B case.' \
220     "rm -f .git/index NA &&
221      cp .orig-B/NA NA &&
222      git update-index --add NA &&
223      read_tree_must_succeed -m $tree_O $tree_A $tree_B"
224
225 test_expect_success \
226     '2 - matching B alone is OK in !O && !A && B case.' \
227     "rm -f .git/index NA &&
228      cp .orig-B/NA NA &&
229      git update-index --add NA &&
230      echo extra >>NA &&
231      read_tree_must_succeed -m $tree_O $tree_A $tree_B"
232
233 test_expect_success \
234     '3 - must match A in !O && A && !B case.' \
235     "rm -f .git/index AN &&
236      cp .orig-A/AN AN &&
237      git update-index --add AN &&
238      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
239      check_result"
240
241 test_expect_success \
242     '3 - matching A alone is OK in !O && A && !B case.' \
243     "rm -f .git/index AN &&
244      cp .orig-A/AN AN &&
245      git update-index --add AN &&
246      echo extra >>AN &&
247      read_tree_must_succeed -m $tree_O $tree_A $tree_B"
248
249 test_expect_success \
250     '3 (fail) - must match A in !O && A && !B case.' "
251      rm -f .git/index AN &&
252      cp .orig-A/AN AN &&
253      echo extra >>AN &&
254      git update-index --add AN &&
255      read_tree_must_fail -m $tree_O $tree_A $tree_B
256 "
257
258 test_expect_success \
259     '4 - must match and be up-to-date in !O && A && B && A!=B case.' \
260     "rm -f .git/index AA &&
261      cp .orig-A/AA AA &&
262      git update-index --add AA &&
263      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
264      check_result"
265
266 test_expect_success \
267     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' "
268      rm -f .git/index AA &&
269      cp .orig-A/AA AA &&
270      git update-index --add AA &&
271      echo extra >>AA &&
272      read_tree_must_fail -m $tree_O $tree_A $tree_B
273 "
274
275 test_expect_success \
276     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' "
277      rm -f .git/index AA &&
278      cp .orig-A/AA AA &&
279      echo extra >>AA &&
280      git update-index --add AA &&
281      read_tree_must_fail -m $tree_O $tree_A $tree_B
282 "
283
284 test_expect_success \
285     '5 - must match in !O && A && B && A==B case.' \
286     "rm -f .git/index LL &&
287      cp .orig-A/LL LL &&
288      git update-index --add LL &&
289      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
290      check_result"
291
292 test_expect_success \
293     '5 - must match in !O && A && B && A==B case.' \
294     "rm -f .git/index LL &&
295      cp .orig-A/LL LL &&
296      git update-index --add LL &&
297      echo extra >>LL &&
298      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
299      check_result"
300
301 test_expect_success \
302     '5 (fail) - must match A in !O && A && B && A==B case.' "
303      rm -f .git/index LL &&
304      cp .orig-A/LL LL &&
305      echo extra >>LL &&
306      git update-index --add LL &&
307      read_tree_must_fail -m $tree_O $tree_A $tree_B
308 "
309
310 test_expect_success \
311     '6 - must not exist in O && !A && !B case' "
312      rm -f .git/index DD &&
313      echo DD >DD &&
314      git update-index --add DD &&
315      read_tree_must_fail -m $tree_O $tree_A $tree_B
316 "
317
318 test_expect_success \
319     '7 - must not exist in O && !A && B && O!=B case' "
320      rm -f .git/index DM &&
321      cp .orig-B/DM DM &&
322      git update-index --add DM &&
323      read_tree_must_fail -m $tree_O $tree_A $tree_B
324 "
325
326 test_expect_success \
327     '8 - must not exist in O && !A && B && O==B case' "
328      rm -f .git/index DN &&
329      cp .orig-B/DN DN &&
330      git update-index --add DN &&
331      read_tree_must_fail -m $tree_O $tree_A $tree_B
332 "
333
334 test_expect_success \
335     '9 - 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      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
340      check_result"
341
342 test_expect_success \
343     '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      git update-index --add MD &&
347      echo extra >>MD &&
348      read_tree_must_fail -m $tree_O $tree_A $tree_B
349 "
350
351 test_expect_success \
352     '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' "
353      rm -f .git/index MD &&
354      cp .orig-A/MD MD &&
355      echo extra >>MD &&
356      git update-index --add MD &&
357      read_tree_must_fail -m $tree_O $tree_A $tree_B
358 "
359
360 test_expect_success \
361     '10 - must match and be up-to-date in O && A && !B && O==A case' \
362     "rm -f .git/index ND &&
363      cp .orig-A/ND ND &&
364      git update-index --add ND &&
365      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
366      check_result"
367
368 test_expect_success \
369     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' "
370      rm -f .git/index ND &&
371      cp .orig-A/ND ND &&
372      git update-index --add ND &&
373      echo extra >>ND &&
374      read_tree_must_fail -m $tree_O $tree_A $tree_B
375 "
376
377 test_expect_success \
378     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' "
379      rm -f .git/index ND &&
380      cp .orig-A/ND ND &&
381      echo extra >>ND &&
382      git update-index --add ND &&
383      read_tree_must_fail -m $tree_O $tree_A $tree_B
384 "
385
386 test_expect_success \
387     '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
388     "rm -f .git/index MM &&
389      cp .orig-A/MM MM &&
390      git update-index --add MM &&
391      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
392      check_result"
393
394 test_expect_success \
395     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' "
396      rm -f .git/index MM &&
397      cp .orig-A/MM MM &&
398      git update-index --add MM &&
399      echo extra >>MM &&
400      read_tree_must_fail -m $tree_O $tree_A $tree_B
401 "
402
403 test_expect_success \
404     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' "
405      rm -f .git/index MM &&
406      cp .orig-A/MM MM &&
407      echo extra >>MM &&
408      git update-index --add MM &&
409      read_tree_must_fail -m $tree_O $tree_A $tree_B
410 "
411
412 test_expect_success \
413     '12 - must match A in O && A && B && O!=A && A==B case' \
414     "rm -f .git/index SS &&
415      cp .orig-A/SS SS &&
416      git update-index --add SS &&
417      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
418      check_result"
419
420 test_expect_success \
421     '12 - must match A in O && A && B && O!=A && A==B case' \
422     "rm -f .git/index SS &&
423      cp .orig-A/SS SS &&
424      git update-index --add SS &&
425      echo extra >>SS &&
426      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
427      check_result"
428
429 test_expect_success \
430     '12 (fail) - must match A in O && A && B && O!=A && A==B case' "
431      rm -f .git/index SS &&
432      cp .orig-A/SS SS &&
433      echo extra >>SS &&
434      git update-index --add SS &&
435      read_tree_must_fail -m $tree_O $tree_A $tree_B
436 "
437
438 test_expect_success \
439     '13 - must match A in O && A && B && O!=A && O==B case' \
440     "rm -f .git/index MN &&
441      cp .orig-A/MN MN &&
442      git update-index --add MN &&
443      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
444      check_result"
445
446 test_expect_success \
447     '13 - must match A in O && A && B && O!=A && O==B case' \
448     "rm -f .git/index MN &&
449      cp .orig-A/MN MN &&
450      git update-index --add MN &&
451      echo extra >>MN &&
452      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
453      check_result"
454
455 test_expect_success \
456     '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \
457     "rm -f .git/index NM &&
458      cp .orig-A/NM NM &&
459      git update-index --add NM &&
460      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
461      check_result"
462
463 test_expect_success \
464     '14 - may match B in O && A && B && O==A && O!=B case' \
465     "rm -f .git/index NM &&
466      cp .orig-B/NM NM &&
467      git update-index --add NM &&
468      echo extra >>NM &&
469      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
470      check_result"
471
472 test_expect_success \
473     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' "
474      rm -f .git/index NM &&
475      cp .orig-A/NM NM &&
476      git update-index --add NM &&
477      echo extra >>NM &&
478      read_tree_must_fail -m $tree_O $tree_A $tree_B
479 "
480
481 test_expect_success \
482     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' "
483      rm -f .git/index NM &&
484      cp .orig-A/NM NM &&
485      echo extra >>NM &&
486      git update-index --add NM &&
487      read_tree_must_fail -m $tree_O $tree_A $tree_B
488 "
489
490 test_expect_success \
491     '15 - 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      git update-index --add NN &&
495      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
496      check_result"
497
498 test_expect_success \
499     '15 - must match A in O && A && B && O==A && O==B case' \
500     "rm -f .git/index NN &&
501      cp .orig-A/NN NN &&
502      git update-index --add NN &&
503      echo extra >>NN &&
504      read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
505      check_result"
506
507 test_expect_success \
508     '15 (fail) - must match A in O && A && B && O==A && O==B case' "
509      rm -f .git/index NN &&
510      cp .orig-A/NN NN &&
511      echo extra >>NN &&
512      git update-index --add NN &&
513      read_tree_must_fail -m $tree_O $tree_A $tree_B
514 "
515
516 # #16
517 test_expect_success \
518     '16 - A matches in one and B matches in another.' \
519     'rm -f .git/index F16 &&
520     echo F16 >F16 &&
521     git update-index --add F16 &&
522     tree0=`git write-tree` &&
523     echo E16 >F16 &&
524     git update-index F16 &&
525     tree1=`git write-tree` &&
526     read_tree_must_succeed -m $tree0 $tree1 $tree1 $tree0 &&
527     git ls-files --stage'
528
529 test_done