[PATCH] clone/pull: abort on reserved filenames on Windows (issue793)

Adrian Buehlmann adrian at cadifra.com
Wed Jun 18 13:22:30 CDT 2008


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1213789809 -7200
# Node ID 08b34b7d9ac6766ab7e89f6945b22c711fc8f626
# Parent  bacfee67c1a9cd9acfed00ecd282a03548a088cb
clone/pull: abort on reserved filenames on Windows (issue793)

hg clone -U (and pull) hangs forever on Windows when pulling from
a remote repository (on unix) containing a file with a filename
which is reserved on Windows (e.g. 'aux', 'nul', 'prn', 'lpt', ...).

With this change, Mercurial now aborts with an error message
when trying to pull the problem file (e.g. "abort: path 'aux' is
not supported").

This is an interim fix which could be better solved for example by
using a different repository layout.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2005,6 +2005,8 @@
                 f = changegroup.getchunk(source)
                 if not f:
                     break
+                if util.unsupported_path(f):
+                    raise util.Abort(_("path '%s' is not supported") % f)
                 self.ui.debug(_("adding %s revisions\n") % f)
                 fl = self.file(f)
                 o = fl.count()
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -983,10 +983,25 @@
 def lookup_reg(key, name=None, scope=None):
     return None
 
+_reserved_windows_filenames = '''CON PRN AUX NUL
+    COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9
+    LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9'''.split()
+def win_unsupported_path(p):
+    '''True, if tracked path p cannot be stored below .hg on Windows
+    (using the current path encoding and repo layout).
+    p is repo-relative and must use '/' as path separator'''
+    for n in p.split('/'):
+        if n:
+            base = n.split('.')[0]
+            if base and base.upper() in _reserved_windows_filenames:
+                return True
+    return False
+
 # Platform specific variants
 if os.name == 'nt':
     import msvcrt
     nulldev = 'NUL:'
+    unsupported_path = win_unsupported_path
 
     class winstdout:
         '''stdout on windows misbehaves if sent through a pipe'''
@@ -1178,6 +1193,7 @@
 
 else:
     nulldev = '/dev/null'
+    unsupported_path = lambda p: False # no unsupported paths
 
     def rcfiles(path):
         rcs = [os.path.join(path, 'hgrc')]


More information about the Mercurial-devel mailing list