revert: fix off by one read when searching the end of a commit subject
[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-m-3way.sh
76
77 ################################################################
78 # Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT
79 # and #5ALT trivial merges.
80
81 cat >expected <<\EOF
82 100644 X 2      AA
83 100644 X 3      AA
84 100644 X 0      AN
85 100644 X 1      DD
86 100644 X 3      DF
87 100644 X 2      DF/DF
88 100644 X 1      DM
89 100644 X 3      DM
90 100644 X 1      DN
91 100644 X 3      DN
92 100644 X 0      LL
93 100644 X 1      MD
94 100644 X 2      MD
95 100644 X 1      MM
96 100644 X 2      MM
97 100644 X 3      MM
98 100644 X 0      MN
99 100644 X 0      NA
100 100644 X 1      ND
101 100644 X 2      ND
102 100644 X 0      NM
103 100644 X 0      NN
104 100644 X 0      SS
105 100644 X 1      TT
106 100644 X 2      TT
107 100644 X 3      TT
108 100644 X 2      Z/AA
109 100644 X 3      Z/AA
110 100644 X 0      Z/AN
111 100644 X 1      Z/DD
112 100644 X 1      Z/DM
113 100644 X 3      Z/DM
114 100644 X 1      Z/DN
115 100644 X 3      Z/DN
116 100644 X 1      Z/MD
117 100644 X 2      Z/MD
118 100644 X 1      Z/MM
119 100644 X 2      Z/MM
120 100644 X 3      Z/MM
121 100644 X 0      Z/MN
122 100644 X 0      Z/NA
123 100644 X 1      Z/ND
124 100644 X 2      Z/ND
125 100644 X 0      Z/NM
126 100644 X 0      Z/NN
127 EOF
128
129 check_result () {
130     git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current &&
131     test_cmp expected current
132 }
133
134 # This is done on an empty work directory, which is the normal
135 # merge person behaviour.
136 test_expect_success \
137     '3-way merge with git read-tree -m, empty cache' \
138     "rm -fr [NDMALTS][NDMALTSF] Z &&
139      rm .git/index &&
140      git read-tree -m $tree_O $tree_A $tree_B &&
141      check_result"
142
143 # This starts out with the first head, which is the normal
144 # patch submitter behaviour.
145 test_expect_success \
146     '3-way merge with git read-tree -m, match H' \
147     "rm -fr [NDMALTS][NDMALTSF] Z &&
148      rm .git/index &&
149      git read-tree $tree_A &&
150      git checkout-index -f -u -a &&
151      git read-tree -m $tree_O $tree_A $tree_B &&
152      check_result"
153
154 : <<\END_OF_CASE_TABLE
155
156 We have so far tested only empty index and clean-and-matching-A index
157 case which are trivial.  Make sure index requirements are also
158 checked.
159
160 "git read-tree -m O A B"
161
162      O       A       B         result      index requirements
163 -------------------------------------------------------------------
164   1  missing missing missing   -           must not exist.
165  ------------------------------------------------------------------
166   2  missing missing exists    take B*     must match B, if exists.
167  ------------------------------------------------------------------
168   3  missing exists  missing   take A*     must match A, if exists.
169  ------------------------------------------------------------------
170   4  missing exists  A!=B      no merge    must match A and be
171                                            up-to-date, if exists.
172  ------------------------------------------------------------------
173   5  missing exists  A==B      take A      must match A, if exists.
174  ------------------------------------------------------------------
175   6  exists  missing missing   remove      must not exist.
176  ------------------------------------------------------------------
177   7  exists  missing O!=B      no merge    must not exist.
178  ------------------------------------------------------------------
179   8  exists  missing O==B      remove      must not exist.
180  ------------------------------------------------------------------
181   9  exists  O!=A    missing   no merge    must match A and be
182                                            up-to-date, if exists.
183  ------------------------------------------------------------------
184  10  exists  O==A    missing   no merge    must match A
185  ------------------------------------------------------------------
186  11  exists  O!=A    O!=B      no merge    must match A and be
187                      A!=B                  up-to-date, if exists.
188  ------------------------------------------------------------------
189  12  exists  O!=A    O!=B      take A      must match A, if exists.
190                      A==B
191  ------------------------------------------------------------------
192  13  exists  O!=A    O==B      take A      must match A, if exists.
193  ------------------------------------------------------------------
194  14  exists  O==A    O!=B      take B      if exists, must either (1)
195                                            match A and be up-to-date,
196                                            or (2) match B.
197  ------------------------------------------------------------------
198  15  exists  O==A    O==B      take B      must match A if exists.
199  ------------------------------------------------------------------
200  16  exists  O==A    O==B      barf        must match A if exists.
201      *multi* in one  in another
202 -------------------------------------------------------------------
203
204 Note: we need to be careful in case 2 and 3.  The tree A may contain
205 DF (file) when tree B require DF to be a directory by having DF/DF
206 (file).
207
208 END_OF_CASE_TABLE
209
210 test_expect_success '1 - must not have an entry not in A.' "
211      rm -f .git/index XX &&
212      echo XX >XX &&
213      git update-index --add XX &&
214      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
215 "
216
217 test_expect_success \
218     '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      git read-tree -m $tree_O $tree_A $tree_B"
223
224 test_expect_success \
225     '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      git read-tree -m $tree_O $tree_A $tree_B"
231
232 test_expect_success \
233     '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      git read-tree -m $tree_O $tree_A $tree_B &&
238      check_result"
239
240 test_expect_success \
241     '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      git read-tree -m $tree_O $tree_A $tree_B"
247
248 test_expect_success \
249     '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      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
255 "
256
257 test_expect_success \
258     '4 - must match and be up-to-date in !O && A && B && A!=B case.' \
259     "rm -f .git/index AA &&
260      cp .orig-A/AA AA &&
261      git update-index --add AA &&
262      git read-tree -m $tree_O $tree_A $tree_B &&
263      check_result"
264
265 test_expect_success \
266     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' "
267      rm -f .git/index AA &&
268      cp .orig-A/AA AA &&
269      git update-index --add AA &&
270      echo extra >>AA &&
271      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
272 "
273
274 test_expect_success \
275     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' "
276      rm -f .git/index AA &&
277      cp .orig-A/AA AA &&
278      echo extra >>AA &&
279      git update-index --add AA &&
280      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
281 "
282
283 test_expect_success \
284     '5 - must match in !O && A && B && A==B case.' \
285     "rm -f .git/index LL &&
286      cp .orig-A/LL LL &&
287      git update-index --add LL &&
288      git read-tree -m $tree_O $tree_A $tree_B &&
289      check_result"
290
291 test_expect_success \
292     '5 - must match in !O && A && B && A==B case.' \
293     "rm -f .git/index LL &&
294      cp .orig-A/LL LL &&
295      git update-index --add LL &&
296      echo extra >>LL &&
297      git read-tree -m $tree_O $tree_A $tree_B &&
298      check_result"
299
300 test_expect_success \
301     '5 (fail) - must match A in !O && A && B && A==B case.' "
302      rm -f .git/index LL &&
303      cp .orig-A/LL LL &&
304      echo extra >>LL &&
305      git update-index --add LL &&
306      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
307 "
308
309 test_expect_success \
310     '6 - must not exist in O && !A && !B case' "
311      rm -f .git/index DD &&
312      echo DD >DD
313      git update-index --add DD &&
314      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
315 "
316
317 test_expect_success \
318     '7 - must not exist in O && !A && B && O!=B case' "
319      rm -f .git/index DM &&
320      cp .orig-B/DM DM &&
321      git update-index --add DM &&
322      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
323 "
324
325 test_expect_success \
326     '8 - must not exist in O && !A && B && O==B case' "
327      rm -f .git/index DN &&
328      cp .orig-B/DN DN &&
329      git update-index --add DN &&
330      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
331 "
332
333 test_expect_success \
334     '9 - must match and be up-to-date in O && A && !B && O!=A case' \
335     "rm -f .git/index MD &&
336      cp .orig-A/MD MD &&
337      git update-index --add MD &&
338      git read-tree -m $tree_O $tree_A $tree_B &&
339      check_result"
340
341 test_expect_success \
342     '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' "
343      rm -f .git/index MD &&
344      cp .orig-A/MD MD &&
345      git update-index --add MD &&
346      echo extra >>MD &&
347      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
348 "
349
350 test_expect_success \
351     '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' "
352      rm -f .git/index MD &&
353      cp .orig-A/MD MD &&
354      echo extra >>MD &&
355      git update-index --add MD &&
356      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
357 "
358
359 test_expect_success \
360     '10 - must match and be up-to-date in O && A && !B && O==A case' \
361     "rm -f .git/index ND &&
362      cp .orig-A/ND ND &&
363      git update-index --add ND &&
364      git read-tree -m $tree_O $tree_A $tree_B &&
365      check_result"
366
367 test_expect_success \
368     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' "
369      rm -f .git/index ND &&
370      cp .orig-A/ND ND &&
371      git update-index --add ND &&
372      echo extra >>ND &&
373      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
374 "
375
376 test_expect_success \
377     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' "
378      rm -f .git/index ND &&
379      cp .orig-A/ND ND &&
380      echo extra >>ND &&
381      git update-index --add ND &&
382      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
383 "
384
385 test_expect_success \
386     '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
387     "rm -f .git/index MM &&
388      cp .orig-A/MM MM &&
389      git update-index --add MM &&
390      git read-tree -m $tree_O $tree_A $tree_B &&
391      check_result"
392
393 test_expect_success \
394     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' "
395      rm -f .git/index MM &&
396      cp .orig-A/MM MM &&
397      git update-index --add MM &&
398      echo extra >>MM &&
399      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
400 "
401
402 test_expect_success \
403     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' "
404      rm -f .git/index MM &&
405      cp .orig-A/MM MM &&
406      echo extra >>MM &&
407      git update-index --add MM &&
408      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
409 "
410
411 test_expect_success \
412     '12 - must match A in O && A && B && O!=A && A==B case' \
413     "rm -f .git/index SS &&
414      cp .orig-A/SS SS &&
415      git update-index --add SS &&
416      git read-tree -m $tree_O $tree_A $tree_B &&
417      check_result"
418
419 test_expect_success \
420     '12 - must match A in O && A && B && O!=A && A==B case' \
421     "rm -f .git/index SS &&
422      cp .orig-A/SS SS &&
423      git update-index --add SS &&
424      echo extra >>SS &&
425      git read-tree -m $tree_O $tree_A $tree_B &&
426      check_result"
427
428 test_expect_success \
429     '12 (fail) - must match A in O && A && B && O!=A && A==B case' "
430      rm -f .git/index SS &&
431      cp .orig-A/SS SS &&
432      echo extra >>SS &&
433      git update-index --add SS &&
434      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
435 "
436
437 test_expect_success \
438     '13 - must match A in O && A && B && O!=A && O==B case' \
439     "rm -f .git/index MN &&
440      cp .orig-A/MN MN &&
441      git update-index --add MN &&
442      git read-tree -m $tree_O $tree_A $tree_B &&
443      check_result"
444
445 test_expect_success \
446     '13 - must match A in O && A && B && O!=A && O==B case' \
447     "rm -f .git/index MN &&
448      cp .orig-A/MN MN &&
449      git update-index --add MN &&
450      echo extra >>MN &&
451      git read-tree -m $tree_O $tree_A $tree_B &&
452      check_result"
453
454 test_expect_success \
455     '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \
456     "rm -f .git/index NM &&
457      cp .orig-A/NM NM &&
458      git update-index --add NM &&
459      git read-tree -m $tree_O $tree_A $tree_B &&
460      check_result"
461
462 test_expect_success \
463     '14 - may match B in O && A && B && O==A && O!=B case' \
464     "rm -f .git/index NM &&
465      cp .orig-B/NM NM &&
466      git update-index --add NM &&
467      echo extra >>NM &&
468      git read-tree -m $tree_O $tree_A $tree_B &&
469      check_result"
470
471 test_expect_success \
472     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' "
473      rm -f .git/index NM &&
474      cp .orig-A/NM NM &&
475      git update-index --add NM &&
476      echo extra >>NM &&
477      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
478 "
479
480 test_expect_success \
481     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' "
482      rm -f .git/index NM &&
483      cp .orig-A/NM NM &&
484      echo extra >>NM &&
485      git update-index --add NM &&
486      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
487 "
488
489 test_expect_success \
490     '15 - must match A in O && A && B && O==A && O==B case' \
491     "rm -f .git/index NN &&
492      cp .orig-A/NN NN &&
493      git update-index --add NN &&
494      git read-tree -m $tree_O $tree_A $tree_B &&
495      check_result"
496
497 test_expect_success \
498     '15 - must match A in O && A && B && O==A && O==B case' \
499     "rm -f .git/index NN &&
500      cp .orig-A/NN NN &&
501      git update-index --add NN &&
502      echo extra >>NN &&
503      git read-tree -m $tree_O $tree_A $tree_B &&
504      check_result"
505
506 test_expect_success \
507     '15 (fail) - must match A in O && A && B && O==A && O==B case' "
508      rm -f .git/index NN &&
509      cp .orig-A/NN NN &&
510      echo extra >>NN &&
511      git update-index --add NN &&
512      test_must_fail git read-tree -m $tree_O $tree_A $tree_B
513 "
514
515 # #16
516 test_expect_success \
517     '16 - A matches in one and B matches in another.' \
518     'rm -f .git/index F16 &&
519     echo F16 >F16 &&
520     git update-index --add F16 &&
521     tree0=`git write-tree` &&
522     echo E16 >F16 &&
523     git update-index F16 &&
524     tree1=`git write-tree` &&
525     git read-tree -m $tree0 $tree1 $tree1 $tree0 &&
526     git ls-files --stage'
527
528 test_done