mercurial/scmutil.py
changeset 34543 6fad8059a970
parent 34542 153e4e05e9b3
child 34619 18309380fb88
--- a/mercurial/scmutil.py	Sun Oct 01 12:21:50 2017 +0100
+++ b/mercurial/scmutil.py	Mon Oct 02 14:05:30 2017 -0700
@@ -38,6 +38,7 @@
     similar,
     url,
     util,
+    vfs,
 )
 
 if pycompat.osname == 'nt':
@@ -573,18 +574,34 @@
     Fall back to default (filepath with .orig suffix) if not specified
     '''
     origbackuppath = ui.config('ui', 'origbackuppath')
-    if origbackuppath is None:
+    if not origbackuppath:
         return filepath + ".orig"
 
-    filepathfromroot = os.path.relpath(filepath, start=repo.root)
-    fullorigpath = repo.wjoin(origbackuppath, filepathfromroot)
+    # Convert filepath from an absolute path into a path inside the repo.
+    filepathfromroot = util.normpath(os.path.relpath(filepath,
+                                                     start=repo.root))
+
+    origvfs = vfs.vfs(repo.wjoin(origbackuppath))
+    origbackupdir = origvfs.dirname(filepathfromroot)
+    if not origvfs.isdir(origbackupdir) or origvfs.islink(origbackupdir):
+        ui.note(_('creating directory: %s\n') % origvfs.join(origbackupdir))
 
-    origbackupdir = repo.vfs.dirname(fullorigpath)
-    if not repo.vfs.exists(origbackupdir):
-        ui.note(_('creating directory: %s\n') % origbackupdir)
-        util.makedirs(origbackupdir)
+        # Remove any files that conflict with the backup file's path
+        for f in reversed(list(util.finddirs(filepathfromroot))):
+            if origvfs.isfileorlink(f):
+                ui.note(_('removing conflicting file: %s\n')
+                        % origvfs.join(f))
+                origvfs.unlink(f)
+                break
 
-    return fullorigpath
+        origvfs.makedirs(origbackupdir)
+
+    if origvfs.isdir(filepathfromroot):
+        ui.note(_('removing conflicting directory: %s\n')
+                % origvfs.join(filepathfromroot))
+        origvfs.rmtree(filepathfromroot, forcibly=True)
+
+    return origvfs.join(filepathfromroot)
 
 class _containsnode(object):
     """proxy __contains__(node) to container.__contains__ which accepts revs"""