##// END OF EJS Templates
merge: warn user about divergent renames
Matt Mackall -
r4674:723e0ddb default
parent child Browse files
Show More
@@ -1,543 +1,564
1 1 # merge.py - directory-level update/merge handling for Mercurial
2 2 #
3 3 # Copyright 2006, 2007 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 _
10 10 import errno, util, os, tempfile, context
11 11
12 12 def filemerge(repo, fw, fo, wctx, mctx):
13 13 """perform a 3-way merge in the working directory
14 14
15 15 fw = filename in the working directory
16 16 fo = filename in other parent
17 17 wctx, mctx = working and merge changecontexts
18 18 """
19 19
20 20 def temp(prefix, ctx):
21 21 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
22 22 (fd, name) = tempfile.mkstemp(prefix=pre)
23 23 data = repo.wwritedata(ctx.path(), ctx.data())
24 24 f = os.fdopen(fd, "wb")
25 25 f.write(data)
26 26 f.close()
27 27 return name
28 28
29 29 fcm = wctx.filectx(fw)
30 30 fco = mctx.filectx(fo)
31 31
32 32 if not fco.cmp(fcm.data()): # files identical?
33 33 return None
34 34
35 35 fca = fcm.ancestor(fco)
36 36 if not fca:
37 37 fca = repo.filectx(fw, fileid=nullrev)
38 38 a = repo.wjoin(fw)
39 39 b = temp("base", fca)
40 40 c = temp("other", fco)
41 41
42 42 if fw != fo:
43 43 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
44 44 else:
45 45 repo.ui.status(_("merging %s\n") % fw)
46 46
47 47 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
48 48
49 49 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
50 50 or "hgmerge")
51 51 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
52 52 environ={'HG_FILE': fw,
53 53 'HG_MY_NODE': str(wctx.parents()[0]),
54 54 'HG_OTHER_NODE': str(mctx)})
55 55 if r:
56 56 repo.ui.warn(_("merging %s failed!\n") % fw)
57 57
58 58 os.unlink(b)
59 59 os.unlink(c)
60 60 return r
61 61
62 62 def checkunknown(wctx, mctx):
63 63 "check for collisions between unknown files and files in mctx"
64 64 man = mctx.manifest()
65 65 for f in wctx.unknown():
66 66 if f in man:
67 67 if mctx.filectx(f).cmp(wctx.filectx(f).data()):
68 68 raise util.Abort(_("untracked local file '%s' differs"
69 69 " from remote version") % f)
70 70
71 71 def checkcollision(mctx):
72 72 "check for case folding collisions in the destination context"
73 73 folded = {}
74 74 for fn in mctx.manifest():
75 75 fold = fn.lower()
76 76 if fold in folded:
77 77 raise util.Abort(_("case-folding collision between %s and %s")
78 78 % (fn, folded[fold]))
79 79 folded[fold] = fn
80 80
81 81 def forgetremoved(wctx, mctx):
82 82 """
83 83 Forget removed files
84 84
85 85 If we're jumping between revisions (as opposed to merging), and if
86 86 neither the working directory nor the target rev has the file,
87 87 then we need to remove it from the dirstate, to prevent the
88 88 dirstate from listing the file when it is no longer in the
89 89 manifest.
90 90 """
91 91
92 92 action = []
93 93 man = mctx.manifest()
94 94 for f in wctx.deleted() + wctx.removed():
95 95 if f not in man:
96 96 action.append((f, "f"))
97 97
98 98 return action
99 99
100 100 def findcopies(repo, m1, m2, ma, limit):
101 101 """
102 102 Find moves and copies between m1 and m2 back to limit linkrev
103 103 """
104 104
105 105 def nonoverlap(d1, d2, d3):
106 106 "Return list of elements in d1 not in d2 or d3"
107 107 l = [d for d in d1 if d not in d3 and d not in d2]
108 108 l.sort()
109 109 return l
110 110
111 111 def dirname(f):
112 112 s = f.rfind("/")
113 113 if s == -1:
114 114 return ""
115 115 return f[:s]
116 116
117 117 def dirs(files):
118 118 d = {}
119 119 for f in files:
120 120 f = dirname(f)
121 121 while f not in d:
122 122 d[f] = True
123 123 f = dirname(f)
124 124 return d
125 125
126 126 wctx = repo.workingctx()
127 127
128 128 def makectx(f, n):
129 129 if len(n) == 20:
130 130 return repo.filectx(f, fileid=n)
131 131 return wctx.filectx(f)
132 132 ctx = util.cachefunc(makectx)
133 133
134 134 def findold(fctx):
135 135 "find files that path was copied from, back to linkrev limit"
136 136 old = {}
137 137 seen = {}
138 138 orig = fctx.path()
139 139 visit = [fctx]
140 140 while visit:
141 141 fc = visit.pop()
142 142 s = str(fc)
143 143 if s in seen:
144 144 continue
145 145 seen[s] = 1
146 146 if fc.path() != orig and fc.path() not in old:
147 147 old[fc.path()] = 1
148 148 if fc.rev() < limit:
149 149 continue
150 150 visit += fc.parents()
151 151
152 152 old = old.keys()
153 153 old.sort()
154 154 return old
155 155
156 156 copy = {}
157 157 fullcopy = {}
158 diverge = {}
158 159
159 160 def checkcopies(c, man):
160 161 '''check possible copies for filectx c'''
161 162 for of in findold(c):
163 fullcopy[c.path()] = of # remember for dir rename detection
162 164 if of not in man: # original file not in other manifest?
165 if of in ma:
166 diverge.setdefault(of, []).append(c.path())
163 167 continue
164 168 c2 = ctx(of, man[of])
165 169 ca = c.ancestor(c2)
166 170 if not ca: # unrelated?
167 171 continue
168 172 # named changed on only one side?
169 173 if ca.path() == c.path() or ca.path() == c2.path():
170 fullcopy[c.path()] = of # remember for dir rename detection
171 174 if c == ca or c2 == ca: # no merge needed, ignore copy
172 175 continue
173 176 copy[c.path()] = of
174 177
175 178 if not repo.ui.configbool("merge", "followcopies", True):
176 return {}
179 return {}, {}
177 180
178 181 # avoid silly behavior for update from empty dir
179 182 if not m1 or not m2 or not ma:
180 return {}
183 return {}, {}
181 184
182 185 u1 = nonoverlap(m1, m2, ma)
183 186 u2 = nonoverlap(m2, m1, ma)
184 187
185 188 for f in u1:
186 189 checkcopies(ctx(f, m1[f]), m2)
187 190
188 191 for f in u2:
189 192 checkcopies(ctx(f, m2[f]), m1)
190 193
194 d2 = {}
195 for of, fl in diverge.items():
196 for f in fl:
197 fo = list(fl)
198 fo.remove(f)
199 d2[f] = (of, fo)
200 #diverge = d2
201
191 202 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True):
192 return copy
203 return copy, diverge
193 204
194 205 # generate a directory move map
195 206 d1, d2 = dirs(m1), dirs(m2)
196 207 invalid = {}
197 208 dirmove = {}
198 209
199 210 # examine each file copy for a potential directory move, which is
200 211 # when all the files in a directory are moved to a new directory
201 212 for dst, src in fullcopy.items():
202 213 dsrc, ddst = dirname(src), dirname(dst)
203 214 if dsrc in invalid:
204 215 # already seen to be uninteresting
205 216 continue
206 217 elif dsrc in d1 and ddst in d1:
207 218 # directory wasn't entirely moved locally
208 219 invalid[dsrc] = True
209 220 elif dsrc in d2 and ddst in d2:
210 221 # directory wasn't entirely moved remotely
211 222 invalid[dsrc] = True
212 223 elif dsrc in dirmove and dirmove[dsrc] != ddst:
213 224 # files from the same directory moved to two different places
214 225 invalid[dsrc] = True
215 226 else:
216 227 # looks good so far
217 228 dirmove[dsrc + "/"] = ddst + "/"
218 229
219 230 for i in invalid:
220 231 if i in dirmove:
221 232 del dirmove[i]
222 233
223 234 del d1, d2, invalid
224 235
225 236 if not dirmove:
226 return copy
237 return copy, diverge
227 238
228 239 # check unaccounted nonoverlapping files against directory moves
229 240 for f in u1 + u2:
230 241 if f not in fullcopy:
231 242 for d in dirmove:
232 243 if f.startswith(d):
233 244 # new file added in a directory that was moved, move it
234 245 copy[f] = dirmove[d] + f[len(d):]
235 246 break
236 247
237 return copy
248 return copy, diverge
238 249
239 250 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
240 251 """
241 252 Merge p1 and p2 with ancestor ma and generate merge action list
242 253
243 254 overwrite = whether we clobber working files
244 255 partial = function to filter file lists
245 256 """
246 257
247 258 repo.ui.note(_("resolving manifests\n"))
248 259 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
249 260 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
250 261
251 262 m1 = p1.manifest()
252 263 m2 = p2.manifest()
253 264 ma = pa.manifest()
254 265 backwards = (pa == p2)
255 266 action = []
256 267 copy = {}
268 diverge = {}
257 269
258 270 def fmerge(f, f2=None, fa=None):
259 271 """merge flags"""
260 272 if not f2:
261 273 f2 = f
262 274 fa = f
263 275 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
264 276 if ((a^b) | (a^c)) ^ a:
265 277 return 'x'
266 278 a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2)
267 279 if ((a^b) | (a^c)) ^ a:
268 280 return 'l'
269 281 return ''
270 282
271 283 def act(msg, m, f, *args):
272 284 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
273 285 action.append((f, m) + args)
274 286
275 287 if not (backwards or overwrite):
276 copy = findcopies(repo, m1, m2, ma, pa.rev())
288 copy, diverge = findcopies(repo, m1, m2, ma, pa.rev())
289
290 for of, fl in diverge.items():
291 act("divergent renames", "dr", of, fl)
292
277 293 copied = dict.fromkeys(copy.values())
278 294
279 295 # Compare manifests
280 296 for f, n in m1.iteritems():
281 297 if partial and not partial(f):
282 298 continue
283 299 if f in m2:
284 300 # are files different?
285 301 if n != m2[f]:
286 302 a = ma.get(f, nullid)
287 303 # are both different from the ancestor?
288 304 if not overwrite and n != a and m2[f] != a:
289 305 act("versions differ", "m", f, f, f, fmerge(f), False)
290 306 # are we clobbering?
291 307 # is remote's version newer?
292 308 # or are we going back in time and clean?
293 309 elif overwrite or m2[f] != a or (backwards and not n[20:]):
294 310 act("remote is newer", "g", f, m2.flags(f))
295 311 # local is newer, not overwrite, check mode bits
296 312 elif fmerge(f) != m1.flags(f):
297 313 act("update permissions", "e", f, m2.flags(f))
298 314 # contents same, check mode bits
299 315 elif m1.flags(f) != m2.flags(f):
300 316 if overwrite or fmerge(f) != m1.flags(f):
301 317 act("update permissions", "e", f, m2.flags(f))
302 318 elif f in copied:
303 319 continue
304 320 elif f in copy:
305 321 f2 = copy[f]
306 322 if f2 not in m2: # directory rename
307 323 act("remote renamed directory to " + f2, "d",
308 324 f, None, f2, m1.flags(f))
309 325 elif f2 in m1: # case 2 A,B/B/B
310 326 act("local copied to " + f2, "m",
311 327 f, f2, f, fmerge(f, f2, f2), False)
312 328 else: # case 4,21 A/B/B
313 329 act("local moved to " + f2, "m",
314 330 f, f2, f, fmerge(f, f2, f2), False)
315 331 elif f in ma:
316 332 if n != ma[f] and not overwrite:
317 333 if repo.ui.prompt(
318 334 (_(" local changed %s which remote deleted\n") % f) +
319 335 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
320 336 act("prompt delete", "r", f)
321 337 else:
322 338 act("other deleted", "r", f)
323 339 else:
324 340 # file is created on branch or in working directory
325 341 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
326 342 act("remote deleted", "r", f)
327 343
328 344 for f, n in m2.iteritems():
329 345 if partial and not partial(f):
330 346 continue
331 347 if f in m1:
332 348 continue
333 349 if f in copied:
334 350 continue
335 351 if f in copy:
336 352 f2 = copy[f]
337 353 if f2 not in m1: # directory rename
338 354 act("local renamed directory to " + f2, "d",
339 355 None, f, f2, m2.flags(f))
340 356 elif f2 in m2: # rename case 1, A/A,B/A
341 357 act("remote copied to " + f, "m",
342 358 f2, f, f, fmerge(f2, f, f2), False)
343 359 else: # case 3,20 A/B/A
344 360 act("remote moved to " + f, "m",
345 361 f2, f, f, fmerge(f2, f, f2), True)
346 362 elif f in ma:
347 363 if overwrite or backwards:
348 364 act("recreating", "g", f, m2.flags(f))
349 365 elif n != ma[f]:
350 366 if repo.ui.prompt(
351 367 (_("remote changed %s which local deleted\n") % f) +
352 368 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
353 369 act("prompt recreating", "g", f, m2.flags(f))
354 370 else:
355 371 act("remote created", "g", f, m2.flags(f))
356 372
357 373 return action
358 374
359 375 def applyupdates(repo, action, wctx, mctx):
360 376 "apply the merge action list to the working directory"
361 377
362 378 updated, merged, removed, unresolved = 0, 0, 0, 0
363 379 action.sort()
364 380 for a in action:
365 381 f, m = a[:2]
366 382 if f and f[0] == "/":
367 383 continue
368 384 if m == "r": # remove
369 385 repo.ui.note(_("removing %s\n") % f)
370 386 util.audit_path(f)
371 387 try:
372 388 util.unlink(repo.wjoin(f))
373 389 except OSError, inst:
374 390 if inst.errno != errno.ENOENT:
375 391 repo.ui.warn(_("update failed to remove %s: %s!\n") %
376 392 (f, inst.strerror))
377 393 removed += 1
378 394 elif m == "m": # merge
379 395 f2, fd, flags, move = a[2:]
380 396 r = filemerge(repo, f, f2, wctx, mctx)
381 397 if r > 0:
382 398 unresolved += 1
383 399 else:
384 400 if r is None:
385 401 updated += 1
386 402 else:
387 403 merged += 1
388 404 if f != fd:
389 405 repo.ui.debug(_("copying %s to %s\n") % (f, fd))
390 406 repo.wwrite(fd, repo.wread(f), flags)
391 407 if move:
392 408 repo.ui.debug(_("removing %s\n") % f)
393 409 os.unlink(repo.wjoin(f))
394 410 util.set_exec(repo.wjoin(fd), "x" in flags)
395 411 elif m == "g": # get
396 412 flags = a[2]
397 413 repo.ui.note(_("getting %s\n") % f)
398 414 t = mctx.filectx(f).data()
399 415 repo.wwrite(f, t, flags)
400 416 updated += 1
401 417 elif m == "d": # directory rename
402 418 f2, fd, flags = a[2:]
403 419 if f:
404 420 repo.ui.note(_("moving %s to %s\n") % (f, fd))
405 421 t = wctx.filectx(f).data()
406 422 repo.wwrite(fd, t, flags)
407 423 util.unlink(repo.wjoin(f))
408 424 if f2:
409 425 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
410 426 t = mctx.filectx(f2).data()
411 427 repo.wwrite(fd, t, flags)
412 428 updated += 1
429 elif m == "dr": # divergent renames
430 fl = a[2]
431 repo.ui.warn("warning: detected divergent renames of %s to:\n" % f)
432 for nf in fl:
433 repo.ui.warn(" %s\n" % nf)
413 434 elif m == "e": # exec
414 435 flags = a[2]
415 436 util.set_exec(repo.wjoin(f), flags)
416 437
417 438 return updated, merged, removed, unresolved
418 439
419 440 def recordupdates(repo, action, branchmerge):
420 441 "record merge actions to the dirstate"
421 442
422 443 for a in action:
423 444 f, m = a[:2]
424 445 if m == "r": # remove
425 446 if branchmerge:
426 447 repo.dirstate.update([f], 'r')
427 448 else:
428 449 repo.dirstate.forget([f])
429 450 elif m == "f": # forget
430 451 repo.dirstate.forget([f])
431 452 elif m == "g": # get
432 453 if branchmerge:
433 454 repo.dirstate.update([f], 'n', st_mtime=-1)
434 455 else:
435 456 repo.dirstate.update([f], 'n')
436 457 elif m == "m": # merge
437 458 f2, fd, flag, move = a[2:]
438 459 if branchmerge:
439 460 # We've done a branch merge, mark this file as merged
440 461 # so that we properly record the merger later
441 462 repo.dirstate.update([fd], 'm')
442 463 if f != f2: # copy/rename
443 464 if move:
444 465 repo.dirstate.update([f], 'r')
445 466 if f != fd:
446 467 repo.dirstate.copy(f, fd)
447 468 else:
448 469 repo.dirstate.copy(f2, fd)
449 470 else:
450 471 # We've update-merged a locally modified file, so
451 472 # we set the dirstate to emulate a normal checkout
452 473 # of that file some time in the past. Thus our
453 474 # merge will appear as a normal local file
454 475 # modification.
455 476 repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1)
456 477 if move:
457 478 repo.dirstate.forget([f])
458 479 elif m == "d": # directory rename
459 480 f2, fd, flag = a[2:]
460 481 if branchmerge:
461 482 repo.dirstate.update([fd], 'a')
462 483 if f:
463 484 repo.dirstate.update([f], 'r')
464 485 repo.dirstate.copy(f, fd)
465 486 if f2:
466 487 repo.dirstate.copy(f2, fd)
467 488 else:
468 489 repo.dirstate.update([fd], 'n')
469 490 if f:
470 491 repo.dirstate.forget([f])
471 492
472 493 def update(repo, node, branchmerge, force, partial, wlock):
473 494 """
474 495 Perform a merge between the working directory and the given node
475 496
476 497 branchmerge = whether to merge between branches
477 498 force = whether to force branch merging or file overwriting
478 499 partial = a function to filter file lists (dirstate not updated)
479 500 wlock = working dir lock, if already held
480 501 """
481 502
482 503 if not wlock:
483 504 wlock = repo.wlock()
484 505
485 506 wc = repo.workingctx()
486 507 if node is None:
487 508 # tip of current branch
488 509 try:
489 510 node = repo.branchtags()[wc.branch()]
490 511 except KeyError:
491 512 raise util.Abort(_("branch %s not found") % wc.branch())
492 513 overwrite = force and not branchmerge
493 514 forcemerge = force and branchmerge
494 515 pl = wc.parents()
495 516 p1, p2 = pl[0], repo.changectx(node)
496 517 pa = p1.ancestor(p2)
497 518 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
498 519 fastforward = False
499 520
500 521 ### check phase
501 522 if not overwrite and len(pl) > 1:
502 523 raise util.Abort(_("outstanding uncommitted merges"))
503 524 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
504 525 if branchmerge:
505 526 if p1.branch() != p2.branch():
506 527 fastforward = True
507 528 else:
508 529 raise util.Abort(_("there is nothing to merge, just use "
509 530 "'hg update' or look at 'hg heads'"))
510 531 elif not (overwrite or branchmerge):
511 532 raise util.Abort(_("update spans branches, use 'hg merge' "
512 533 "or 'hg update -C' to lose changes"))
513 534 if branchmerge and not forcemerge:
514 535 if wc.files():
515 536 raise util.Abort(_("outstanding uncommitted changes"))
516 537
517 538 ### calculate phase
518 539 action = []
519 540 if not force:
520 541 checkunknown(wc, p2)
521 542 if not util.checkfolding(repo.path):
522 543 checkcollision(p2)
523 544 if not branchmerge:
524 545 action += forgetremoved(wc, p2)
525 546 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
526 547
527 548 ### apply phase
528 549 if not branchmerge: # just jump to the new rev
529 550 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
530 551 if not partial:
531 552 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
532 553
533 554 stats = applyupdates(repo, action, wc, p2)
534 555
535 556 if not partial:
536 557 recordupdates(repo, action, branchmerge)
537 558 repo.dirstate.setparents(fp1, fp2)
538 559 if not branchmerge and not fastforward:
539 560 repo.dirstate.setbranch(p2.branch())
540 561 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
541 562
542 563 return stats
543 564
@@ -1,214 +1,217
1 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 3 rev offset length base linkrev nodeid p1 p2
4 4 0 0 3 0 0 362fef284ce2 000000000000 000000000000
5 5 1 3 5 1 1 125144f7e028 362fef284ce2 000000000000
6 6 2 8 7 2 2 4c982badb186 125144f7e028 000000000000
7 7 3 15 9 3 3 19b1fc555737 4c982badb186 000000000000
8 8 rev offset length base linkrev nodeid p1 p2
9 9 0 0 75 0 7 905359268f77 000000000000 000000000000
10 10 rev offset length base linkrev nodeid p1 p2
11 11 0 0 75 0 8 905359268f77 000000000000 000000000000
12 12 rev offset length base linkrev nodeid p1 p2
13 13 0 0 8 0 6 12ab3bcc5ea4 000000000000 000000000000
14 14 rev offset length base linkrev nodeid p1 p2
15 15 0 0 48 0 0 43eadb1d2d06 000000000000 000000000000
16 16 1 48 48 1 1 8b89697eba2c 43eadb1d2d06 000000000000
17 17 2 96 48 2 2 626a32663c2f 8b89697eba2c 000000000000
18 18 3 144 48 3 3 f54c32f13478 626a32663c2f 000000000000
19 19 4 192 58 3 6 de68e904d169 626a32663c2f 000000000000
20 20 5 250 68 3 7 3b45cc2ab868 de68e904d169 000000000000
21 21 6 318 54 6 8 24d86153a002 f54c32f13478 000000000000
22 22 checking changesets
23 23 checking manifests
24 24 crosschecking files in changesets and manifests
25 25 checking files
26 26 4 files, 9 changesets, 7 total revisions
27 27 searching for changes
28 28 adding changesets
29 29 adding manifests
30 30 adding file changes
31 31 added 1 changesets with 1 changes to 1 files
32 32 (run 'hg update' to get a working copy)
33 33 checking changesets
34 34 checking manifests
35 35 crosschecking files in changesets and manifests
36 36 checking files
37 37 1 files, 1 changesets, 1 total revisions
38 38 0:5649c9d34dd8
39 39 searching for changes
40 40 adding changesets
41 41 adding manifests
42 42 adding file changes
43 43 added 2 changesets with 2 changes to 1 files
44 44 (run 'hg update' to get a working copy)
45 45 checking changesets
46 46 checking manifests
47 47 crosschecking files in changesets and manifests
48 48 checking files
49 49 1 files, 2 changesets, 2 total revisions
50 50 1:10b2180f755b
51 51 searching for changes
52 52 adding changesets
53 53 adding manifests
54 54 adding file changes
55 55 added 3 changesets with 3 changes to 1 files
56 56 (run 'hg update' to get a working copy)
57 57 checking changesets
58 58 checking manifests
59 59 crosschecking files in changesets and manifests
60 60 checking files
61 61 1 files, 3 changesets, 3 total revisions
62 62 2:d62976ca1e50
63 63 searching for changes
64 64 adding changesets
65 65 adding manifests
66 66 adding file changes
67 67 added 4 changesets with 4 changes to 1 files
68 68 (run 'hg update' to get a working copy)
69 69 checking changesets
70 70 checking manifests
71 71 crosschecking files in changesets and manifests
72 72 checking files
73 73 1 files, 4 changesets, 4 total revisions
74 74 3:ac69c658229d
75 75 searching for changes
76 76 adding changesets
77 77 adding manifests
78 78 adding file changes
79 79 added 2 changesets with 2 changes to 1 files
80 80 (run 'hg update' to get a working copy)
81 81 checking changesets
82 82 checking manifests
83 83 crosschecking files in changesets and manifests
84 84 checking files
85 85 1 files, 2 changesets, 2 total revisions
86 86 1:5f4f3ceb285e
87 87 searching for changes
88 88 adding changesets
89 89 adding manifests
90 90 adding file changes
91 91 added 3 changesets with 3 changes to 1 files
92 92 (run 'hg update' to get a working copy)
93 93 checking changesets
94 94 checking manifests
95 95 crosschecking files in changesets and manifests
96 96 checking files
97 97 1 files, 3 changesets, 3 total revisions
98 98 2:024e4e7df376
99 99 searching for changes
100 100 adding changesets
101 101 adding manifests
102 102 adding file changes
103 103 added 4 changesets with 5 changes to 2 files
104 104 (run 'hg update' to get a working copy)
105 105 checking changesets
106 106 checking manifests
107 107 crosschecking files in changesets and manifests
108 108 checking files
109 109 2 files, 4 changesets, 5 total revisions
110 110 3:1e3f6b843bd6
111 111 searching for changes
112 112 adding changesets
113 113 adding manifests
114 114 adding file changes
115 115 added 5 changesets with 6 changes to 3 files
116 116 (run 'hg update' to get a working copy)
117 117 checking changesets
118 118 checking manifests
119 119 crosschecking files in changesets and manifests
120 120 checking files
121 121 3 files, 5 changesets, 6 total revisions
122 122 4:80fe151401c2
123 123 searching for changes
124 124 adding changesets
125 125 adding manifests
126 126 adding file changes
127 127 added 5 changesets with 5 changes to 2 files
128 128 (run 'hg update' to get a working copy)
129 129 checking changesets
130 130 checking manifests
131 131 crosschecking files in changesets and manifests
132 132 checking files
133 133 2 files, 5 changesets, 5 total revisions
134 134 4:836ac62537ab
135 135 pulling from ../test-7
136 136 searching for changes
137 137 adding changesets
138 138 adding manifests
139 139 adding file changes
140 140 added 4 changesets with 2 changes to 3 files (+1 heads)
141 141 (run 'hg heads' to see heads, 'hg merge' to merge)
142 142 checking changesets
143 143 checking manifests
144 144 crosschecking files in changesets and manifests
145 145 checking files
146 146 4 files, 9 changesets, 7 total revisions
147 147 rolling back last transaction
148 148 % should fail
149 149 abort: --base is incompatible with specifiying a destination
150 150 abort: repository default-push not found!
151 151 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
152 152 % 2
153 153 2:d62976ca1e50
154 154 adding changesets
155 155 abort: unknown parent ac69c658229d!
156 156 transaction abort!
157 157 rollback completed
158 158 % 2
159 159 2:d62976ca1e50
160 160 adding changesets
161 161 adding manifests
162 162 adding file changes
163 163 added 6 changesets with 4 changes to 4 files (+1 heads)
164 164 (run 'hg heads' to see heads, 'hg merge' to merge)
165 165 % 8
166 166 8:836ac62537ab
167 167 checking changesets
168 168 checking manifests
169 169 crosschecking files in changesets and manifests
170 170 checking files
171 171 4 files, 9 changesets, 7 total revisions
172 172 rolling back last transaction
173 173 % 2
174 174 2:d62976ca1e50
175 175 adding changesets
176 176 adding manifests
177 177 adding file changes
178 178 added 2 changesets with 2 changes to 2 files
179 179 (run 'hg update' to get a working copy)
180 180 % 4
181 181 4:836ac62537ab
182 182 checking changesets
183 183 checking manifests
184 184 crosschecking files in changesets and manifests
185 185 checking files
186 186 2 files, 5 changesets, 5 total revisions
187 187 rolling back last transaction
188 188 adding changesets
189 189 adding manifests
190 190 adding file changes
191 191 added 4 changesets with 3 changes to 3 files (+1 heads)
192 192 (run 'hg heads' to see heads, 'hg merge' to merge)
193 193 % 6
194 194 6:80fe151401c2
195 195 checking changesets
196 196 checking manifests
197 197 crosschecking files in changesets and manifests
198 198 checking files
199 199 3 files, 7 changesets, 6 total revisions
200 warning: detected divergent renames of afile to:
201 anotherfile
202 adifferentfile
200 203 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 204 (branch merge, don't forget to commit)
202 205 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 206 adding changesets
204 207 adding manifests
205 208 adding file changes
206 209 added 7 changesets with 4 changes to 4 files
207 210 (run 'hg update' to get a working copy)
208 211 % 9
209 212 9:607fe5912aad
210 213 checking changesets
211 214 checking manifests
212 215 crosschecking files in changesets and manifests
213 216 checking files
214 217 4 files, 10 changesets, 7 total revisions
@@ -1,25 +1,29
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 partial False
6 6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
7 a2: divergent renames -> dr
7 8 a: remote moved to b -> m
8 9 b2: remote created -> g
9 10 merging a and b
10 11 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
11 12 copying a to b
12 13 removing a
14 warning: detected divergent renames of a2 to:
15 c2
16 b2
13 17 getting b2
14 18 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
15 19 (branch merge, don't forget to commit)
16 20 M b
17 21 a
18 22 M b2
19 23 R a
20 24 C c2
21 25 blahblah
22 26 rev offset length base linkrev nodeid p1 p2
23 27 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
24 28 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
25 29 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
@@ -1,409 +1,413
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 partial False
6 6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
7 7 rev: versions differ -> m
8 8 a: remote copied to b -> m
9 9 merging a and b
10 10 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
11 11 copying a to b
12 12 merging rev
13 13 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
14 14 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
15 15 (branch merge, don't forget to commit)
16 16 --------------
17 17 M a
18 18 M b
19 19 a
20 20 --------------
21 21
22 22 --------------
23 23 test L:nc a b R:up a W: - 2 get rem change to a and b
24 24 --------------
25 25 resolving manifests
26 26 overwrite None partial False
27 27 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
28 28 a: remote is newer -> g
29 29 b: local copied to a -> m
30 30 rev: versions differ -> m
31 31 getting a
32 32 merging b and a
33 33 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
34 34 merging rev
35 35 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
36 36 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
37 37 (branch merge, don't forget to commit)
38 38 --------------
39 39 M a
40 40 M b
41 41 a
42 42 --------------
43 43
44 44 --------------
45 45 test L:up a R:nm a b W: - 3 get local a change to b, remove a
46 46 --------------
47 47 resolving manifests
48 48 overwrite None partial False
49 49 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
50 50 rev: versions differ -> m
51 51 a: remote moved to b -> m
52 52 merging a and b
53 53 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
54 54 copying a to b
55 55 removing a
56 56 merging rev
57 57 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
58 58 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
59 59 (branch merge, don't forget to commit)
60 60 --------------
61 61 M b
62 62 a
63 63 --------------
64 64
65 65 --------------
66 66 test L:nm a b R:up a W: - 4 get remote change to b
67 67 --------------
68 68 resolving manifests
69 69 overwrite None partial False
70 70 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
71 71 b: local moved to a -> m
72 72 rev: versions differ -> m
73 73 merging b and a
74 74 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
75 75 merging rev
76 76 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
77 77 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
78 78 (branch merge, don't forget to commit)
79 79 --------------
80 80 M b
81 81 a
82 82 --------------
83 83
84 84 --------------
85 85 test L: R:nc a b W: - 5 get b
86 86 --------------
87 87 resolving manifests
88 88 overwrite None partial False
89 89 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
90 90 rev: versions differ -> m
91 91 b: remote created -> g
92 92 getting b
93 93 merging rev
94 94 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
95 95 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
96 96 (branch merge, don't forget to commit)
97 97 --------------
98 98 M b
99 99 C a
100 100 --------------
101 101
102 102 --------------
103 103 test L:nc a b R: W: - 6 nothing
104 104 --------------
105 105 resolving manifests
106 106 overwrite None partial False
107 107 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
108 108 rev: versions differ -> m
109 109 merging rev
110 110 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
111 111 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
112 112 (branch merge, don't forget to commit)
113 113 --------------
114 114 C a
115 115 C b
116 116 --------------
117 117
118 118 --------------
119 119 test L: R:nm a b W: - 7 get b
120 120 --------------
121 121 resolving manifests
122 122 overwrite None partial False
123 123 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
124 124 a: other deleted -> r
125 125 rev: versions differ -> m
126 126 b: remote created -> g
127 127 removing a
128 128 getting b
129 129 merging rev
130 130 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
131 131 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
132 132 (branch merge, don't forget to commit)
133 133 --------------
134 134 M b
135 135 --------------
136 136
137 137 --------------
138 138 test L:nm a b R: W: - 8 nothing
139 139 --------------
140 140 resolving manifests
141 141 overwrite None partial False
142 142 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
143 143 rev: versions differ -> m
144 144 merging rev
145 145 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
146 146 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
147 147 (branch merge, don't forget to commit)
148 148 --------------
149 149 C b
150 150 --------------
151 151
152 152 --------------
153 153 test L:um a b R:um a b W: - 9 do merge with ancestor in a
154 154 --------------
155 155 resolving manifests
156 156 overwrite None partial False
157 157 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
158 158 b: versions differ -> m
159 159 rev: versions differ -> m
160 160 merging b
161 161 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
162 162 merging rev
163 163 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
164 164 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
165 165 (branch merge, don't forget to commit)
166 166 --------------
167 167 M b
168 168 --------------
169 169
170 170 --------------
171 171 test L:nm a b R:nm a c W: - 11 get c, keep b
172 172 --------------
173 173 resolving manifests
174 174 overwrite None partial False
175 175 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
176 a: divergent renames -> dr
176 177 rev: versions differ -> m
177 178 c: remote created -> g
179 warning: detected divergent renames of a to:
180 b
181 c
178 182 getting c
179 183 merging rev
180 184 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
181 185 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
182 186 (branch merge, don't forget to commit)
183 187 --------------
184 188 M c
185 189 C b
186 190 --------------
187 191
188 192 --------------
189 193 test L:nc a b R:up b W: - 12 merge b no ancestor
190 194 --------------
191 195 resolving manifests
192 196 overwrite None partial False
193 197 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
194 198 b: versions differ -> m
195 199 rev: versions differ -> m
196 200 merging b
197 201 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
198 202 merging rev
199 203 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
200 204 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
201 205 (branch merge, don't forget to commit)
202 206 --------------
203 207 M b
204 208 C a
205 209 --------------
206 210
207 211 --------------
208 212 test L:up b R:nm a b W: - 13 merge b no ancestor
209 213 --------------
210 214 resolving manifests
211 215 overwrite None partial False
212 216 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
213 217 a: other deleted -> r
214 218 b: versions differ -> m
215 219 rev: versions differ -> m
216 220 removing a
217 221 merging b
218 222 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
219 223 merging rev
220 224 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
221 225 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
222 226 (branch merge, don't forget to commit)
223 227 --------------
224 228 M b
225 229 --------------
226 230
227 231 --------------
228 232 test L:nc a b R:up a b W: - 14 merge b no ancestor
229 233 --------------
230 234 resolving manifests
231 235 overwrite None partial False
232 236 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
233 237 a: remote is newer -> g
234 238 b: versions differ -> m
235 239 rev: versions differ -> m
236 240 getting a
237 241 merging b
238 242 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
239 243 merging rev
240 244 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
241 245 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
242 246 (branch merge, don't forget to commit)
243 247 --------------
244 248 M a
245 249 M b
246 250 --------------
247 251
248 252 --------------
249 253 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
250 254 --------------
251 255 resolving manifests
252 256 overwrite None partial False
253 257 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
254 258 a: other deleted -> r
255 259 b: versions differ -> m
256 260 rev: versions differ -> m
257 261 removing a
258 262 merging b
259 263 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
260 264 merging rev
261 265 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
262 266 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
263 267 (branch merge, don't forget to commit)
264 268 --------------
265 269 M b
266 270 --------------
267 271
268 272 --------------
269 273 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
270 274 --------------
271 275 resolving manifests
272 276 overwrite None partial False
273 277 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
274 278 a: remote is newer -> g
275 279 b: versions differ -> m
276 280 rev: versions differ -> m
277 281 getting a
278 282 merging b
279 283 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
280 284 merging rev
281 285 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
282 286 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
283 287 (branch merge, don't forget to commit)
284 288 --------------
285 289 M a
286 290 M b
287 291 --------------
288 292
289 293 --------------
290 294 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
291 295 --------------
292 296 resolving manifests
293 297 overwrite None partial False
294 298 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
295 299 b: versions differ -> m
296 300 rev: versions differ -> m
297 301 merging b
298 302 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
299 303 merging rev
300 304 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
301 305 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
302 306 (branch merge, don't forget to commit)
303 307 --------------
304 308 M b
305 309 C a
306 310 --------------
307 311
308 312 --------------
309 313 test L:nm a b R:up a b W: - 18 merge b no ancestor
310 314 --------------
311 315 resolving manifests
312 316 overwrite None partial False
313 317 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
314 318 b: versions differ -> m
315 319 rev: versions differ -> m
316 320 a: prompt recreating -> g
317 321 getting a
318 322 merging b
319 323 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
320 324 merging rev
321 325 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
322 326 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
323 327 (branch merge, don't forget to commit)
324 328 --------------
325 329 M a
326 330 M b
327 331 --------------
328 332
329 333 --------------
330 334 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
331 335 --------------
332 336 resolving manifests
333 337 overwrite None partial False
334 338 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
335 339 b: versions differ -> m
336 340 rev: versions differ -> m
337 341 merging b
338 342 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
339 343 merging rev
340 344 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
341 345 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
342 346 (branch merge, don't forget to commit)
343 347 --------------
344 348 M b
345 349 C a
346 350 --------------
347 351
348 352 --------------
349 353 test L:up a R:um a b W: - 20 merge a and b to b, remove a
350 354 --------------
351 355 resolving manifests
352 356 overwrite None partial False
353 357 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
354 358 rev: versions differ -> m
355 359 a: remote moved to b -> m
356 360 merging a and b
357 361 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
358 362 copying a to b
359 363 removing a
360 364 merging rev
361 365 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
362 366 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
363 367 (branch merge, don't forget to commit)
364 368 --------------
365 369 M b
366 370 a
367 371 --------------
368 372
369 373 --------------
370 374 test L:um a b R:up a W: - 21 merge a and b to b
371 375 --------------
372 376 resolving manifests
373 377 overwrite None partial False
374 378 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
375 379 b: local moved to a -> m
376 380 rev: versions differ -> m
377 381 merging b and a
378 382 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
379 383 merging rev
380 384 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
381 385 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
382 386 (branch merge, don't forget to commit)
383 387 --------------
384 388 M b
385 389 a
386 390 --------------
387 391
388 392 --------------
389 393 test L:nm a b R:up a c W: - 23 get c, keep b
390 394 --------------
391 395 resolving manifests
392 396 overwrite None partial False
393 397 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
394 398 b: local moved to a -> m
395 399 rev: versions differ -> m
396 400 c: remote created -> g
397 401 merging b and a
398 402 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
399 403 getting c
400 404 merging rev
401 405 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
402 406 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
403 407 (branch merge, don't forget to commit)
404 408 --------------
405 409 M b
406 410 a
407 411 M c
408 412 --------------
409 413
General Comments 0
You need to be logged in to leave comments. Login now