##// END OF EJS Templates
merge: fix crash on criss cross merge with dir move and delete (issue5020)...
Mads Kiilerich -
r30856:41f6af50 stable
parent child Browse files
Show More
@@ -997,6 +997,7 b' def calculateupdates(repo, wctx, mctx, a'
997 997 # Pick the best bid for each file
998 998 repo.ui.note(_('\nauction for merging merge bids\n'))
999 999 actions = {}
1000 dms = [] # filenames that have dm actions
1000 1001 for f, bids in sorted(fbids.items()):
1001 1002 # bids is a mapping from action method to list af actions
1002 1003 # Consensus?
@@ -1005,6 +1006,8 b' def calculateupdates(repo, wctx, mctx, a'
1005 1006 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1006 1007 repo.ui.note(_(" %s: consensus for %s\n") % (f, m))
1007 1008 actions[f] = l[0]
1009 if m == 'dm':
1010 dms.append(f)
1008 1011 continue
1009 1012 # If keep is an option, just do it.
1010 1013 if 'k' in bids:
@@ -1029,7 +1032,19 b' def calculateupdates(repo, wctx, mctx, a'
1029 1032 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
1030 1033 (f, m))
1031 1034 actions[f] = l[0]
1035 if m == 'dm':
1036 dms.append(f)
1032 1037 continue
1038 # Work around 'dm' that can cause multiple actions for the same file
1039 for f in dms:
1040 dm, (f0, flags), msg = actions[f]
1041 assert dm == 'dm', dm
1042 m, args, msg = actions[f0]
1043 if m == 'r':
1044 # We have one bid for removing a file and another for moving it.
1045 # These two could be merged as first move and then delete ...
1046 # but instead drop moving and just delete.
1047 del actions[f]
1033 1048 repo.ui.note(_('end of auction\n\n'))
1034 1049
1035 1050 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
@@ -11,9 +11,15 b' Criss cross merging'
11 11
12 12 $ hg up -qr0
13 13 $ echo '2 first change' > f2
14 $ mkdir d1
15 $ echo '0 base' > d1/f3
16 $ echo '0 base' > d1/f4
17 $ hg add -q d1
14 18 $ hg ci -qm '2 first change f2'
15 19
16 20 $ hg merge -qr 1
21 $ hg rm d1/f3
22 $ hg mv -q d1 d2
17 23 $ hg ci -m '3 merge'
18 24
19 25 $ hg up -qr2
@@ -24,38 +30,38 b' Criss cross merging'
24 30 $ hg ci -m '5 second change f1'
25 31
26 32 $ hg up -r3
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
28 34 $ echo '6 second change' > f2
29 35 $ hg ci -m '6 second change f2'
30 36
31 37 $ hg log -G
32 @ changeset: 6:3b08d01b0ab5
38 @ changeset: 6:6373bbfdae1d
33 39 | tag: tip
34 | parent: 3:cf89f02107e5
40 | parent: 3:c202c8af058d
35 41 | user: test
36 42 | date: Thu Jan 01 00:00:00 1970 +0000
37 43 | summary: 6 second change f2
38 44 |
39 | o changeset: 5:adfe50279922
45 | o changeset: 5:e673248094b1
40 46 | | user: test
41 47 | | date: Thu Jan 01 00:00:00 1970 +0000
42 48 | | summary: 5 second change f1
43 49 | |
44 | o changeset: 4:7d3e55501ae6
45 | |\ parent: 2:40663881a6dd
50 | o changeset: 4:177f58377c06
51 | |\ parent: 2:d1d156401c1b
46 52 | | | parent: 1:0f6b37dbe527
47 53 | | | user: test
48 54 | | | date: Thu Jan 01 00:00:00 1970 +0000
49 55 | | | summary: 4 merge
50 56 | | |
51 o---+ changeset: 3:cf89f02107e5
52 | | | parent: 2:40663881a6dd
57 o---+ changeset: 3:c202c8af058d
58 | | | parent: 2:d1d156401c1b
53 59 |/ / parent: 1:0f6b37dbe527
54 60 | | user: test
55 61 | | date: Thu Jan 01 00:00:00 1970 +0000
56 62 | | summary: 3 merge
57 63 | |
58 | o changeset: 2:40663881a6dd
64 | o changeset: 2:d1d156401c1b
59 65 | | parent: 0:40494bf2444c
60 66 | | user: test
61 67 | | date: Thu Jan 01 00:00:00 1970 +0000
@@ -73,27 +79,51 b' Criss cross merging'
73 79
74 80
75 81 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor='!'
76 note: using 0f6b37dbe527 as ancestor of 3b08d01b0ab5 and adfe50279922
77 alternatively, use --config merge.preferancestor=40663881a6dd
82 note: using 0f6b37dbe527 as ancestor of 6373bbfdae1d and e673248094b1
83 alternatively, use --config merge.preferancestor=d1d156401c1b
78 84 searching for copies back to rev 3
85 unmatched files in local:
86 d2/f4
87 unmatched files in other:
88 d1/f3
89 d1/f4
90 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
91 src: 'd1/f4' -> dst: 'd2/f4'
92 checking for directory renames
93 discovered dir src: 'd1/' -> dst: 'd2/'
94 pending file src: 'd1/f3' -> dst: 'd2/f3'
95 pending file src: 'd1/f4' -> dst: 'd2/f4'
79 96 resolving manifests
80 97 branchmerge: True, force: False, partial: False
81 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
98 ancestor: 0f6b37dbe527, local: 6373bbfdae1d+, remote: e673248094b1
99 preserving d2/f4 for resolve of d2/f4
82 100 preserving f2 for resolve of f2
83 101 f1: remote is newer -> g
84 102 getting f1
103 d2/f3: local directory rename - get from d1/f3 -> dg
104 getting d1/f3 to d2/f3
105 d2/f4: local directory rename, both created -> m (premerge)
85 106 f2: versions differ -> m (premerge)
86 107 picked tool ':dump' for f2 (binary False symlink False changedelete False)
87 108 merging f2
88 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
109 my f2@6373bbfdae1d+ other f2@e673248094b1 ancestor f2@0f6b37dbe527
89 110 f2: versions differ -> m (merge)
90 111 picked tool ':dump' for f2 (binary False symlink False changedelete False)
91 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
92 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
112 my f2@6373bbfdae1d+ other f2@e673248094b1 ancestor f2@0f6b37dbe527
113 3 files updated, 0 files merged, 0 files removed, 1 files unresolved
93 114 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
94 115 [1]
95 116
96 $ f --dump *
117 $ f --dump --recurse *
118 d2: directory with 2 files
119 d2/f3:
120 >>>
121 0 base
122 <<<
123 d2/f4:
124 >>>
125 0 base
126 <<<
97 127 f1:
98 128 >>>
99 129 5 second change
@@ -121,11 +151,13 b' Criss cross merging'
121 151
122 152 $ hg up -qC .
123 153 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
124 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
125 alternatively, use --config merge.preferancestor=0f6b37dbe527
154 note: using 0f6b37dbe527 as ancestor of 6373bbfdae1d and e673248094b1
155 alternatively, use --config merge.preferancestor=d1d156401c1b
126 156 resolving manifests
127 merging f1
128 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
157 getting f1
158 getting d1/f3 to d2/f3
159 merging f2
160 3 files updated, 0 files merged, 0 files removed, 1 files unresolved
129 161 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
130 162 [1]
131 163
@@ -134,36 +166,70 b' Redo merge with merge.preferancestor="*"'
134 166 $ rm f*
135 167 $ hg up -qC .
136 168 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
137 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
169 note: merging 6373bbfdae1d+ and e673248094b1 using bids from ancestors 0f6b37dbe527 and d1d156401c1b
138 170
139 171 calculating bids for ancestor 0f6b37dbe527
140 172 searching for copies back to rev 3
173 unmatched files in local:
174 d2/f4
175 unmatched files in other:
176 d1/f3
177 d1/f4
178 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
179 src: 'd1/f4' -> dst: 'd2/f4'
180 checking for directory renames
181 discovered dir src: 'd1/' -> dst: 'd2/'
182 pending file src: 'd1/f3' -> dst: 'd2/f3'
183 pending file src: 'd1/f4' -> dst: 'd2/f4'
141 184 resolving manifests
142 185 branchmerge: True, force: False, partial: False
143 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
186 ancestor: 0f6b37dbe527, local: 6373bbfdae1d+, remote: e673248094b1
187 d2/f3: local directory rename - get from d1/f3 -> dg
188 d2/f4: local directory rename, both created -> m
144 189 f1: remote is newer -> g
145 190 f2: versions differ -> m
146 191
147 calculating bids for ancestor 40663881a6dd
192 calculating bids for ancestor d1d156401c1b
148 193 searching for copies back to rev 3
194 unmatched files in local:
195 d2/f4
196 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
197 src: 'd1/f4' -> dst: 'd2/f4'
198 checking for directory renames
199 discovered dir src: 'd1/' -> dst: 'd2/'
149 200 resolving manifests
150 201 branchmerge: True, force: False, partial: False
151 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
202 ancestor: d1d156401c1b, local: 6373bbfdae1d+, remote: e673248094b1
152 203 f1: versions differ -> m
153 204 f2: remote unchanged -> k
154 205
155 206 auction for merging merge bids
207 d2/f3: consensus for dg
208 d2/f4: consensus for m
156 209 f1: picking 'get' action
157 210 f2: picking 'keep' action
158 211 end of auction
159 212
213 preserving d2/f4 for resolve of d2/f4
160 214 f1: remote is newer -> g
161 215 getting f1
162 216 f2: remote unchanged -> k
163 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
217 d2/f3: local directory rename - get from d1/f3 -> dg
218 getting d1/f3 to d2/f3
219 d2/f4: local directory rename, both created -> m (premerge)
220 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 221 (branch merge, don't forget to commit)
165 222
166 $ f --dump *
223 $ f --dump --recurse *
224 d2: directory with 2 files
225 d2/f3:
226 >>>
227 0 base
228 <<<
229 d2/f4:
230 >>>
231 0 base
232 <<<
167 233 f1:
168 234 >>>
169 235 5 second change
@@ -177,38 +243,79 b' Redo merge with merge.preferancestor="*"'
177 243 The other way around:
178 244
179 245 $ hg up -C -r5
180 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 4 files updated, 0 files merged, 1 files removed, 0 files unresolved
181 247 $ hg merge -v --debug --config merge.preferancestor="*"
182 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
248 note: merging e673248094b1+ and 6373bbfdae1d using bids from ancestors 0f6b37dbe527 and d1d156401c1b
183 249
184 250 calculating bids for ancestor 0f6b37dbe527
185 251 searching for copies back to rev 3
252 unmatched files in local:
253 d1/f3
254 d1/f4
255 unmatched files in other:
256 d2/f4
257 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
258 src: 'd1/f4' -> dst: 'd2/f4'
259 checking for directory renames
260 discovered dir src: 'd1/' -> dst: 'd2/'
261 pending file src: 'd1/f3' -> dst: 'd2/f3'
262 pending file src: 'd1/f4' -> dst: 'd2/f4'
186 263 resolving manifests
187 264 branchmerge: True, force: False, partial: False
188 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
265 ancestor: 0f6b37dbe527, local: e673248094b1+, remote: 6373bbfdae1d
266 d2/f3: remote directory rename - move from d1/f3 -> dm
267 d2/f4: remote directory rename, both created -> m
189 268 f1: remote unchanged -> k
190 269 f2: versions differ -> m
191 270
192 calculating bids for ancestor 40663881a6dd
271 calculating bids for ancestor d1d156401c1b
193 272 searching for copies back to rev 3
273 unmatched files in other:
274 d2/f4
275 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
276 src: 'd1/f4' -> dst: 'd2/f4'
277 checking for directory renames
278 discovered dir src: 'd1/' -> dst: 'd2/'
194 279 resolving manifests
195 280 branchmerge: True, force: False, partial: False
196 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
281 ancestor: d1d156401c1b, local: e673248094b1+, remote: 6373bbfdae1d
282 d1/f3: other deleted -> r
283 d1/f4: other deleted -> r
284 d2/f4: remote created -> g
197 285 f1: versions differ -> m
198 286 f2: remote is newer -> g
199 287
200 288 auction for merging merge bids
289 d1/f3: consensus for r
290 d1/f4: consensus for r
291 d2/f3: consensus for dm
292 d2/f4: picking 'get' action
201 293 f1: picking 'keep' action
202 294 f2: picking 'get' action
203 295 end of auction
204 296
297 d1/f3: other deleted -> r
298 removing d1/f3
299 d1/f4: other deleted -> r
300 removing d1/f4
301 d2/f4: remote created -> g
302 getting d2/f4
205 303 f2: remote is newer -> g
206 304 getting f2
207 305 f1: remote unchanged -> k
208 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
306 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
209 307 (branch merge, don't forget to commit)
210 308
211 $ f --dump *
309 $ f --dump --recurse *
310 d2: directory with 2 files
311 d2/f3:
312 >>>
313 0 base
314 <<<
315 d2/f4:
316 >>>
317 0 base
318 <<<
212 319 f1:
213 320 >>>
214 321 5 second change
@@ -222,57 +329,85 b' Verify how the output looks and and how '
222 329
223 330 $ hg up -qC
224 331 $ hg merge
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
226 333 (branch merge, don't forget to commit)
227 334
228 335 $ hg up -qC tip
229 336 $ hg merge -v
230 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
337 note: merging 6373bbfdae1d+ and e673248094b1 using bids from ancestors 0f6b37dbe527 and d1d156401c1b
231 338
232 339 calculating bids for ancestor 0f6b37dbe527
233 340 resolving manifests
234 341
235 calculating bids for ancestor 40663881a6dd
342 calculating bids for ancestor d1d156401c1b
236 343 resolving manifests
237 344
238 345 auction for merging merge bids
346 d2/f3: consensus for dg
347 d2/f4: consensus for m
239 348 f1: picking 'get' action
240 349 f2: picking 'keep' action
241 350 end of auction
242 351
243 352 getting f1
244 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
353 getting d1/f3 to d2/f3
354 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 355 (branch merge, don't forget to commit)
246 356
247 357 $ hg up -qC
248 358 $ hg merge -v --debug --config merge.preferancestor="*"
249 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
359 note: merging 6373bbfdae1d+ and e673248094b1 using bids from ancestors 0f6b37dbe527 and d1d156401c1b
250 360
251 361 calculating bids for ancestor 0f6b37dbe527
252 362 searching for copies back to rev 3
363 unmatched files in local:
364 d2/f4
365 unmatched files in other:
366 d1/f3
367 d1/f4
368 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
369 src: 'd1/f4' -> dst: 'd2/f4'
370 checking for directory renames
371 discovered dir src: 'd1/' -> dst: 'd2/'
372 pending file src: 'd1/f3' -> dst: 'd2/f3'
373 pending file src: 'd1/f4' -> dst: 'd2/f4'
253 374 resolving manifests
254 375 branchmerge: True, force: False, partial: False
255 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
376 ancestor: 0f6b37dbe527, local: 6373bbfdae1d+, remote: e673248094b1
377 d2/f3: local directory rename - get from d1/f3 -> dg
378 d2/f4: local directory rename, both created -> m
256 379 f1: remote is newer -> g
257 380 f2: versions differ -> m
258 381
259 calculating bids for ancestor 40663881a6dd
382 calculating bids for ancestor d1d156401c1b
260 383 searching for copies back to rev 3
384 unmatched files in local:
385 d2/f4
386 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
387 src: 'd1/f4' -> dst: 'd2/f4'
388 checking for directory renames
389 discovered dir src: 'd1/' -> dst: 'd2/'
261 390 resolving manifests
262 391 branchmerge: True, force: False, partial: False
263 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
392 ancestor: d1d156401c1b, local: 6373bbfdae1d+, remote: e673248094b1
264 393 f1: versions differ -> m
265 394 f2: remote unchanged -> k
266 395
267 396 auction for merging merge bids
397 d2/f3: consensus for dg
398 d2/f4: consensus for m
268 399 f1: picking 'get' action
269 400 f2: picking 'keep' action
270 401 end of auction
271 402
403 preserving d2/f4 for resolve of d2/f4
272 404 f1: remote is newer -> g
273 405 getting f1
274 406 f2: remote unchanged -> k
275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 d2/f3: local directory rename - get from d1/f3 -> dg
408 getting d1/f3 to d2/f3
409 d2/f4: local directory rename, both created -> m (premerge)
410 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 411 (branch merge, don't forget to commit)
277 412
278 413 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now