scmutil: introduce a new backuppath() to replace origpath()
authorMartin von Zweigbergk <martinvonz@google.com>
Mon, 04 Feb 2019 20:46:33 -0800
changeset 41595 8785188d1915
parent 41594 7e09ffb3170d
child 41596 630af04d4ae4
scmutil: introduce a new backuppath() to replace origpath() Unlike most functions in our codebase, origpath() takes a path that is relative to cwd. This commit introduces a replacement for origpath(). The new function takes a path that is relative to the repo root. There is a lot of duplication between the two, but I intend to remove origpath() within the next few commits, so it won't be a maintenance burden. origpath() is also a little weird in that it returns either a a cwd-relative path or an absolute path. It needs to be able to return a path outside the repo, so it makes sense that it can return an absolute path. However, it would be simpler to always return an absolute path. The new function does that. Differential Revision: https://phab.mercurial-scm.org/D5851
mercurial/scmutil.py
--- a/mercurial/scmutil.py	Mon Feb 04 09:21:40 2019 -0800
+++ b/mercurial/scmutil.py	Mon Feb 04 20:46:33 2019 -0800
@@ -838,6 +838,41 @@
         return None
     return vfs.vfs(repo.wvfs.join(origbackuppath))
 
+def backuppath(ui, repo, filepath):
+    '''customize where working copy backup files (.orig files) are created
+
+    Fetch user defined path from config file: [ui] origbackuppath = <path>
+    Fall back to default (filepath with .orig suffix) if not specified
+
+    filepath is repo-relative
+
+    Returns an absolute path
+    '''
+    origvfs = getorigvfs(ui, repo)
+    if origvfs is None:
+        return repo.wjoin(filepath + ".orig")
+
+    origbackupdir = origvfs.dirname(filepath)
+    if not origvfs.isdir(origbackupdir) or origvfs.islink(origbackupdir):
+        ui.note(_('creating directory: %s\n') % origvfs.join(origbackupdir))
+
+        # Remove any files that conflict with the backup file's path
+        for f in reversed(list(util.finddirs(filepath))):
+            if origvfs.isfileorlink(f):
+                ui.note(_('removing conflicting file: %s\n')
+                        % origvfs.join(f))
+                origvfs.unlink(f)
+                break
+
+        origvfs.makedirs(origbackupdir)
+
+    if origvfs.isdir(filepath) and not origvfs.islink(filepath):
+        ui.note(_('removing conflicting directory: %s\n')
+                % origvfs.join(filepath))
+        origvfs.rmtree(filepath, forcibly=True)
+
+    return origvfs.join(filepath)
+
 def origpath(ui, repo, filepath):
     '''customize where .orig files are created