comparison mercurial/merge.py @ 3314:b16456909a0a

merge: various tidying update tests to handle corrected output and new workingctx display
author Matt Mackall <mpm@selenic.com>
date Tue, 10 Oct 2006 02:15:20 -0500
parents c5075ad5e3e9
children 38be819a1225
comparison
equal deleted inserted replaced
3313:6c68bc1e7873 3314:b16456909a0a
175 def manifestmerge(repo, p1, p2, pa, overwrite, partial): 175 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
176 """ 176 """
177 Merge manifest m1 with m2 using ancestor ma and generate merge action list 177 Merge manifest m1 with m2 using ancestor ma and generate merge action list
178 """ 178 """
179 179
180 repo.ui.note(_("resolving manifests\n"))
181 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
182 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
183
180 m1 = p1.manifest() 184 m1 = p1.manifest()
181 m2 = p2.manifest() 185 m2 = p2.manifest()
182 ma = pa.manifest() 186 ma = pa.manifest()
183 backwards = (pa == p2) 187 backwards = (pa == p2)
188 action = []
189 copy = {}
184 190
185 def fmerge(f, f2=None, fa=None): 191 def fmerge(f, f2=None, fa=None):
186 """merge executable flags""" 192 """merge executable flags"""
187 if not f2: 193 if not f2:
188 f2 = f 194 f2 = f
189 fa = f 195 fa = f
190 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) 196 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
191 return ((a^b) | (a^c)) ^ a 197 return ((a^b) | (a^c)) ^ a
192 198
193 action = []
194
195 def act(msg, m, f, *args): 199 def act(msg, m, f, *args):
196 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) 200 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
197 action.append((f, m) + args) 201 action.append((f, m) + args)
198 202
199 copy = {}
200 if not (backwards or overwrite): 203 if not (backwards or overwrite):
201 copy = findcopies(repo, m1, m2, pa.rev()) 204 copy = findcopies(repo, m1, m2, pa.rev())
202 205
203 # Compare manifests 206 # Compare manifests
204 for f, n in m1.iteritems(): 207 for f, n in m1.iteritems():
353 repo.dirstate.copy(f2, fd) 356 repo.dirstate.copy(f2, fd)
354 357
355 def update(repo, node, branchmerge=False, force=False, partial=None, 358 def update(repo, node, branchmerge=False, force=False, partial=None,
356 wlock=None, show_stats=True, remind=True): 359 wlock=None, show_stats=True, remind=True):
357 360
361 if not wlock:
362 wlock = repo.wlock()
363
358 overwrite = force and not branchmerge 364 overwrite = force and not branchmerge
359 forcemerge = force and branchmerge 365 forcemerge = force and branchmerge
360
361 if not wlock:
362 wlock = repo.wlock()
363
364 ### check phase
365
366 wc = repo.workingctx() 366 wc = repo.workingctx()
367 pl = wc.parents() 367 pl = wc.parents()
368 p1, p2 = pl[0], repo.changectx(node)
369 pa = p1.ancestor(p2)
370 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
371
372 ### check phase
368 if not overwrite and len(pl) > 1: 373 if not overwrite and len(pl) > 1:
369 raise util.Abort(_("outstanding uncommitted merges")) 374 raise util.Abort(_("outstanding uncommitted merges"))
370 375 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
371 p1, p2 = pl[0], repo.changectx(node)
372 pa = p1.ancestor(p2)
373
374 # is there a linear path from p1 to p2?
375 if pa == p1 or pa == p2:
376 if branchmerge: 376 if branchmerge:
377 raise util.Abort(_("there is nothing to merge, just use " 377 raise util.Abort(_("there is nothing to merge, just use "
378 "'hg update' or look at 'hg heads'")) 378 "'hg update' or look at 'hg heads'"))
379 elif not (overwrite or branchmerge): 379 elif not (overwrite or branchmerge):
380 raise util.Abort(_("update spans branches, use 'hg merge' " 380 raise util.Abort(_("update spans branches, use 'hg merge' "
381 "or 'hg update -C' to lose changes")) 381 "or 'hg update -C' to lose changes"))
382
383 if branchmerge and not forcemerge: 382 if branchmerge and not forcemerge:
384 if wc.modified() or wc.added() or wc.removed(): 383 if wc.modified() or wc.added() or wc.removed():
385 raise util.Abort(_("outstanding uncommitted changes")) 384 raise util.Abort(_("outstanding uncommitted changes"))
386 385
387 # resolve the manifest to determine which files 386 ### calculate phase
388 # we care about merging
389 repo.ui.note(_("resolving manifests\n"))
390 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
391 (overwrite, branchmerge, bool(partial)))
392 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (p1, p2, pa))
393
394 action = [] 387 action = []
395
396 if not force: 388 if not force:
397 checkunknown(wc, p2) 389 checkunknown(wc, p2)
398 if not branchmerge: 390 if not branchmerge:
399 action += forgetremoved(wc, p2) 391 action += forgetremoved(wc, p2)
400
401 action += manifestmerge(repo, wc, p2, pa, overwrite, partial) 392 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
402 393
403 ### apply phase 394 ### apply phase
404 395 if not branchmerge: # just jump to the new rev
405 if not branchmerge: 396 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
406 # just jump to the new rev
407 fp1, fp2, xp1, xp2 = p2.node(), nullid, str(p2), ''
408 else:
409 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
410
411 if not partial: 397 if not partial:
412 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) 398 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
413 399
414 updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2) 400 updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2)
415
416 # update dirstate
417 if not partial:
418 recordupdates(repo, action, branchmerge, p2)
419 repo.dirstate.setparents(fp1, fp2)
420 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
421 401
422 if show_stats: 402 if show_stats:
423 stats = ((updated, _("updated")), 403 stats = ((updated, _("updated")),
424 (merged - unresolved, _("merged")), 404 (merged - unresolved, _("merged")),
425 (removed, _("removed")), 405 (removed, _("removed")),
426 (unresolved, _("unresolved"))) 406 (unresolved, _("unresolved")))
427 note = ", ".join([_("%d files %s") % s for s in stats]) 407 note = ", ".join([_("%d files %s") % s for s in stats])
428 repo.ui.status("%s\n" % note) 408 repo.ui.status("%s\n" % note)
429 if not partial: 409 if not partial:
410 recordupdates(repo, action, branchmerge, p2)
411 repo.dirstate.setparents(fp1, fp2)
412 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
413
430 if branchmerge: 414 if branchmerge:
431 if unresolved: 415 if unresolved:
432 repo.ui.status(_("There are unresolved merges," 416 repo.ui.status(_("There are unresolved merges,"
433 " you can redo the full merge using:\n" 417 " you can redo the full merge using:\n"
434 " hg update -C %s\n" 418 " hg update -C %s\n"