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