mercurial/merge.py
changeset 3301 72d1e521da77
parent 3295 764688cf51e5
child 3302 20087b4bc6f9
equal deleted inserted replaced
3300:a2d93b186a0e 3301:72d1e521da77
   172                 for mf in match[of]:
   172                 for mf in match[of]:
   173                     checkpair(c, mf, m1)
   173                     checkpair(c, mf, m1)
   174 
   174 
   175     return copy
   175     return copy
   176 
   176 
   177 def manifestmerge(ui, m1, m2, ma, copy, overwrite, backwards, partial):
   177 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
   178     """
   178     """
   179     Merge manifest m1 with m2 using ancestor ma and generate merge action list
   179     Merge manifest m1 with m2 using ancestor ma and generate merge action list
   180     """
   180     """
       
   181 
       
   182     m1 = p1.manifest()
       
   183     m2 = p2.manifest()
       
   184     ma = pa.manifest()
       
   185     backwards = (pa == p2)
   181 
   186 
   182     def fmerge(f, f2=None, fa=None):
   187     def fmerge(f, f2=None, fa=None):
   183         """merge executable flags"""
   188         """merge executable flags"""
   184         if not f2:
   189         if not f2:
   185             f2 = f
   190             f2 = f
   188         return ((a^b) | (a^c)) ^ a
   193         return ((a^b) | (a^c)) ^ a
   189 
   194 
   190     action = []
   195     action = []
   191 
   196 
   192     def act(msg, f, m, *args):
   197     def act(msg, f, m, *args):
   193         ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   198         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   194         action.append((f, m) + args)
   199         action.append((f, m) + args)
       
   200 
       
   201     copy = {}
       
   202     if not (backwards or overwrite):
       
   203         copy = findcopies(repo, m1, m2, pa.rev())
   195 
   204 
   196     # Compare manifests
   205     # Compare manifests
   197     for f, n in m1.iteritems():
   206     for f, n in m1.iteritems():
   198         if partial and not partial(f):
   207         if partial and not partial(f):
   199             continue
   208             continue
   228                 else: # case 4,21 A/B/B
   237                 else: # case 4,21 A/B/B
   229                     act("local moved",
   238                     act("local moved",
   230                         f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
   239                         f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
   231         elif f in ma:
   240         elif f in ma:
   232             if n != ma[f] and not overwrite:
   241             if n != ma[f] and not overwrite:
   233                 if ui.prompt(
   242                 if repo.ui.prompt(
   234                     (_(" local changed %s which remote deleted\n") % f) +
   243                     (_(" local changed %s which remote deleted\n") % f) +
   235                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
   244                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
   236                     act("prompt delete", f, "r")
   245                     act("prompt delete", f, "r")
   237             else:
   246             else:
   238                 act("other deleted", f, "r")
   247                 act("other deleted", f, "r")
   255                 f2, "c", f, f, m1[f2], m2[f], fmerge(f2, f, f2), False)
   264                 f2, "c", f, f, m1[f2], m2[f], fmerge(f2, f, f2), False)
   256         elif f in ma:
   265         elif f in ma:
   257             if overwrite or backwards:
   266             if overwrite or backwards:
   258                 act("recreating", f, "g", m2.execf(f), n)
   267                 act("recreating", f, "g", m2.execf(f), n)
   259             elif n != ma[f]:
   268             elif n != ma[f]:
   260                 if ui.prompt(
   269                 if repo.ui.prompt(
   261                     (_("remote changed %s which local deleted\n") % f) +
   270                     (_("remote changed %s which local deleted\n") % f) +
   262                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
   271                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
   263                     act("prompt recreating", f, "g", m2.execf(f), n)
   272                     act("prompt recreating", f, "g", m2.execf(f), n)
   264         else:
   273         else:
   265             act("remote created", f, "g", m2.execf(f), n)
   274             act("remote created", f, "g", m2.execf(f), n)
   379         raise util.Abort(_("outstanding uncommitted merges"))
   388         raise util.Abort(_("outstanding uncommitted merges"))
   380 
   389 
   381     p1, p2 = pl[0], repo.changectx(node)
   390     p1, p2 = pl[0], repo.changectx(node)
   382     pa = p1.ancestor(p2)
   391     pa = p1.ancestor(p2)
   383 
   392 
   384     # are we going backwards?
       
   385     backwards = (pa == p2)
       
   386 
       
   387     # is there a linear path from p1 to p2?
   393     # is there a linear path from p1 to p2?
   388     if pa == p1 or pa == p2:
   394     if pa == p1 or pa == p2:
   389         if branchmerge:
   395         if branchmerge:
   390             raise util.Abort(_("there is nothing to merge, just use "
   396             raise util.Abort(_("there is nothing to merge, just use "
   391                                "'hg update' or look at 'hg heads'"))
   397                                "'hg update' or look at 'hg heads'"))
   397         if wc.modified() or wc.added() or wc.removed():
   403         if wc.modified() or wc.added() or wc.removed():
   398             raise util.Abort(_("outstanding uncommitted changes"))
   404             raise util.Abort(_("outstanding uncommitted changes"))
   399 
   405 
   400     m1 = wc.manifest()
   406     m1 = wc.manifest()
   401     m2 = p2.manifest()
   407     m2 = p2.manifest()
   402     ma = pa.manifest()
       
   403 
   408 
   404     # resolve the manifest to determine which files
   409     # resolve the manifest to determine which files
   405     # we care about merging
   410     # we care about merging
   406     repo.ui.note(_("resolving manifests\n"))
   411     repo.ui.note(_("resolving manifests\n"))
   407     repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
   412     repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
   408                   (overwrite, branchmerge, bool(partial)))
   413                   (overwrite, branchmerge, bool(partial)))
   409     repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (p1, p2, pa))
   414     repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (p1, p2, pa))
   410 
   415 
   411     action = []
   416     action = []
   412     copy = {}
       
   413 
   417 
   414     if not force:
   418     if not force:
   415         checkunknown(repo, m2, wc)
   419         checkunknown(repo, m2, wc)
   416     if not branchmerge:
   420     if not branchmerge:
   417         action += forgetremoved(m2, wc)
   421         action += forgetremoved(m2, wc)
   418     if not (backwards or overwrite):
   422 
   419         copy = findcopies(repo, m1, m2, pa.rev())
   423     action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
   420 
       
   421     action += manifestmerge(repo.ui, m1, m2, ma, copy,
       
   422                             overwrite, backwards, partial)
       
   423 
   424 
   424     ### apply phase
   425     ### apply phase
   425 
   426 
   426     if not branchmerge:
   427     if not branchmerge:
   427         # we don't need to do any magic, just jump to the new rev
   428         # we don't need to do any magic, just jump to the new rev