mercurial/filemerge.py
changeset 34031 52bd006b4f49
parent 33906 fa6309c5761d
child 34032 67cfffbfb6a0
equal deleted inserted replaced
34030:e97be042fa1b 34031:52bd006b4f49
   584     return {
   584     return {
   585         "l": " [%s]" % labels[0],
   585         "l": " [%s]" % labels[0],
   586         "o": " [%s]" % labels[1],
   586         "o": " [%s]" % labels[1],
   587     }
   587     }
   588 
   588 
   589 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
   589 def _makebackup(repo, ui, fcd, premerge):
   590     """perform a 3-way merge in the working directory
   590     """Makes a backup of the local `fcd` file prior to merging.
   591 
   591 
   592     premerge = whether this is a premerge
   592     In addition to preserving the user's pre-existing modifications to `fcd`
   593     mynode = parent node before merge
   593     (if any), the backup is used to undo certain premerges, confirm whether a
   594     orig = original local filename before merge
   594     merge changed anything, and determine what line endings the new file should
   595     fco = other file context
   595     have.
   596     fca = ancestor file context
   596     """
   597     fcd = local file context for current/destination file
   597     if fcd.isabsent():
   598 
   598         return None
   599     Returns whether the merge is complete, the return value of the merge, and
   599 
   600     a boolean indicating whether the file was deleted from disk."""
   600     a = repo.wjoin(fcd.path())
   601 
   601     back = scmutil.origpath(ui, repo, a)
       
   602     if premerge:
       
   603         util.copyfile(a, back)
       
   604     return back
       
   605 
       
   606 def _maketempfiles(repo, fcd, fco, fca):
       
   607     """Writes out `fco` and `fca` as temporary files, so an external merge
       
   608     tool may use them.
       
   609 
       
   610     `fcd` is returned as-is, by convention, because it currently doubles as both
       
   611     the local version and merge destination.
       
   612     """
   602     def temp(prefix, ctx):
   613     def temp(prefix, ctx):
   603         fullbase, ext = os.path.splitext(ctx.path())
   614         fullbase, ext = os.path.splitext(ctx.path())
   604         pre = "%s~%s." % (os.path.basename(fullbase), prefix)
   615         pre = "%s~%s." % (os.path.basename(fullbase), prefix)
   605         (fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext)
   616         (fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext)
   606         data = repo.wwritedata(ctx.path(), ctx.data())
   617         data = repo.wwritedata(ctx.path(), ctx.data())
   607         f = os.fdopen(fd, pycompat.sysstr("wb"))
   618         f = os.fdopen(fd, pycompat.sysstr("wb"))
   608         f.write(data)
   619         f.write(data)
   609         f.close()
   620         f.close()
   610         return name
   621         return name
       
   622 
       
   623     a = repo.wjoin(fcd.path())
       
   624     b = temp("base", fca)
       
   625     c = temp("other", fco)
       
   626 
       
   627     return a, b, c
       
   628 
       
   629 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
       
   630     """perform a 3-way merge in the working directory
       
   631 
       
   632     premerge = whether this is a premerge
       
   633     mynode = parent node before merge
       
   634     orig = original local filename before merge
       
   635     fco = other file context
       
   636     fca = ancestor file context
       
   637     fcd = local file context for current/destination file
       
   638 
       
   639     Returns whether the merge is complete, the return value of the merge, and
       
   640     a boolean indicating whether the file was deleted from disk."""
   611 
   641 
   612     if not fco.cmp(fcd): # files identical?
   642     if not fco.cmp(fcd): # files identical?
   613         return True, None, False
   643         return True, None, False
   614 
   644 
   615     ui = repo.ui
   645     ui = repo.ui
   654                                  toolconf):
   684                                  toolconf):
   655         if onfailure:
   685         if onfailure:
   656             ui.warn(onfailure % fd)
   686             ui.warn(onfailure % fd)
   657         return True, 1, False
   687         return True, 1, False
   658 
   688 
   659     a = repo.wjoin(fd)
   689     back = _makebackup(repo, ui, fcd, premerge)
   660     b = temp("base", fca)
   690     files = _maketempfiles(repo, fcd, fco, fca) + (back,)
   661     c = temp("other", fco)
       
   662     if not fcd.isabsent():
       
   663         back = scmutil.origpath(ui, repo, a)
       
   664         if premerge:
       
   665             util.copyfile(a, back)
       
   666     else:
       
   667         back = None
       
   668     files = (a, b, c, back)
       
   669 
       
   670     r = 1
   691     r = 1
   671     try:
   692     try:
   672         markerstyle = ui.config('ui', 'mergemarkers')
   693         markerstyle = ui.config('ui', 'mergemarkers')
   673         if not labels:
   694         if not labels:
   674             labels = _defaultconflictlabels
   695             labels = _defaultconflictlabels
   692 
   713 
   693         return True, r, deleted
   714         return True, r, deleted
   694     finally:
   715     finally:
   695         if not r and back is not None:
   716         if not r and back is not None:
   696             util.unlink(back)
   717             util.unlink(back)
   697         util.unlink(b)
   718         util.unlink(files[1])
   698         util.unlink(c)
   719         util.unlink(files[2])
   699 
   720 
   700 def _check(r, ui, tool, fcd, files):
   721 def _check(r, ui, tool, fcd, files):
   701     fd = fcd.path()
   722     fd = fcd.path()
   702     a, b, c, back = files
   723     a, b, c, back = files
   703 
   724