Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2010 Will Palmer
4 #
5
6 test_description='git merge-tree'
7
8 . ./test-lib.sh
9
10 test_expect_success setup '
11 test_commit "initial" "initial-file" "initial"
12 '
13
14 test_expect_success 'file add A, !B' '
15 git reset --hard initial &&
16 test_commit "add-a-not-b" "ONE" "AAA" &&
17 git merge-tree initial initial add-a-not-b >actual &&
18 cat >expected <<EXPECTED &&
19 added in remote
20 their 100644 $(git rev-parse HEAD:ONE) ONE
21 @@ -0,0 +1 @@
22 +AAA
23 EXPECTED
24
25 test_cmp expected actual
26 '
27
28 test_expect_success 'file add !A, B' '
29 git reset --hard initial &&
30 test_commit "add-not-a-b" "ONE" "AAA" &&
31 git merge-tree initial add-not-a-b initial >actual &&
32 test_must_be_empty actual
33 '
34
35 test_expect_success 'file add A, B (same)' '
36 git reset --hard initial &&
37 test_commit "add-a-b-same-A" "ONE" "AAA" &&
38 git reset --hard initial &&
39 test_commit "add-a-b-same-B" "ONE" "AAA" &&
40 git merge-tree initial add-a-b-same-A add-a-b-same-B >actual &&
41 test_must_be_empty actual
42 '
43
44 test_expect_success 'file add A, B (different)' '
45 git reset --hard initial &&
46 test_commit "add-a-b-diff-A" "ONE" "AAA" &&
47 git reset --hard initial &&
48 test_commit "add-a-b-diff-B" "ONE" "BBB" &&
49 git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual &&
50 cat >expected <<EXPECTED &&
51 added in both
52 our 100644 $(git rev-parse add-a-b-diff-A:ONE) ONE
53 their 100644 $(git rev-parse add-a-b-diff-B:ONE) ONE
54 @@ -1 +1,5 @@
55 +<<<<<<< .our
56 AAA
57 +=======
58 +BBB
59 +>>>>>>> .their
60 EXPECTED
61
62 test_cmp expected actual
63 '
64
65 test_expect_success 'file change A, !B' '
66 git reset --hard initial &&
67 test_commit "change-a-not-b" "initial-file" "BBB" &&
68 git merge-tree initial change-a-not-b initial >actual &&
69 test_must_be_empty actual
70 '
71
72 test_expect_success 'file change !A, B' '
73 git reset --hard initial &&
74 test_commit "change-not-a-b" "initial-file" "BBB" &&
75 git merge-tree initial initial change-not-a-b >actual &&
76 cat >expected <<EXPECTED &&
77 merged
78 result 100644 $(git rev-parse change-a-not-b:initial-file) initial-file
79 our 100644 $(git rev-parse initial:initial-file ) initial-file
80 @@ -1 +1 @@
81 -initial
82 +BBB
83 EXPECTED
84
85 test_cmp expected actual
86 '
87
88 test_expect_success '3-way merge with --attr-source' '
89 test_when_finished rm -rf 3-way &&
90 git init 3-way &&
91 (
92 cd 3-way &&
93 test_commit initial file1 foo &&
94 base=$(git rev-parse HEAD) &&
95 git checkout -b brancha &&
96 echo bar >>file1 &&
97 git commit -am "adding bar" &&
98 source=$(git rev-parse HEAD) &&
99 git checkout @{-1} &&
100 git checkout -b branchb &&
101 echo baz >>file1 &&
102 git commit -am "adding baz" &&
103 merge=$(git rev-parse HEAD) &&
104 git checkout -b gitattributes &&
105 test_commit "gitattributes" .gitattributes "file1 merge=union" &&
106 git checkout @{-1} &&
107 tree=$(git --attr-source=gitattributes merge-tree --write-tree \
108 --merge-base "$base" --end-of-options "$source" "$merge") &&
109 test_write_lines foo bar baz >expect &&
110 git cat-file -p "$tree:file1" >actual &&
111 test_cmp expect actual
112 )
113 '
114
115 test_expect_success 'file change A, B (same)' '
116 git reset --hard initial &&
117 test_commit "change-a-b-same-A" "initial-file" "AAA" &&
118 git reset --hard initial &&
119 test_commit "change-a-b-same-B" "initial-file" "AAA" &&
120 git merge-tree initial change-a-b-same-A change-a-b-same-B >actual &&
121 test_must_be_empty actual
122 '
123
124 test_expect_success 'file change A, B (different)' '
125 git reset --hard initial &&
126 test_commit "change-a-b-diff-A" "initial-file" "AAA" &&
127 git reset --hard initial &&
128 test_commit "change-a-b-diff-B" "initial-file" "BBB" &&
129 git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual &&
130 cat >expected <<EXPECTED &&
131 changed in both
132 base 100644 $(git rev-parse initial:initial-file ) initial-file
133 our 100644 $(git rev-parse change-a-b-diff-A:initial-file) initial-file
134 their 100644 $(git rev-parse change-a-b-diff-B:initial-file) initial-file
135 @@ -1 +1,5 @@
136 +<<<<<<< .our
137 AAA
138 +=======
139 +BBB
140 +>>>>>>> .their
141 EXPECTED
142
143 test_cmp expected actual
144 '
145
146 test_expect_success 'file change A, B (mixed)' '
147 git reset --hard initial &&
148 test_commit "change-a-b-mix-base" "ONE" "
149 AAA
150 AAA
151 AAA
152 AAA
153 AAA
154 AAA
155 AAA
156 AAA
157 AAA
158 AAA
159 AAA
160 AAA
161 AAA
162 AAA
163 AAA" &&
164 test_commit "change-a-b-mix-A" "ONE" \
165 "$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/BBB/;}" <ONE)" &&
166 git reset --hard change-a-b-mix-base &&
167 test_commit "change-a-b-mix-B" "ONE" \
168 "$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/CCC/;}" <ONE)" &&
169 git merge-tree change-a-b-mix-base change-a-b-mix-A change-a-b-mix-B \
170 >actual &&
171
172 cat >expected <<EXPECTED &&
173 changed in both
174 base 100644 $(git rev-parse change-a-b-mix-base:ONE) ONE
175 our 100644 $(git rev-parse change-a-b-mix-A:ONE ) ONE
176 their 100644 $(git rev-parse change-a-b-mix-B:ONE ) ONE
177 @@ -7,7 +7,11 @@
178 AAA
179 AAA
180 AAA
181 +<<<<<<< .our
182 BBB
183 +=======
184 +CCC
185 +>>>>>>> .their
186 AAA
187 AAA
188 AAA
189 EXPECTED
190
191 test_cmp expected actual
192 '
193
194 test_expect_success 'file remove A, !B' '
195 git reset --hard initial &&
196 test_commit "rm-a-not-b-base" "ONE" "AAA" &&
197 git rm ONE &&
198 git commit -m "rm-a-not-b" &&
199 git tag "rm-a-not-b" &&
200 git merge-tree rm-a-not-b-base rm-a-not-b rm-a-not-b-base >actual &&
201 test_must_be_empty actual
202 '
203
204 test_expect_success 'file remove !A, B' '
205 git reset --hard initial &&
206 test_commit "rm-not-a-b-base" "ONE" "AAA" &&
207 git rm ONE &&
208 git commit -m "rm-not-a-b" &&
209 git tag "rm-not-a-b" &&
210 git merge-tree rm-a-not-b-base rm-a-not-b-base rm-a-not-b >actual &&
211 cat >expected <<EXPECTED &&
212 removed in remote
213 base 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE
214 our 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE
215 @@ -1 +0,0 @@
216 -AAA
217 EXPECTED
218
219 test_cmp expected actual
220 '
221
222 test_expect_success 'file remove A, B (same)' '
223 git reset --hard initial &&
224 test_commit "rm-a-b-base" "ONE" "AAA" &&
225 git rm ONE &&
226 git commit -m "rm-a-b" &&
227 git tag "rm-a-b" &&
228 git merge-tree rm-a-b-base rm-a-b rm-a-b >actual &&
229 test_must_be_empty actual
230 '
231
232 test_expect_success 'file change A, remove B' '
233 git reset --hard initial &&
234 test_commit "change-a-rm-b-base" "ONE" "AAA" &&
235 test_commit "change-a-rm-b-A" "ONE" "BBB" &&
236 git reset --hard change-a-rm-b-base &&
237 git rm ONE &&
238 git commit -m "change-a-rm-b-B" &&
239 git tag "change-a-rm-b-B" &&
240 git merge-tree change-a-rm-b-base change-a-rm-b-A change-a-rm-b-B \
241 >actual &&
242 cat >expected <<EXPECTED &&
243 removed in remote
244 base 100644 $(git rev-parse change-a-rm-b-base:ONE) ONE
245 our 100644 $(git rev-parse change-a-rm-b-A:ONE ) ONE
246 @@ -1 +0,0 @@
247 -BBB
248 EXPECTED
249
250 test_cmp expected actual
251 '
252
253 test_expect_success 'file remove A, change B' '
254 git reset --hard initial &&
255 test_commit "rm-a-change-b-base" "ONE" "AAA" &&
256
257 git rm ONE &&
258 git commit -m "rm-a-change-b-A" &&
259 git tag "rm-a-change-b-A" &&
260 git reset --hard rm-a-change-b-base &&
261 test_commit "rm-a-change-b-B" "ONE" "BBB" &&
262 git merge-tree rm-a-change-b-base rm-a-change-b-A rm-a-change-b-B \
263 >actual &&
264 cat >expected <<EXPECTED &&
265 removed in local
266 base 100644 $(git rev-parse rm-a-change-b-base:ONE) ONE
267 their 100644 $(git rev-parse rm-a-change-b-B:ONE ) ONE
268 EXPECTED
269 test_cmp expected actual
270 '
271
272 test_expect_success 'tree add A, B (same)' '
273 git reset --hard initial &&
274 mkdir sub &&
275 test_commit "add sub/file" "sub/file" "file" add-tree-A &&
276 git merge-tree initial add-tree-A add-tree-A >actual &&
277 test_must_be_empty actual
278 '
279
280 test_expect_success 'tree add A, B (different)' '
281 git reset --hard initial &&
282 mkdir sub &&
283 test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A &&
284 git reset --hard initial &&
285 mkdir sub &&
286 test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B &&
287 git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual &&
288 cat >expect <<-EOF &&
289 added in both
290 our 100644 $(git rev-parse add-tree-a-b-A:sub/file) sub/file
291 their 100644 $(git rev-parse add-tree-a-b-B:sub/file) sub/file
292 @@ -1 +1,5 @@
293 +<<<<<<< .our
294 AAA
295 +=======
296 +BBB
297 +>>>>>>> .their
298 EOF
299 test_cmp expect actual
300 '
301
302 test_expect_success 'tree unchanged A, removed B' '
303 git reset --hard initial &&
304 mkdir sub &&
305 test_commit "add sub/file" "sub/file" "AAA" tree-remove-b-initial &&
306 git rm sub/file &&
307 test_tick &&
308 git commit -m "remove sub/file" &&
309 git tag tree-remove-b-B &&
310 git merge-tree tree-remove-b-initial tree-remove-b-initial tree-remove-b-B >actual &&
311 cat >expect <<-EOF &&
312 removed in remote
313 base 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file
314 our 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file
315 @@ -1 +0,0 @@
316 -AAA
317 EOF
318 test_cmp expect actual
319 '
320
321 test_expect_success 'turn file to tree' '
322 git reset --hard initial &&
323 rm initial-file &&
324 mkdir initial-file &&
325 test_commit "turn-file-to-tree" "initial-file/ONE" "CCC" &&
326 git merge-tree initial initial turn-file-to-tree >actual &&
327 cat >expect <<-EOF &&
328 added in remote
329 their 100644 $(git rev-parse turn-file-to-tree:initial-file/ONE) initial-file/ONE
330 @@ -0,0 +1 @@
331 +CCC
332 removed in remote
333 base 100644 $(git rev-parse initial:initial-file) initial-file
334 our 100644 $(git rev-parse initial:initial-file) initial-file
335 @@ -1 +0,0 @@
336 -initial
337 EOF
338 test_cmp expect actual
339 '
340
341 test_expect_success 'turn tree to file' '
342 git reset --hard initial &&
343 mkdir dir &&
344 test_commit "add-tree" "dir/path" "AAA" &&
345 test_commit "add-another-tree" "dir/another" "BBB" &&
346 rm -fr dir &&
347 test_commit "make-file" "dir" "CCC" &&
348 git merge-tree add-tree add-another-tree make-file >actual &&
349 cat >expect <<-EOF &&
350 removed in remote
351 base 100644 $(git rev-parse add-tree:dir/path) dir/path
352 our 100644 $(git rev-parse add-tree:dir/path) dir/path
353 @@ -1 +0,0 @@
354 -AAA
355 added in remote
356 their 100644 $(git rev-parse make-file:dir) dir
357 @@ -0,0 +1 @@
358 +CCC
359 EOF
360 test_cmp expect actual
361 '
362
363 test_expect_success 'merge-tree respects core.useReplaceRefs=false' '
364 test_commit merge-to &&
365 test_commit valid base &&
366 git reset --hard HEAD^ &&
367 test_commit malicious base &&
368
369 test_when_finished "git replace -d $(git rev-parse valid^0)" &&
370 git replace valid^0 malicious^0 &&
371
372 tree=$(git -c core.useReplaceRefs=true merge-tree --write-tree merge-to valid) &&
373 merged=$(git cat-file -p $tree:base) &&
374 test malicious = $merged &&
375
376 tree=$(git -c core.useReplaceRefs=false merge-tree --write-tree merge-to valid) &&
377 merged=$(git cat-file -p $tree:base) &&
378 test valid = $merged
379 '
380
381 test_done