##// END OF EJS Templates
merge: unify merge and copy actions
Matt Mackall -
r3308:ecc1bf27 default
parent child Browse files
Show More
@@ -1,463 +1,443 b''
1 1 # merge.py - directory-level update/merge handling for Mercurial
2 2 #
3 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from node import *
9 9 from i18n import gettext as _
10 10 from demandload import *
11 11 demandload(globals(), "errno util os tempfile")
12 12
13 13 def filemerge(repo, fw, fo, fd, wctx, mctx, move):
14 14 """perform a 3-way merge in the working directory
15 15
16 16 fw = filename in the working directory and first parent
17 17 fo = filename in other parent
18 18 fd = destination filename
19 19 wctx, mctx = working and merge changecontexts
20 20 move = whether to move or copy the file to the destination
21 21
22 22 TODO:
23 23 if fw is copied in the working directory, we get confused
24 24 implement move and fd
25 25 """
26 26
27 27 def temp(prefix, ctx):
28 28 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
29 29 (fd, name) = tempfile.mkstemp(prefix=pre)
30 30 f = os.fdopen(fd, "wb")
31 31 repo.wwrite(ctx.path(), ctx.data(), f)
32 32 f.close()
33 33 return name
34 34
35 35 fcm = wctx.filectx(fw)
36 36 fco = mctx.filectx(fo)
37 37 fca = fcm.ancestor(fco)
38 38 if not fca:
39 39 fca = repo.filectx(fw, fileid=-1)
40 40 a = repo.wjoin(fw)
41 41 b = temp("base", fca)
42 42 c = temp("other", fco)
43 43
44 44 repo.ui.note(_("resolving %s\n") % fw)
45 45 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
46 46
47 47 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
48 48 or "hgmerge")
49 49 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
50 50 environ={'HG_FILE': fw,
51 51 'HG_MY_NODE': str(wctx.parents()[0]),
52 52 'HG_OTHER_NODE': str(mctx)})
53 53 if r:
54 54 repo.ui.warn(_("merging %s failed!\n") % fw)
55 55 else:
56 56 if fd != fw:
57 57 repo.ui.debug(_("copying %s to %s\n") % (fw, fd))
58 58 repo.wwrite(fd, repo.wread(fw))
59 59 if move:
60 60 repo.ui.debug(_("removing %s\n") % fw)
61 61 os.unlink(a)
62 62
63 63 os.unlink(b)
64 64 os.unlink(c)
65 65 return r
66 66
67 67 def checkunknown(repo, m2, wctx):
68 68 """
69 69 check for collisions between unknown files and files in m2
70 70 """
71 71 for f in wctx.unknown():
72 72 if f in m2:
73 73 if repo.file(f).cmp(m2[f], repo.wread(f)):
74 74 raise util.Abort(_("'%s' already exists in the working"
75 75 " dir and differs from remote") % f)
76 76
77 77 def forgetremoved(m2, wctx):
78 78 """
79 79 Forget removed files
80 80
81 81 If we're jumping between revisions (as opposed to merging), and if
82 82 neither the working directory nor the target rev has the file,
83 83 then we need to remove it from the dirstate, to prevent the
84 84 dirstate from listing the file when it is no longer in the
85 85 manifest.
86 86 """
87 87
88 88 action = []
89 89
90 90 for f in wctx.deleted() + wctx.removed():
91 91 if f not in m2:
92 92 action.append((f, "f"))
93 93
94 94 return action
95 95
96 96 def nonoverlap(d1, d2):
97 97 """
98 98 Return list of elements in d1 not in d2
99 99 """
100 100
101 101 l = []
102 102 for d in d1:
103 103 if d not in d2:
104 104 l.append(d)
105 105
106 106 l.sort()
107 107 return l
108 108
109 109 def findold(fctx, limit):
110 110 """
111 111 find files that path was copied from, back to linkrev limit
112 112 """
113 113
114 114 old = {}
115 115 orig = fctx.path()
116 116 visit = [fctx]
117 117 while visit:
118 118 fc = visit.pop()
119 119 if fc.rev() < limit:
120 120 continue
121 121 if fc.path() != orig and fc.path() not in old:
122 122 old[fc.path()] = 1
123 123 visit += fc.parents()
124 124
125 125 old = old.keys()
126 126 old.sort()
127 127 return old
128 128
129 129 def findcopies(repo, m1, m2, limit):
130 130 """
131 131 Find moves and copies between m1 and m2 back to limit linkrev
132 132 """
133 133
134 134 if not repo.ui.config("merge", "followcopies"):
135 135 return {}
136 136
137 137 # avoid silly behavior for update from empty dir
138 138 if not m1:
139 139 return {}
140 140
141 141 dcopies = repo.dirstate.copies()
142 142 copy = {}
143 143 match = {}
144 144 u1 = nonoverlap(m1, m2)
145 145 u2 = nonoverlap(m2, m1)
146 146 ctx = util.cachefunc(lambda f,n: repo.filectx(f, fileid=n[:20]))
147 147
148 148 def checkpair(c, f2, man):
149 149 ''' check if an apparent pair actually matches '''
150 150 c2 = ctx(f2, man[f2])
151 151 ca = c.ancestor(c2)
152 152 if ca and ca.path() == c.path() or ca.path() == c2.path():
153 153 copy[c.path()] = f2
154 154 copy[f2] = c.path()
155 155
156 156 for f in u1:
157 157 c = ctx(dcopies.get(f, f), m1[f])
158 158 for of in findold(c, limit):
159 159 if of in m2:
160 160 checkpair(c, of, m2)
161 161 else:
162 162 match.setdefault(of, []).append(f)
163 163
164 164 for f in u2:
165 165 c = ctx(f, m2[f])
166 166 for of in findold(c, limit):
167 167 if of in m1:
168 168 checkpair(c, of, m1)
169 169 elif of in match:
170 170 for mf in match[of]:
171 171 checkpair(c, mf, m1)
172 172
173 173 return copy
174 174
175 175 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
176 176 """
177 177 Merge manifest m1 with m2 using ancestor ma and generate merge action list
178 178 """
179 179
180 180 m1 = p1.manifest()
181 181 m2 = p2.manifest()
182 182 ma = pa.manifest()
183 183 backwards = (pa == p2)
184 184
185 185 def fmerge(f, f2=None, fa=None):
186 186 """merge executable flags"""
187 187 if not f2:
188 188 f2 = f
189 189 fa = f
190 190 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
191 191 return ((a^b) | (a^c)) ^ a
192 192
193 193 action = []
194 194
195 195 def act(msg, m, f, *args):
196 196 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
197 197 action.append((f, m) + args)
198 198
199 199 copy = {}
200 200 if not (backwards or overwrite):
201 201 copy = findcopies(repo, m1, m2, pa.rev())
202 202
203 203 # Compare manifests
204 204 for f, n in m1.iteritems():
205 205 if partial and not partial(f):
206 206 continue
207 207 if f in m2:
208 208 # are files different?
209 209 if n != m2[f]:
210 210 a = ma.get(f, nullid)
211 211 # are both different from the ancestor?
212 212 if not overwrite and n != a and m2[f] != a:
213 act("versions differ", "m", f, fmerge(f))
213 act("versions differ", "m", f, f, f, fmerge(f), False)
214 214 # are we clobbering?
215 215 # is remote's version newer?
216 216 # or are we going back in time and clean?
217 217 elif overwrite or m2[f] != a or (backwards and not n[20:]):
218 218 act("remote is newer", "g", f, m2.execf(f))
219 219 # local is newer, not overwrite, check mode bits
220 220 elif fmerge(f) != m1.execf(f):
221 221 act("update permissions", "e", f, m2.execf(f))
222 222 # contents same, check mode bits
223 223 elif m1.execf(f) != m2.execf(f):
224 224 if overwrite or fmerge(f) != m1.execf(f):
225 225 act("update permissions", "e", f, m2.execf(f))
226 226 elif f in copy:
227 227 f2 = copy[f]
228 228 if f in ma: # case 3,20 A/B/A
229 act("remote moved", "c",
230 f, f2, f2, fmerge(f, f2, f), True)
229 act("remote moved", "m", f, f2, f2, fmerge(f, f2, f), True)
231 230 else:
232 231 if f2 in m1: # case 2 A,B/B/B
233 act("local copied", "c",
232 act("local copied", "m",
234 233 f, f2, f, fmerge(f, f2, f2), False)
235 234 else: # case 4,21 A/B/B
236 act("local moved", "c",
235 act("local moved", "m",
237 236 f, f2, f, fmerge(f, f2, f2), False)
238 237 elif f in ma:
239 238 if n != ma[f] and not overwrite:
240 239 if repo.ui.prompt(
241 240 (_(" local changed %s which remote deleted\n") % f) +
242 241 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
243 242 act("prompt delete", "r", f)
244 243 else:
245 244 act("other deleted", "r", f)
246 245 else:
247 246 # file is created on branch or in working directory
248 247 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
249 248 act("remote deleted", "r", f)
250 249
251 250 for f, n in m2.iteritems():
252 251 if partial and not partial(f):
253 252 continue
254 253 if f in m1:
255 254 continue
256 255 if f in copy:
257 256 f2 = copy[f]
258 257 if f2 not in m2: # already seen
259 258 continue
260 259 # rename case 1, A/A,B/A
261 act("remote copied", "c", f2, f, f, fmerge(f2, f, f2), False)
260 act("remote copied", "m", f2, f, f, fmerge(f2, f, f2), False)
262 261 elif f in ma:
263 262 if overwrite or backwards:
264 263 act("recreating", "g", f, m2.execf(f))
265 264 elif n != ma[f]:
266 265 if repo.ui.prompt(
267 266 (_("remote changed %s which local deleted\n") % f) +
268 267 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
269 268 act("prompt recreating", "g", f, m2.execf(f))
270 269 else:
271 270 act("remote created", "g", f, m2.execf(f))
272 271
273 272 return action
274 273
275 274 def applyupdates(repo, action, wctx, mctx):
276 275 updated, merged, removed, unresolved = 0, 0, 0, 0
277 276 action.sort()
278 277 for a in action:
279 278 f, m = a[:2]
280 279 if f[0] == "/":
281 280 continue
282 281 if m == "r": # remove
283 282 repo.ui.note(_("removing %s\n") % f)
284 283 util.audit_path(f)
285 284 try:
286 285 util.unlink(repo.wjoin(f))
287 286 except OSError, inst:
288 287 if inst.errno != errno.ENOENT:
289 288 repo.ui.warn(_("update failed to remove %s: %s!\n") %
290 289 (f, inst.strerror))
291 290 removed +=1
292 elif m == "c": # copy
291 elif m == "m": # merge
293 292 f2, fd, flag, move = a[2:]
294 repo.ui.status(_("merging %s and %s to %s\n") % (f, f2, fd))
293 if f != f2:
294 repo.ui.status(_("merging %s and %s to %s\n") % (f, f2, fd))
295 else:
296 repo.ui.status(_("merging %s\n") % f)
295 297 if filemerge(repo, f, f2, fd, wctx, mctx, move):
296 298 unresolved += 1
297 299 util.set_exec(repo.wjoin(fd), flag)
298 300 merged += 1
299 elif m == "m": # merge
300 flag = a[2]
301 repo.ui.status(_("merging %s\n") % f)
302 if filemerge(repo, f, f, f, wctx, mctx, False):
303 unresolved += 1
304 util.set_exec(repo.wjoin(f), flag)
305 merged += 1
306 301 elif m == "g": # get
307 302 flag = a[2]
308 303 repo.ui.note(_("getting %s\n") % f)
309 304 t = mctx.filectx(f).data()
310 305 repo.wwrite(f, t)
311 306 util.set_exec(repo.wjoin(f), flag)
312 307 updated += 1
313 308 elif m == "e": # exec
314 309 flag = a[2]
315 310 util.set_exec(repo.wjoin(f), flag)
316 311
317 312 return updated, merged, removed, unresolved
318 313
319 314 def recordupdates(repo, action, branchmerge, mctx):
320 315 for a in action:
321 316 f, m = a[:2]
322 317 if m == "r": # remove
323 318 if branchmerge:
324 319 repo.dirstate.update([f], 'r')
325 320 else:
326 321 repo.dirstate.forget([f])
327 322 elif m == "f": # forget
328 323 repo.dirstate.forget([f])
329 324 elif m == "g": # get
330 325 if branchmerge:
331 326 repo.dirstate.update([f], 'n', st_mtime=-1)
332 327 else:
333 328 repo.dirstate.update([f], 'n')
334 329 elif m == "m": # merge
335 flag = a[2]
336 if branchmerge:
337 # We've done a branch merge, mark this file as merged
338 # so that we properly record the merger later
339 repo.dirstate.update([f], 'm')
340 else:
341 # We've update-merged a locally modified file, so
342 # we set the dirstate to emulate a normal checkout
343 # of that file some time in the past. Thus our
344 # merge will appear as a normal local file
345 # modification.
346 fl = repo.file(f)
347 f_len = mctx.filectx(f).size()
348 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
349 elif m == "c": # copy
350 330 f2, fd, flag, move = a[2:]
351 331 if branchmerge:
352 332 # We've done a branch merge, mark this file as merged
353 333 # so that we properly record the merger later
354 334 repo.dirstate.update([fd], 'm')
355 335 else:
356 336 # We've update-merged a locally modified file, so
357 337 # we set the dirstate to emulate a normal checkout
358 338 # of that file some time in the past. Thus our
359 339 # merge will appear as a normal local file
360 340 # modification.
361 fl = repo.file(f)
362 341 f_len = mctx.filectx(f).size()
363 342 repo.dirstate.update([fd], 'n', st_size=f_len, st_mtime=-1)
364 if move:
365 repo.dirstate.update([f], 'r')
366 if f != fd:
367 repo.dirstate.copy(f, fd)
368 else:
369 repo.dirstate.copy(f2, fd)
343 if f != f2: # copy/rename
344 if move:
345 repo.dirstate.update([f], 'r')
346 if f != fd:
347 repo.dirstate.copy(f, fd)
348 else:
349 repo.dirstate.copy(f2, fd)
370 350
371 351 def update(repo, node, branchmerge=False, force=False, partial=None,
372 352 wlock=None, show_stats=True, remind=True):
373 353
374 354 overwrite = force and not branchmerge
375 355 forcemerge = force and branchmerge
376 356
377 357 if not wlock:
378 358 wlock = repo.wlock()
379 359
380 360 ### check phase
381 361
382 362 wc = repo.workingctx()
383 363 pl = wc.parents()
384 364 if not overwrite and len(pl) > 1:
385 365 raise util.Abort(_("outstanding uncommitted merges"))
386 366
387 367 p1, p2 = pl[0], repo.changectx(node)
388 368 pa = p1.ancestor(p2)
389 369
390 370 # is there a linear path from p1 to p2?
391 371 if pa == p1 or pa == p2:
392 372 if branchmerge:
393 373 raise util.Abort(_("there is nothing to merge, just use "
394 374 "'hg update' or look at 'hg heads'"))
395 375 elif not (overwrite or branchmerge):
396 376 raise util.Abort(_("update spans branches, use 'hg merge' "
397 377 "or 'hg update -C' to lose changes"))
398 378
399 379 if branchmerge and not forcemerge:
400 380 if wc.modified() or wc.added() or wc.removed():
401 381 raise util.Abort(_("outstanding uncommitted changes"))
402 382
403 383 m1 = wc.manifest()
404 384 m2 = p2.manifest()
405 385
406 386 # resolve the manifest to determine which files
407 387 # we care about merging
408 388 repo.ui.note(_("resolving manifests\n"))
409 389 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
410 390 (overwrite, branchmerge, bool(partial)))
411 391 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (p1, p2, pa))
412 392
413 393 action = []
414 394
415 395 if not force:
416 396 checkunknown(repo, m2, wc)
417 397 if not branchmerge:
418 398 action += forgetremoved(m2, wc)
419 399
420 400 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
421 401
422 402 ### apply phase
423 403
424 404 if not branchmerge:
425 405 # just jump to the new rev
426 406 fp1, fp2, xp1, xp2 = p2.node(), nullid, str(p2), ''
427 407 else:
428 408 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
429 409
430 410 if not partial:
431 411 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
432 412
433 413 updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2)
434 414
435 415 # update dirstate
436 416 if not partial:
437 417 recordupdates(repo, action, branchmerge, p2)
438 418 repo.dirstate.setparents(fp1, fp2)
439 419 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
440 420
441 421 if show_stats:
442 422 stats = ((updated, _("updated")),
443 423 (merged - unresolved, _("merged")),
444 424 (removed, _("removed")),
445 425 (unresolved, _("unresolved")))
446 426 note = ", ".join([_("%d files %s") % s for s in stats])
447 427 repo.ui.status("%s\n" % note)
448 428 if not partial:
449 429 if branchmerge:
450 430 if unresolved:
451 431 repo.ui.status(_("There are unresolved merges,"
452 432 " you can redo the full merge using:\n"
453 433 " hg update -C %s\n"
454 434 " hg merge %s\n"
455 435 % (p1.rev(), p2.rev())))
456 436 elif remind:
457 437 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
458 438 elif unresolved:
459 439 repo.ui.status(_("There are unresolved merges with"
460 440 " locally modified files.\n"))
461 441
462 442 return unresolved
463 443
@@ -1,26 +1,26 b''
1 1 checkout
2 2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 3 merge
4 4 resolving manifests
5 5 overwrite None branchmerge True partial False
6 6 ancestor f26ec4fc3fa3 local 8e765a822af2 remote af1939970a1c
7 a: remote moved -> c
7 a: remote moved -> m
8 8 b2: remote created -> g
9 9 merging a and b to b
10 10 resolving a
11 11 my a@. other b@8e765a822af2 ancestor a@af1939970a1c
12 12 copying a to b
13 13 removing a
14 14 getting b2
15 15 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
16 16 (branch merge, don't forget to commit)
17 17 M b
18 18 a
19 19 M b2
20 20 R a
21 21 C c2
22 22 blahblah
23 23 rev offset length base linkrev nodeid p1 p2
24 24 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
25 25 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
26 26 renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
@@ -1,463 +1,463 b''
1 1 --------------
2 2 test L:up a R:nc a b W: - 1 get local a to b
3 3 --------------
4 4 resolving manifests
5 5 overwrite None branchmerge True partial False
6 6 ancestor e300d1c794ec local 735846fee2d7 remote 924404dff337
7 7 rev: versions differ -> m
8 a: remote copied -> c
8 a: remote copied -> m
9 9 merging a and b to b
10 10 resolving a
11 11 my a@. other b@735846fee2d7 ancestor a@924404dff337
12 12 copying a to b
13 13 merging rev
14 14 resolving rev
15 15 my rev@. other rev@735846fee2d7 ancestor rev@924404dff337
16 16 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
17 17 (branch merge, don't forget to commit)
18 18 --------------
19 19 M a
20 20 M b
21 21 a
22 22 --------------
23 23
24 24 --------------
25 25 test L:nc a b R:up a W: - 2 get rem change to a and b
26 26 --------------
27 27 resolving manifests
28 28 overwrite None branchmerge True partial False
29 29 ancestor ac809aeed39a local f4db7e329e71 remote 924404dff337
30 30 a: remote is newer -> g
31 b: local copied -> c
31 b: local copied -> m
32 32 rev: versions differ -> m
33 33 getting a
34 34 merging b and a to b
35 35 resolving b
36 36 my b@. other a@f4db7e329e71 ancestor a@924404dff337
37 37 merging rev
38 38 resolving rev
39 39 my rev@. other rev@f4db7e329e71 ancestor rev@924404dff337
40 40 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
41 41 (branch merge, don't forget to commit)
42 42 --------------
43 43 M a
44 44 M b
45 45 a
46 46 --------------
47 47
48 48 --------------
49 49 test L:up a R:nm a b W: - 3 get local a change to b, remove a
50 50 --------------
51 51 resolving manifests
52 52 overwrite None branchmerge True partial False
53 53 ancestor e300d1c794ec local e03727d2d66b remote 924404dff337
54 a: remote moved -> c
54 a: remote moved -> m
55 55 rev: versions differ -> m
56 56 merging a and b to b
57 57 resolving a
58 58 my a@. other b@e03727d2d66b ancestor a@924404dff337
59 59 copying a to b
60 60 removing a
61 61 merging rev
62 62 resolving rev
63 63 my rev@. other rev@e03727d2d66b ancestor rev@924404dff337
64 64 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
65 65 (branch merge, don't forget to commit)
66 66 --------------
67 67 M b
68 68 a
69 69 --------------
70 70
71 71 --------------
72 72 test L:nm a b R:up a W: - 4 get remote change to b
73 73 --------------
74 74 resolving manifests
75 75 overwrite None branchmerge True partial False
76 76 ancestor ecf3cb2a4219 local f4db7e329e71 remote 924404dff337
77 b: local moved -> c
77 b: local moved -> m
78 78 rev: versions differ -> m
79 79 merging b and a to b
80 80 resolving b
81 81 my b@. other a@f4db7e329e71 ancestor a@924404dff337
82 82 merging rev
83 83 resolving rev
84 84 my rev@. other rev@f4db7e329e71 ancestor rev@924404dff337
85 85 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
86 86 (branch merge, don't forget to commit)
87 87 --------------
88 88 M b
89 89 a
90 90 --------------
91 91
92 92 --------------
93 93 test L: R:nc a b W: - 5 get b
94 94 --------------
95 95 resolving manifests
96 96 overwrite None branchmerge True partial False
97 97 ancestor 94b33a1b7f2d local 735846fee2d7 remote 924404dff337
98 98 rev: versions differ -> m
99 a: remote copied -> c
99 a: remote copied -> m
100 100 merging a and b to b
101 101 resolving a
102 102 my a@. other b@735846fee2d7 ancestor a@924404dff337
103 103 copying a to b
104 104 merging rev
105 105 resolving rev
106 106 my rev@. other rev@735846fee2d7 ancestor rev@924404dff337
107 107 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
108 108 (branch merge, don't forget to commit)
109 109 --------------
110 110 M a
111 111 M b
112 112 a
113 113 --------------
114 114
115 115 --------------
116 116 test L:nc a b R: W: - 6 nothing
117 117 --------------
118 118 resolving manifests
119 119 overwrite None branchmerge True partial False
120 120 ancestor ac809aeed39a local 97c705ade336 remote 924404dff337
121 b: local copied -> c
121 b: local copied -> m
122 122 rev: versions differ -> m
123 123 merging b and a to b
124 124 resolving b
125 125 my b@. other a@97c705ade336 ancestor a@924404dff337
126 126 merging rev
127 127 resolving rev
128 128 my rev@. other rev@97c705ade336 ancestor rev@924404dff337
129 129 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
130 130 (branch merge, don't forget to commit)
131 131 --------------
132 132 M b
133 133 a
134 134 C a
135 135 --------------
136 136
137 137 --------------
138 138 test L: R:nm a b W: - 7 get b
139 139 --------------
140 140 resolving manifests
141 141 overwrite None branchmerge True partial False
142 142 ancestor 94b33a1b7f2d local e03727d2d66b remote 924404dff337
143 a: remote moved -> c
143 a: remote moved -> m
144 144 rev: versions differ -> m
145 145 merging a and b to b
146 146 resolving a
147 147 my a@. other b@e03727d2d66b ancestor a@924404dff337
148 148 copying a to b
149 149 removing a
150 150 merging rev
151 151 resolving rev
152 152 my rev@. other rev@e03727d2d66b ancestor rev@924404dff337
153 153 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
154 154 (branch merge, don't forget to commit)
155 155 --------------
156 156 M b
157 157 a
158 158 --------------
159 159
160 160 --------------
161 161 test L:nm a b R: W: - 8 nothing
162 162 --------------
163 163 resolving manifests
164 164 overwrite None branchmerge True partial False
165 165 ancestor ecf3cb2a4219 local 97c705ade336 remote 924404dff337
166 b: local moved -> c
166 b: local moved -> m
167 167 rev: versions differ -> m
168 168 merging b and a to b
169 169 resolving b
170 170 my b@. other a@97c705ade336 ancestor a@924404dff337
171 171 merging rev
172 172 resolving rev
173 173 my rev@. other rev@97c705ade336 ancestor rev@924404dff337
174 174 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
175 175 (branch merge, don't forget to commit)
176 176 --------------
177 177 M b
178 178 a
179 179 --------------
180 180
181 181 --------------
182 182 test L:um a b R:um a b W: - 9 do merge with ancestor in a
183 183 --------------
184 184 resolving manifests
185 185 overwrite None branchmerge True partial False
186 186 ancestor ec03c2ca8642 local 79cc6877a3b7 remote 924404dff337
187 187 b: versions differ -> m
188 188 rev: versions differ -> m
189 189 merging b
190 190 resolving b
191 191 my b@. other b@79cc6877a3b7 ancestor a@924404dff337
192 192 merging rev
193 193 resolving rev
194 194 my rev@. other rev@79cc6877a3b7 ancestor rev@924404dff337
195 195 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
196 196 (branch merge, don't forget to commit)
197 197 --------------
198 198 M b
199 199 --------------
200 200
201 201 --------------
202 202 test L:nm a b R:nm a c W: - 11 get c, keep b
203 203 --------------
204 204 resolving manifests
205 205 overwrite None branchmerge True partial False
206 206 ancestor ecf3cb2a4219 local e6abcc1a30c2 remote 924404dff337
207 207 rev: versions differ -> m
208 208 c: remote created -> g
209 209 getting c
210 210 merging rev
211 211 resolving rev
212 212 my rev@. other rev@e6abcc1a30c2 ancestor rev@924404dff337
213 213 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
214 214 (branch merge, don't forget to commit)
215 215 --------------
216 216 M c
217 217 C b
218 218 --------------
219 219
220 220 --------------
221 221 test L:nc a b R:up b W: - 12 merge b no ancestor
222 222 --------------
223 223 resolving manifests
224 224 overwrite None branchmerge True partial False
225 225 ancestor ac809aeed39a local af30c7647fc7 remote 924404dff337
226 226 b: versions differ -> m
227 227 rev: versions differ -> m
228 228 merging b
229 229 resolving b
230 230 my b@. other b@af30c7647fc7 ancestor b@000000000000
231 231 merging rev
232 232 resolving rev
233 233 my rev@. other rev@af30c7647fc7 ancestor rev@924404dff337
234 234 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
235 235 (branch merge, don't forget to commit)
236 236 --------------
237 237 M b
238 238 C a
239 239 --------------
240 240
241 241 --------------
242 242 test L:up b R:nm a b W: - 13 merge b no ancestor
243 243 --------------
244 244 resolving manifests
245 245 overwrite None branchmerge True partial False
246 246 ancestor 59318016310c local e03727d2d66b remote 924404dff337
247 247 a: other deleted -> r
248 248 b: versions differ -> m
249 249 rev: versions differ -> m
250 250 removing a
251 251 merging b
252 252 resolving b
253 253 my b@. other b@e03727d2d66b ancestor b@000000000000
254 254 merging rev
255 255 resolving rev
256 256 my rev@. other rev@e03727d2d66b ancestor rev@924404dff337
257 257 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
258 258 (branch merge, don't forget to commit)
259 259 --------------
260 260 M b
261 261 --------------
262 262
263 263 --------------
264 264 test L:nc a b R:up a b W: - 14 merge b no ancestor
265 265 --------------
266 266 resolving manifests
267 267 overwrite None branchmerge True partial False
268 268 ancestor ac809aeed39a local 8dbce441892a remote 924404dff337
269 269 a: remote is newer -> g
270 270 b: versions differ -> m
271 271 rev: versions differ -> m
272 272 getting a
273 273 merging b
274 274 resolving b
275 275 my b@. other b@8dbce441892a ancestor b@000000000000
276 276 merging rev
277 277 resolving rev
278 278 my rev@. other rev@8dbce441892a ancestor rev@924404dff337
279 279 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
280 280 (branch merge, don't forget to commit)
281 281 --------------
282 282 M a
283 283 M b
284 284 --------------
285 285
286 286 --------------
287 287 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
288 288 --------------
289 289 resolving manifests
290 290 overwrite None branchmerge True partial False
291 291 ancestor 59318016310c local e03727d2d66b remote 924404dff337
292 292 a: other deleted -> r
293 293 b: versions differ -> m
294 294 rev: versions differ -> m
295 295 removing a
296 296 merging b
297 297 resolving b
298 298 my b@. other b@e03727d2d66b ancestor b@000000000000
299 299 merging rev
300 300 resolving rev
301 301 my rev@. other rev@e03727d2d66b ancestor rev@924404dff337
302 302 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
303 303 (branch merge, don't forget to commit)
304 304 --------------
305 305 M b
306 306 --------------
307 307
308 308 --------------
309 309 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
310 310 --------------
311 311 resolving manifests
312 312 overwrite None branchmerge True partial False
313 313 ancestor ac809aeed39a local 8dbce441892a remote 924404dff337
314 314 a: remote is newer -> g
315 315 b: versions differ -> m
316 316 rev: versions differ -> m
317 317 getting a
318 318 merging b
319 319 resolving b
320 320 my b@. other b@8dbce441892a ancestor b@000000000000
321 321 merging rev
322 322 resolving rev
323 323 my rev@. other rev@8dbce441892a ancestor rev@924404dff337
324 324 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
325 325 (branch merge, don't forget to commit)
326 326 --------------
327 327 M a
328 328 M b
329 329 --------------
330 330
331 331 --------------
332 332 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
333 333 --------------
334 334 resolving manifests
335 335 overwrite None branchmerge True partial False
336 336 ancestor 0b76e65c8289 local 735846fee2d7 remote 924404dff337
337 337 b: versions differ -> m
338 338 rev: versions differ -> m
339 339 merging b
340 340 resolving b
341 341 my b@. other b@735846fee2d7 ancestor b@000000000000
342 342 merging rev
343 343 resolving rev
344 344 my rev@. other rev@735846fee2d7 ancestor rev@924404dff337
345 345 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
346 346 (branch merge, don't forget to commit)
347 347 --------------
348 348 M b
349 349 C a
350 350 --------------
351 351
352 352 --------------
353 353 test L:nm a b R:up a b W: - 18 merge b no ancestor
354 354 --------------
355 355 resolving manifests
356 356 overwrite None branchmerge True partial False
357 357 ancestor ecf3cb2a4219 local 8dbce441892a remote 924404dff337
358 358 b: versions differ -> m
359 359 rev: versions differ -> m
360 360 a: prompt recreating -> g
361 361 getting a
362 362 merging b
363 363 resolving b
364 364 my b@. other b@8dbce441892a ancestor b@000000000000
365 365 merging rev
366 366 resolving rev
367 367 my rev@. other rev@8dbce441892a ancestor rev@924404dff337
368 368 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
369 369 (branch merge, don't forget to commit)
370 370 --------------
371 371 M a
372 372 M b
373 373 --------------
374 374
375 375 --------------
376 376 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
377 377 --------------
378 378 resolving manifests
379 379 overwrite None branchmerge True partial False
380 380 ancestor 0b76e65c8289 local e03727d2d66b remote 924404dff337
381 381 b: versions differ -> m
382 382 rev: versions differ -> m
383 383 merging b
384 384 resolving b
385 385 my b@. other b@e03727d2d66b ancestor b@000000000000
386 386 merging rev
387 387 resolving rev
388 388 my rev@. other rev@e03727d2d66b ancestor rev@924404dff337
389 389 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
390 390 (branch merge, don't forget to commit)
391 391 --------------
392 392 M b
393 393 C a
394 394 --------------
395 395
396 396 --------------
397 397 test L:up a R:um a b W: - 20 merge a and b to b, remove a
398 398 --------------
399 399 resolving manifests
400 400 overwrite None branchmerge True partial False
401 401 ancestor e300d1c794ec local 79cc6877a3b7 remote 924404dff337
402 a: remote moved -> c
402 a: remote moved -> m
403 403 rev: versions differ -> m
404 404 merging a and b to b
405 405 resolving a
406 406 my a@. other b@79cc6877a3b7 ancestor a@924404dff337
407 407 copying a to b
408 408 removing a
409 409 merging rev
410 410 resolving rev
411 411 my rev@. other rev@79cc6877a3b7 ancestor rev@924404dff337
412 412 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
413 413 (branch merge, don't forget to commit)
414 414 --------------
415 415 M b
416 416 a
417 417 --------------
418 418
419 419 --------------
420 420 test L:um a b R:up a W: - 21 merge a and b to b
421 421 --------------
422 422 resolving manifests
423 423 overwrite None branchmerge True partial False
424 424 ancestor ec03c2ca8642 local f4db7e329e71 remote 924404dff337
425 b: local moved -> c
425 b: local moved -> m
426 426 rev: versions differ -> m
427 427 merging b and a to b
428 428 resolving b
429 429 my b@. other a@f4db7e329e71 ancestor a@924404dff337
430 430 merging rev
431 431 resolving rev
432 432 my rev@. other rev@f4db7e329e71 ancestor rev@924404dff337
433 433 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
434 434 (branch merge, don't forget to commit)
435 435 --------------
436 436 M b
437 437 a
438 438 --------------
439 439
440 440 --------------
441 441 test L:nm a b R:up a c W: - 23 get c, keep b
442 442 --------------
443 443 resolving manifests
444 444 overwrite None branchmerge True partial False
445 445 ancestor ecf3cb2a4219 local 2b958612230f remote 924404dff337
446 b: local moved -> c
446 b: local moved -> m
447 447 rev: versions differ -> m
448 448 c: remote created -> g
449 449 merging b and a to b
450 450 resolving b
451 451 my b@. other a@2b958612230f ancestor a@924404dff337
452 452 getting c
453 453 merging rev
454 454 resolving rev
455 455 my rev@. other rev@2b958612230f ancestor rev@924404dff337
456 456 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
457 457 (branch merge, don't forget to commit)
458 458 --------------
459 459 M b
460 460 a
461 461 M c
462 462 --------------
463 463
General Comments 0
You need to be logged in to leave comments. Login now