util: add safename function for generating safe names to rename to
authorMark Thomas <mbthomas@fb.com>
Mon, 02 Oct 2017 14:05:30 -0700
changeset 34554 6f11a74d489f
parent 34553 0217d66846f7
child 34555 989e884d1be9
util: add safename function for generating safe names to rename to This function finds a name which does not clash with any other name in the manifest, and so can be used to safely rename a file. Differential Revision: https://phab.mercurial-scm.org/D783
mercurial/util.py
--- a/mercurial/util.py	Mon Oct 02 14:05:30 2017 -0700
+++ b/mercurial/util.py	Mon Oct 02 14:05:30 2017 -0700
@@ -26,6 +26,7 @@
 import gc
 import hashlib
 import imp
+import itertools
 import mmap
 import os
 import platform as pyplatform
@@ -3835,3 +3836,26 @@
 
 # convenient shortcut
 dst = debugstacktrace
+
+def safename(f, tag, ctx, others=None):
+    """
+    Generate a name that it is safe to rename f to in the given context.
+
+    f:      filename to rename
+    tag:    a string tag that will be included in the new name
+    ctx:    a context, in which the new name must not exist
+    others: a set of other filenames that the new name must not be in
+
+    Returns a file name of the form oldname~tag[~number] which does not exist
+    in the provided context and is not in the set of other names.
+    """
+    if others is None:
+        others = set()
+
+    fn = '%s~%s' % (f, tag)
+    if fn not in ctx and fn not in others:
+        return fn
+    for n in itertools.count(1):
+        fn = '%s~%s~%s' % (f, tag, n)
+        if fn not in ctx and fn not in others:
+            return fn