Patchwork synthrepo: new filenames must not also be new directories, and vice-versa

login
register
mail settings
Submitter adgar@google.com
Date Jan. 8, 2015, 10:57 p.m.
Message ID <7b6d6fc70633e36a4cf0.1420757820@adgar.nyc.corp.google.com>
Download mbox | patch
Permalink /patch/7397/
State Accepted
Commit a5dbec255f146fe0d8715e61cee933898ebbb28d
Headers show

Comments

adgar@google.com - Jan. 8, 2015, 10:57 p.m.
# HG changeset patch
# User Mike Edgar <adgar@google.com>
# Date 1418406134 0
#      Fri Dec 12 17:42:14 2014 +0000
# Node ID 7b6d6fc70633e36a4cf0e7c942e744c3c7ba9b30
# Parent  3575f42e1b7b174f46f1c69951526d410452abf4
synthrepo: new filenames must not also be new directories, and vice-versa

When generating many new files into a set of many possible new directories,
there is the possibility that the same path is chosen as both file and
directory. How likely this is depends on the size of the dictionary used,
the generated directory structure and the number of generated files.
Pierre-Yves David - Jan. 9, 2015, 3:05 a.m.
On 01/08/2015 02:57 PM, Mike Edgar wrote:
> # HG changeset patch
> # User Mike Edgar <adgar@google.com>
> # Date 1418406134 0
> #      Fri Dec 12 17:42:14 2014 +0000
> # Node ID 7b6d6fc70633e36a4cf0e7c942e744c3c7ba9b30
> # Parent  3575f42e1b7b174f46f1c69951526d410452abf4
> synthrepo: new filenames must not also be new directories, and vice-versa

Sure, pushed to the clowncopter.

Patch

diff -r 3575f42e1b7b -r 7b6d6fc70633 contrib/synthrepo.py
--- a/contrib/synthrepo.py	Tue Dec 09 14:45:12 2014 -0500
+++ b/contrib/synthrepo.py	Fri Dec 12 17:42:14 2014 +0000
@@ -323,15 +323,32 @@ 
     initcount = int(opts['initfiles'])
     if initcount and initdirs:
         pctx = repo[None].parents()[0]
+        dirs = set(pctx.dirs())
         files = {}
+
+        def validpath(path):
+            # Don't pick filenames which are already directory names.
+            if path in dirs:
+                return False
+            # Don't pick directories which were used as file names.
+            while path:
+                if path in files:
+                    return False
+                path = os.path.dirname(path)
+            return True
+
         for i in xrange(0, initcount):
             ui.progress(_synthesizing, i, unit=_files, total=initcount)
 
             path = pickpath()
-            while path in pctx.dirs():
+            while not validpath(path):
                 path = pickpath()
             data = '%s contents\n' % path
             files[path] = context.memfilectx(repo, path, data)
+            dir = os.path.dirname(path)
+            while dir and dir not in dirs:
+                dirs.add(dir)
+                dir = os.path.dirname(dir)
 
         def filectxfn(repo, memctx, path):
             return files[path]