comparison mercurial/filemerge.py @ 34048:52bd006b4f49

filemerge: extract _maketemp and _makebackup These functions will be modified by in-memory merge, so let's extract them first and add some comments. This also shortens `_filemerge` a bit. Differential Revision: https://phab.mercurial-scm.org/D388
author Phil Cohen <phillco@fb.com>
date Thu, 31 Aug 2017 11:05:19 -0700
parents fa6309c5761d
children 67cfffbfb6a0
comparison
equal deleted inserted replaced
34047:e97be042fa1b 34048: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