mercurial/merge.py
changeset 3255 f05c182430a0
parent 3254 751840e739a1
child 3257 c93ce7f10f85
equal deleted inserted replaced
3254:751840e739a1 3255:f05c182430a0
    52                     environ={'HG_FILE': fw,
    52                     environ={'HG_FILE': fw,
    53                              'HG_MY_NODE': p1,
    53                              'HG_MY_NODE': p1,
    54                              'HG_OTHER_NODE': p2})
    54                              'HG_OTHER_NODE': p2})
    55     if r:
    55     if r:
    56         repo.ui.warn(_("merging %s failed!\n") % fw)
    56         repo.ui.warn(_("merging %s failed!\n") % fw)
       
    57     else:
       
    58         if fd != fw:
       
    59             repo.ui.debug(_("copying %s to %s\n") % (fw, fd))
       
    60             repo.wwrite(fd, repo.wread(fw))
       
    61             if move:
       
    62                 repo.ui.debug(_("removing %s\n") % fw)
       
    63                 os.unlink(a)
    57 
    64 
    58     os.unlink(b)
    65     os.unlink(b)
    59     os.unlink(c)
    66     os.unlink(c)
    60     return r
    67     return r
    61 
    68 
   124 def findcopies(repo, m1, m2, limit):
   131 def findcopies(repo, m1, m2, limit):
   125     """
   132     """
   126     Find moves and copies between m1 and m2 back to limit linkrev
   133     Find moves and copies between m1 and m2 back to limit linkrev
   127     """
   134     """
   128 
   135 
       
   136     if not repo.ui.config("merge", "followcopies"):
       
   137         return {}
       
   138 
   129     # avoid silly behavior for update from empty dir
   139     # avoid silly behavior for update from empty dir
   130     if not m1:
   140     if not m1:
   131         return {}
   141         return {}
   132 
   142 
   133     dcopies = repo.dirstate.copies()
   143     dcopies = repo.dirstate.copies()
   162                 for mf in match[of]:
   172                 for mf in match[of]:
   163                     checkpair(c, mf, m1)
   173                     checkpair(c, mf, m1)
   164 
   174 
   165     return copy
   175     return copy
   166 
   176 
   167 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
   177 def manifestmerge(ui, m1, m2, ma, copy, overwrite, backwards, partial):
   168     """
   178     """
   169     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
   170     """
   180     """
   171 
   181 
   172     def fmerge(f):
   182     def fmerge(f, f2=None, fa=None):
   173         """merge executable flags"""
   183         """merge executable flags"""
   174         a, b, c = ma.execf(f), m1.execf(f), m2.execf(f)
   184         if not f2:
       
   185             f2 = f
       
   186             fa = f
       
   187         a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
   175         return ((a^b) | (a^c)) ^ a
   188         return ((a^b) | (a^c)) ^ a
   176 
   189 
   177     action = []
   190     action = []
   178 
   191 
   179     def act(msg, f, m, *args):
   192     def act(msg, f, m, *args):
   201                     act("update permissions", f, "e", m2.execf(f))
   214                     act("update permissions", f, "e", m2.execf(f))
   202             # contents same, check mode bits
   215             # contents same, check mode bits
   203             elif m1.execf(f) != m2.execf(f):
   216             elif m1.execf(f) != m2.execf(f):
   204                 if overwrite or fmerge(f) != m1.execf(f):
   217                 if overwrite or fmerge(f) != m1.execf(f):
   205                     act("update permissions", f, "e", m2.execf(f))
   218                     act("update permissions", f, "e", m2.execf(f))
       
   219         elif f in copy:
       
   220             f2 = copy[f]
       
   221             if f in ma: # case 3,20 A/B/A
       
   222                 act("remote moved",
       
   223                     f, "c", f2, f2, m1[f], m2[f2], fmerge(f, f2, f), True)
       
   224             else:
       
   225                 if f2 in m1: # case 2 A,B/B/B
       
   226                     act("local copied",
       
   227                         f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
       
   228                 else: # case 4,21 A/B/B
       
   229                     act("local moved",
       
   230                         f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
   206         elif f in ma:
   231         elif f in ma:
   207             if n != ma[f] and not overwrite:
   232             if n != ma[f] and not overwrite:
   208                 if ui.prompt(
   233                 if ui.prompt(
   209                     (_(" local changed %s which remote deleted\n") % f) +
   234                     (_(" local changed %s which remote deleted\n") % f) +
   210                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
   235                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
   219     for f, n in m2.iteritems():
   244     for f, n in m2.iteritems():
   220         if partial and not partial(f):
   245         if partial and not partial(f):
   221             continue
   246             continue
   222         if f in m1:
   247         if f in m1:
   223             continue
   248             continue
   224         if f in ma:
   249         if f in copy:
       
   250             f2 = copy[f]
       
   251             if f2 in ma or f2 in m1: # already seen
       
   252                 continue
       
   253             # rename case 1, A/A,B/A
       
   254             act("remote copied",
       
   255                 f, "c", f2, f, m1[f2], m2[f], fmerge(f2, f, f2), False)
       
   256         elif f in ma:
   225             if overwrite or backwards:
   257             if overwrite or backwards:
   226                 act("recreating", f, "g", m2.execf(f), n)
   258                 act("recreating", f, "g", m2.execf(f), n)
   227             elif n != ma[f]:
   259             elif n != ma[f]:
   228                 if ui.prompt(
   260                 if ui.prompt(
   229                     (_("remote changed %s which local deleted\n") % f) +
   261                     (_("remote changed %s which local deleted\n") % f) +
   249             except OSError, inst:
   281             except OSError, inst:
   250                 if inst.errno != errno.ENOENT:
   282                 if inst.errno != errno.ENOENT:
   251                     repo.ui.warn(_("update failed to remove %s: %s!\n") %
   283                     repo.ui.warn(_("update failed to remove %s: %s!\n") %
   252                                  (f, inst.strerror))
   284                                  (f, inst.strerror))
   253             removed +=1
   285             removed +=1
       
   286         elif m == "c": # copy
       
   287             f2, fd, my, other, flag, remove = a[2:]
       
   288             if filemerge(repo, f, f2, fd, my, other, xp1, xp2, remove):
       
   289                 unresolved += 1
       
   290             util.set_exec(repo.wjoin(fd), flag)
       
   291             merged += 1
   254         elif m == "m": # merge
   292         elif m == "m": # merge
   255             flag, my, other = a[2:]
   293             flag, my, other = a[2:]
   256             repo.ui.status(_("merging %s\n") % f)
   294             repo.ui.status(_("merging %s\n") % f)
   257             if filemerge(repo, f, f, f, my, other, xp1, xp2, False):
   295             if filemerge(repo, f, f, f, my, other, xp1, xp2, False):
   258                 unresolved += 1
   296                 unresolved += 1
   356     if not branchmerge:
   394     if not branchmerge:
   357         action += forgetremoved(m2, wc)
   395         action += forgetremoved(m2, wc)
   358     if not (backwards or overwrite):
   396     if not (backwards or overwrite):
   359         copy = findcopies(repo, m1, m2, pa.rev())
   397         copy = findcopies(repo, m1, m2, pa.rev())
   360 
   398 
   361     action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
   399     action += manifestmerge(repo.ui, m1, m2, ma, copy,
       
   400                             overwrite, backwards, partial)
   362 
   401 
   363     ### apply phase
   402     ### apply phase
   364 
   403 
   365     if not branchmerge:
   404     if not branchmerge:
   366         # we don't need to do any magic, just jump to the new rev
   405         # we don't need to do any magic, just jump to the new rev