[PATCH stable] subrepo: use standard handling of \ in subpath replacement strings (BC)

Mads Kiilerich mads at kiilerich.com
Wed Jul 25 19:57:58 CDT 2012


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1343264252 -7200
# Branch stable
# Node ID 1de046d28995fb6c5af554882d2c5ec14b364ece
# Parent  1675ef8a2bf2e32e9f42aa3a74b48c0f44ff9b80
subrepo: use standard handling of \ in subpath replacement strings (BC)

The previous approach for both allowing replacement strings like C:\foo\bar and
back references as C:\foo\lib\1 is problematic:

1. string-escape will escape \ - also on unix. That is surprising and
undocumented.

2. string-escape will also escape ' and characters outside printable ASCII -
and it is thus not the right kind of escape for a regexp replacement string.

3. there is no obvious way to to represent a path element starting with a digit
after a \. The only way is to use / as path element separator.

It is better to be strict and consistent and say that replacement paths on
windows must be written with / or \\.

The old behaviour is not documented anywhere.

This is a behavioural change that might show up in some real world scenarios
... but it can be worked around by defining subpaths in hgrc. The old behaviour
could be considered a bug and a bigger problem than the behavioural change.

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -60,13 +60,8 @@
 
     def remap(src):
         for pattern, repl in p.items('subpaths'):
-            # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
-            # does a string decode.
-            repl = repl.encode('string-escape')
-            # However, we still want to allow back references to go
-            # through unharmed, so we turn r'\\1' into r'\1'. Again,
-            # extra escapes are needed because re.sub string decodes.
-            repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
+            # Paths like C:\foo\bar must be specified as C:\\foo\\bar. There is
+            # thus no ambiguity with \1 replacement markers.
             try:
                 src = re.sub(pattern, repl, src, 1)
             except re.error, e:
diff --git a/tests/test-subrepo-paths.t b/tests/test-subrepo-paths.t
--- a/tests/test-subrepo-paths.t
+++ b/tests/test-subrepo-paths.t
@@ -17,7 +17,7 @@
 hg debugsub with remapping
 
   $ echo '[subpaths]' >> .hg/hgrc
-  $ printf 'http://example.net/lib(.*) = C:\\libs\\\\1-lib\\\n' >> .hg/hgrc # no-check-code
+  $ printf 'http://example.net/lib(.*) = C:\\\\libs\\\\\\1-lib\\\\\n' >> .hg/hgrc # no-check-code
 
   $ hg debugsub
   path sub


More information about the Mercurial-devel mailing list