mercurial/merge.py
changeset 3320 b16456909a0a
parent 3318 c5075ad5e3e9
child 3322 38be819a1225
equal deleted inserted replaced
3319:6c68bc1e7873 3320: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"