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
--- a/mercurial/filemerge.py Wed Dec 27 17:38:28 2017 -0600
+++ b/mercurial/filemerge.py Thu Jan 04 21:36:58 2018 -0800
@@ -618,6 +618,9 @@
(if any), the backup is used to undo certain premerges, confirm whether a
merge changed anything, and determine what line endings the new file should
have.
+
+ Backups only need to be written once (right before the premerge) since their
+ content doesn't change afterwards.
"""
if fcd.isabsent():
return None
@@ -628,7 +631,6 @@
back = scmutil.origpath(ui, repo, a)
inworkingdir = (back.startswith(repo.wvfs.base) and not
back.startswith(repo.vfs.base))
-
if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir:
# If the backup file is to be in the working directory, and we're
# merging in-memory, we must redirect the backup to the memory context
@@ -637,12 +639,17 @@
wctx[relpath].write(fcd.data(), fcd.flags())
return wctx[relpath]
else:
- # Otherwise, write to wherever the user specified the backups should go.
- #
+ if premerge:
+ # Otherwise, write to wherever path the user specified the backups
+ # should go. We still need to switch based on whether the source is
+ # in-memory so we can use the fast path of ``util.copy`` if both are
+ # on disk.
+ if isinstance(fcd, context.overlayworkingfilectx):
+ util.writefile(back, fcd.data())
+ else:
+ util.copyfile(a, back)
# A arbitraryfilectx is returned, so we can run the same functions on
# the backup context regardless of where it lives.
- if premerge:
- util.copyfile(a, back)
return context.arbitraryfilectx(back, repo=repo)
def _maketempfiles(repo, fco, fca):