comparison mercurial/filemerge.py @ 35702:c0439e11af16

filemerge: fix backing up an in-memory file to a custom location If the user specifies a ui.origbackuppath, we used to always copy the file there, but if the source file is in memory we must write it instead of copying. Differential Revision: https://phab.mercurial-scm.org/D1806
author Phil Cohen <phillco@fb.com>
date Thu, 04 Jan 2018 21:36:58 -0800
parents 817a3d20dd01
children 9a50ffd15b25
comparison
equal deleted inserted replaced
35701:c5d220a621e7 35702:c0439e11af16
616 616
617 In addition to preserving the user's pre-existing modifications to `fcd` 617 In addition to preserving the user's pre-existing modifications to `fcd`
618 (if any), the backup is used to undo certain premerges, confirm whether a 618 (if any), the backup is used to undo certain premerges, confirm whether a
619 merge changed anything, and determine what line endings the new file should 619 merge changed anything, and determine what line endings the new file should
620 have. 620 have.
621
622 Backups only need to be written once (right before the premerge) since their
623 content doesn't change afterwards.
621 """ 624 """
622 if fcd.isabsent(): 625 if fcd.isabsent():
623 return None 626 return None
624 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset -> 627 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset ->
625 # merge -> filemerge). (I suspect the fileset import is the weakest link) 628 # merge -> filemerge). (I suspect the fileset import is the weakest link)
626 from . import context 629 from . import context
627 a = _workingpath(repo, fcd) 630 a = _workingpath(repo, fcd)
628 back = scmutil.origpath(ui, repo, a) 631 back = scmutil.origpath(ui, repo, a)
629 inworkingdir = (back.startswith(repo.wvfs.base) and not 632 inworkingdir = (back.startswith(repo.wvfs.base) and not
630 back.startswith(repo.vfs.base)) 633 back.startswith(repo.vfs.base))
631
632 if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: 634 if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir:
633 # If the backup file is to be in the working directory, and we're 635 # If the backup file is to be in the working directory, and we're
634 # merging in-memory, we must redirect the backup to the memory context 636 # merging in-memory, we must redirect the backup to the memory context
635 # so we don't disturb the working directory. 637 # so we don't disturb the working directory.
636 relpath = back[len(repo.wvfs.base) + 1:] 638 relpath = back[len(repo.wvfs.base) + 1:]
637 wctx[relpath].write(fcd.data(), fcd.flags()) 639 wctx[relpath].write(fcd.data(), fcd.flags())
638 return wctx[relpath] 640 return wctx[relpath]
639 else: 641 else:
640 # Otherwise, write to wherever the user specified the backups should go. 642 if premerge:
641 # 643 # Otherwise, write to wherever path the user specified the backups
644 # should go. We still need to switch based on whether the source is
645 # in-memory so we can use the fast path of ``util.copy`` if both are
646 # on disk.
647 if isinstance(fcd, context.overlayworkingfilectx):
648 util.writefile(back, fcd.data())
649 else:
650 util.copyfile(a, back)
642 # A arbitraryfilectx is returned, so we can run the same functions on 651 # A arbitraryfilectx is returned, so we can run the same functions on
643 # the backup context regardless of where it lives. 652 # the backup context regardless of where it lives.
644 if premerge:
645 util.copyfile(a, back)
646 return context.arbitraryfilectx(back, repo=repo) 653 return context.arbitraryfilectx(back, repo=repo)
647 654
648 def _maketempfiles(repo, fco, fca): 655 def _maketempfiles(repo, fco, fca):
649 """Writes out `fco` and `fca` as temporary files, so an external merge 656 """Writes out `fco` and `fca` as temporary files, so an external merge
650 tool may use them. 657 tool may use them.