comparison mercurial/filemerge.py @ 48782:c7dbfc363655

filemerge: when using in-memory merge, always put backup files in temp dir Before calling a merge tool, we create a backup of the local side of the merge. That file can be put in the working copy or in a temporary directory, depending on the user's config. When we're merging in memory, we don't want to write to the actual, on-disk working copy, so we write the file to the in-memory working copy instead. However, since we don't support external merge tools with in-memory merge, it makes no difference where the file is actually stored (and if we ever do add support for external merge tools, then the file clearly can't live in the in-memory working-copy object anyway). So, since it doesn't matter where the file is stored, we can simplify by always putting them in the system's temp directory. Differential Revision: https://phab.mercurial-scm.org/D12187
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 11 Feb 2022 21:39:55 -0800
parents 8dd5853eaa04
children 218154867575
comparison
equal deleted inserted replaced
48781:8dd5853eaa04 48782:c7dbfc363655
875 b"l": b" [%s]" % labels[0], 875 b"l": b" [%s]" % labels[0],
876 b"o": b" [%s]" % labels[1], 876 b"o": b" [%s]" % labels[1],
877 } 877 }
878 878
879 879
880 def _makebackup(repo, ui, wctx, fcd): 880 def _makebackup(repo, ui, fcd):
881 """Makes and returns a filectx-like object for ``fcd``'s backup file. 881 """Makes and returns a filectx-like object for ``fcd``'s backup file.
882 882
883 In addition to preserving the user's pre-existing modifications to `fcd` 883 In addition to preserving the user's pre-existing modifications to `fcd`
884 (if any), the backup is used to undo certain premerges, confirm whether a 884 (if any), the backup is used to undo certain premerges, confirm whether a
885 merge changed anything, and determine what line endings the new file should 885 merge changed anything, and determine what line endings the new file should
892 return None 892 return None
893 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset -> 893 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset ->
894 # merge -> filemerge). (I suspect the fileset import is the weakest link) 894 # merge -> filemerge). (I suspect the fileset import is the weakest link)
895 from . import context 895 from . import context
896 896
897 backup = scmutil.backuppath(ui, repo, fcd.path()) 897 if isinstance(fcd, context.overlayworkingfilectx):
898 inworkingdir = backup.startswith(repo.wvfs.base) and not backup.startswith( 898 # If we're merging in-memory, we're free to put the backup anywhere.
899 repo.vfs.base 899 fd, backup = pycompat.mkstemp(b'hg-merge-backup')
900 ) 900 with os.fdopen(fd, 'wb') as f:
901 if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: 901 f.write(fcd.data())
902 # If the backup file is to be in the working directory, and we're
903 # merging in-memory, we must redirect the backup to the memory context
904 # so we don't disturb the working directory.
905 relpath = backup[len(repo.wvfs.base) + 1 :]
906 wctx[relpath].write(fcd.data(), fcd.flags())
907 return wctx[relpath]
908 else: 902 else:
909 # Otherwise, write to wherever path the user specified the backups 903 backup = scmutil.backuppath(ui, repo, fcd.path())
910 # should go. We still need to switch based on whether the source is 904 a = _workingpath(repo, fcd)
911 # in-memory so we can use the fast path of ``util.copy`` if both are 905 util.copyfile(a, backup)
912 # on disk. 906
913 if isinstance(fcd, context.overlayworkingfilectx): 907 return context.arbitraryfilectx(backup, repo=repo)
914 util.writefile(backup, fcd.data())
915 else:
916 a = _workingpath(repo, fcd)
917 util.copyfile(a, backup)
918 # A arbitraryfilectx is returned, so we can run the same functions on
919 # the backup context regardless of where it lives.
920 return context.arbitraryfilectx(backup, repo=repo)
921 908
922 909
923 @contextlib.contextmanager 910 @contextlib.contextmanager
924 def _maketempfiles(fco, fca, localpath, uselocalpath): 911 def _maketempfiles(fco, fca, localpath, uselocalpath):
925 """Writes out `fco` and `fca` as temporary files, and (if uselocalpath) 912 """Writes out `fco` and `fca` as temporary files, and (if uselocalpath)
1063 b'in-memory merge does not support merge conflicts' 1050 b'in-memory merge does not support merge conflicts'
1064 ) 1051 )
1065 ui.warn(onfailure % fduipath) 1052 ui.warn(onfailure % fduipath)
1066 return 1, False 1053 return 1, False
1067 1054
1068 backup = _makebackup(repo, ui, wctx, fcd) 1055 backup = _makebackup(repo, ui, fcd)
1069 r = 1 1056 r = 1
1070 try: 1057 try:
1071 internalmarkerstyle = ui.config(b'ui', b'mergemarkers') 1058 internalmarkerstyle = ui.config(b'ui', b'mergemarkers')
1072 if isexternal: 1059 if isexternal:
1073 markerstyle = _toolstr(ui, tool, b'mergemarkers') 1060 markerstyle = _toolstr(ui, tool, b'mergemarkers')