[PATCH] introduce upath repositories (issue793)

Adrian Buehlmann adrian at cadifra.com
Wed Jun 18 02:59:36 CDT 2008


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1213742337 -7200
# Node ID f26690cd0a452fe1bb0efdcf36c83f4ba2a92f3a
# Parent  bb1575f74f27070e3c58083608837c192dd8df35
introduce upath repositories (issue793)

This change adds a new entry 'upath' in the .hg/requires file
of new repositories.

upath encodes repository paths by prepending an underbar
to every path component inside .hg/store/data.

This encoding ensures that repositories containing tracked files
with path components consisting of Windows reserved file names
(e.g. 'nul', 'aux', 'lpt', etc.) can be pulled to Windows.

Older versions of Mercurial accessing a upath repository will
abort with "abort: requirement 'upath' not supported!".

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -15,7 +15,7 @@
 
 class localrepository(repo.repository):
     capabilities = util.set(('lookup', 'changegroupsubset'))
-    supported = ('revlogv1', 'store')
+    supported = ('revlogv1', 'store', 'upath')
 
     def __init__(self, parentui, path=None, create=0):
         repo.repository.__init__(self)
@@ -34,6 +34,7 @@
                 if parentui.configbool('format', 'usestore', True):
                     os.mkdir(os.path.join(self.path, "store"))
                     requirements.append("store")
+                    requirements.append("upath")
                     # create an invalid changelog
                     self.opener("00changelog.i", "a").write(
                         '\0\0\0\2' # represents revlogv2
@@ -62,8 +63,12 @@
 
         # setup store
         if "store" in requirements:
-            self.encodefn = util.encodefilename
-            self.decodefn = util.decodefilename
+            if "upath" in requirements:
+                self.encodefn = util.upathencode
+                self.decodefn = util.upathdecode
+            else:
+                self.encodefn = util.encodefilename
+                self.decodefn = util.decodefilename
             self.spath = os.path.join(self.path, "store")
         else:
             self.encodefn = lambda x: x
diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
--- a/mercurial/statichttprepo.py
+++ b/mercurial/statichttprepo.py
@@ -55,8 +55,12 @@
 
         # setup store
         if "store" in requirements:
-            self.encodefn = util.encodefilename
-            self.decodefn = util.decodefilename
+            if "upath" in requirements:
+                self.encodefn = util.upathencode
+                self.decodefn = util.upathdecode
+            else:
+                self.encodefn = util.encodefilename
+                self.decodefn = util.decodefilename
             self.spath = self.path + "/store"
         else:
             self.encodefn = lambda x: x
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1379,6 +1379,11 @@
 
 encodefilename, decodefilename = _buildencodefun()
 
+def upathencode(path):
+    return encodefilename(path).replace('/', '/_')
+def upathdecode(path):
+    return decodefilename(path.replace('/_', '/'))
+
 def encodedopener(openerfn, fn):
     def o(path, *args, **kw):
         return openerfn(fn(path), *args, **kw)
diff --git a/tests/test-bundle-r b/tests/test-bundle-r
--- a/tests/test-bundle-r
+++ b/tests/test-bundle-r
@@ -41,10 +41,10 @@
 hg update -C 3
 hg mv afile anotherfile
 hg commit -m "0.3m" -d "1000000 0"
-hg debugindex .hg/store/data/afile.i
-hg debugindex .hg/store/data/adifferentfile.i
-hg debugindex .hg/store/data/anotherfile.i
-hg debugindex .hg/store/data/fred.i
+hg debugindex .hg/store/data/_afile.i
+hg debugindex .hg/store/data/_adifferentfile.i
+hg debugindex .hg/store/data/_anotherfile.i
+hg debugindex .hg/store/data/_fred.i
 hg debugindex .hg/store/00manifest.i
 hg verify
 cd ..
diff --git a/tests/test-changelog-exec b/tests/test-changelog-exec
--- a/tests/test-changelog-exec
+++ b/tests/test-changelog-exec
@@ -29,4 +29,4 @@
 echo '% this should not mention bar:'
 hg tip -v
 
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
diff --git a/tests/test-clone-r b/tests/test-clone-r
--- a/tests/test-clone-r
+++ b/tests/test-clone-r
@@ -41,10 +41,10 @@
 hg update -C 3
 hg mv afile anotherfile
 hg commit -m "0.3m"
-hg debugindex .hg/store/data/afile.i
-hg debugindex .hg/store/data/adifferentfile.i
-hg debugindex .hg/store/data/anotherfile.i
-hg debugindex .hg/store/data/fred.i
+hg debugindex .hg/store/data/_afile.i
+hg debugindex .hg/store/data/_adifferentfile.i
+hg debugindex .hg/store/data/_anotherfile.i
+hg debugindex .hg/store/data/_fred.i
 hg debugindex .hg/store/00manifest.i
 hg verify
 cd ..
diff --git a/tests/test-commit-copy b/tests/test-commit-copy
--- a/tests/test-commit-copy
+++ b/tests/test-commit-copy
@@ -11,4 +11,4 @@
 hg ci -m 'cp bar foo; change bar'
 
 hg debugrename foo
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
diff --git a/tests/test-copy b/tests/test-copy
--- a/tests/test-copy
+++ b/tests/test-copy
@@ -13,16 +13,16 @@
 echo "we should see one log entry for a"
 hg log a
 echo "this should show a revision linked to changeset 0"
-hg debugindex .hg/store/data/a.i
+hg debugindex .hg/store/data/_a.i
 echo "we should see one log entry for b"
 hg log b
 echo "this should show a revision linked to changeset 1"
-hg debugindex .hg/store/data/b.i
+hg debugindex .hg/store/data/_b.i
 
 echo "this should show the rename information in the metadata"
-hg debugdata .hg/store/data/b.d 0 | head -3 | tail -2
+hg debugdata .hg/store/data/_b.d 0 | head -3 | tail -2
 
-$TESTDIR/md5sum.py .hg/store/data/b.i
+$TESTDIR/md5sum.py .hg/store/data/_b.i
 hg cat b > bsum
 $TESTDIR/md5sum.py bsum
 hg cat a > asum
diff --git a/tests/test-copy.out b/tests/test-copy.out
--- a/tests/test-copy.out
+++ b/tests/test-copy.out
@@ -41,7 +41,7 @@
 this should show the rename information in the metadata
 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
 copy: a
-ed156f22f0a6fde642de0b5eba0cbbb2  .hg/store/data/b.i
+ed156f22f0a6fde642de0b5eba0cbbb2  .hg/store/data/_b.i
 60b725f10c9c85c70d97880dfe8191b3  bsum
 60b725f10c9c85c70d97880dfe8191b3  asum
 checking changesets
diff --git a/tests/test-copy2 b/tests/test-copy2
--- a/tests/test-copy2
+++ b/tests/test-copy2
@@ -31,7 +31,7 @@
 hg st -C
 
 echo "# should match"
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 hg debugrename bar
 
 echo bleah > foo
@@ -47,9 +47,9 @@
 hg commit -m3 -d"0 0"
 
 echo "# should show no parents for tip"
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 echo "# should match"
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 hg debugrename bar
 
 echo "# should show no copies"
diff --git a/tests/test-debugindexdot b/tests/test-debugindexdot
--- a/tests/test-debugindexdot
+++ b/tests/test-debugindexdot
@@ -14,4 +14,4 @@
 HGMERGE=true hg merge -q
 hg ci -m merge -d '3 0'
 
-hg debugindexdot .hg/store/data/a.i
+hg debugindexdot .hg/store/data/_a.i
diff --git a/tests/test-dumprevlog b/tests/test-dumprevlog
--- a/tests/test-dumprevlog
+++ b/tests/test-dumprevlog
@@ -19,7 +19,7 @@
 hg verify
 
 echo dumping revlog of file a to stdout:
-python $CONTRIBDIR/dumprevlog .hg/store/data/a.i
+python $CONTRIBDIR/dumprevlog .hg/store/data/_a.i
 echo dumprevlog done
 
 # dump all revlogs to file repo.dump
diff --git a/tests/test-dumprevlog.out b/tests/test-dumprevlog.out
--- a/tests/test-dumprevlog.out
+++ b/tests/test-dumprevlog.out
@@ -4,7 +4,7 @@
 checking files
 1 files, 3 changesets, 3 total revisions
 dumping revlog of file a to stdout:
-file: .hg/store/data/a.i
+file: .hg/store/data/_a.i
 node: 183d2312b35066fb6b3b449b84efc370d50993d0
 linkrev: 0
 parents: 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
@@ -36,7 +36,7 @@
 undumping:
 .hg/store/00changelog.i
 .hg/store/00manifest.i
-.hg/store/data/a.i
+.hg/store/data/_a.i
 undumping done
 checking changesets
 checking manifests
diff --git a/tests/test-encode b/tests/test-encode
--- a/tests/test-encode
+++ b/tests/test-encode
@@ -22,7 +22,7 @@
 hg status
 
 echo %% uncompressed contents in repo
-hg debugdata .hg/store/data/a.gz.d 0
+hg debugdata .hg/store/data/_a.gz.d 0
 
 echo %% uncompress our working dir copy
 gunzip < a.gz
diff --git a/tests/test-excessive-merge b/tests/test-excessive-merge
--- a/tests/test-excessive-merge
+++ b/tests/test-excessive-merge
@@ -41,6 +41,6 @@
 
 echo
 
-hg debugindex .hg/store/data/a.i
+hg debugindex .hg/store/data/_a.i
 
 hg verify
diff --git a/tests/test-extra-filelog-entry b/tests/test-extra-filelog-entry
--- a/tests/test-extra-filelog-entry
+++ b/tests/test-extra-filelog-entry
@@ -16,4 +16,4 @@
 hg qnew -f foo.diff
 echo b > b
 hg qrefresh
-hg debugindex .hg/store/data/b.i
+hg debugindex .hg/store/data/_b.i
diff --git a/tests/test-filebranch b/tests/test-filebranch
--- a/tests/test-filebranch
+++ b/tests/test-filebranch
@@ -59,16 +59,16 @@
 hg log -v -r tip
 
 echo "foo: we should have a merge here"
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 
 echo "bar: we shouldn't have a merge here"
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 
 echo "baz: we shouldn't have a merge here"
-hg debugindex .hg/store/data/baz.i
+hg debugindex .hg/store/data/_baz.i
 
 echo "quux: we shouldn't have a merge here"
-hg debugindex .hg/store/data/quux.i
+hg debugindex .hg/store/data/_quux.i
 
 echo "manifest entries should match tips of all files"
 hg manifest --debug
diff --git a/tests/test-flags b/tests/test-flags
--- a/tests/test-flags
+++ b/tests/test-flags
@@ -45,6 +45,6 @@
 ls -l ../test[123]/a > foo
 cut -b 1-10 < foo
 
-hg debugindex .hg/store/data/a.i
-hg debugindex ../test2/.hg/store/data/a.i
-hg debugindex ../test1/.hg/store/data/a.i
+hg debugindex .hg/store/data/_a.i
+hg debugindex ../test2/.hg/store/data/_a.i
+hg debugindex ../test1/.hg/store/data/_a.i
diff --git a/tests/test-http-clone-r b/tests/test-http-clone-r
--- a/tests/test-http-clone-r
+++ b/tests/test-http-clone-r
@@ -42,10 +42,10 @@
 hg update -C 3
 hg mv afile anotherfile
 hg commit -m "0.3m"
-hg debugindex .hg/store/data/afile.i
-hg debugindex .hg/store/data/adifferentfile.i
-hg debugindex .hg/store/data/anotherfile.i
-hg debugindex .hg/store/data/fred.i
+hg debugindex .hg/store/data/_afile.i
+hg debugindex .hg/store/data/_adifferentfile.i
+hg debugindex .hg/store/data/_anotherfile.i
+hg debugindex .hg/store/data/_fred.i
 hg debugindex .hg/store/00manifest.i
 hg verify
 echo "# Starting server"
diff --git a/tests/test-inherit-mode b/tests/test-inherit-mode
--- a/tests/test-inherit-mode
+++ b/tests/test-inherit-mode
@@ -84,7 +84,7 @@
 touch dir/file
 hg ci -qAm 'add dir/file'
 storemode=`python ../mode.py .hg/store`
-dirmode=`python ../mode.py .hg/store/data/dir`
+dirmode=`python ../mode.py .hg/store/data/_dir`
 if [ "$storemode" != "$dirmode" ]; then
     echo "$storemode != $dirmode"
 fi
diff --git a/tests/test-inherit-mode.out b/tests/test-inherit-mode.out
--- a/tests/test-inherit-mode.out
+++ b/tests/test-inherit-mode.out
@@ -19,9 +19,9 @@
 00660 ./.hg/store/00changelog.i
 00660 ./.hg/store/00manifest.i
 00770 ./.hg/store/data/
-00770 ./.hg/store/data/dir/
-00660 ./.hg/store/data/dir/bar.i
-00660 ./.hg/store/data/foo.i
+00770 ./.hg/store/data/_dir/
+00660 ./.hg/store/data/_dir/_bar.i
+00660 ./.hg/store/data/_foo.i
 00660 ./.hg/store/undo
 00660 ./.hg/undo.branch
 00660 ./.hg/undo.dirstate
@@ -46,9 +46,9 @@
 00660 ../push/.hg/store/00changelog.i
 00660 ../push/.hg/store/00manifest.i
 00770 ../push/.hg/store/data/
-00770 ../push/.hg/store/data/dir/
-00660 ../push/.hg/store/data/dir/bar.i
-00660 ../push/.hg/store/data/foo.i
+00770 ../push/.hg/store/data/_dir/
+00660 ../push/.hg/store/data/_dir/_bar.i
+00660 ../push/.hg/store/data/_foo.i
 00660 ../push/.hg/store/undo
 00660 ../push/.hg/undo.branch
 00660 ../push/.hg/undo.dirstate
diff --git a/tests/test-init.out b/tests/test-init.out
--- a/tests/test-init.out
+++ b/tests/test-init.out
@@ -3,6 +3,7 @@
 00changelog.i created
 revlogv1
 store
+upath
 adding foo
 # creating repo with old format
 revlogv1
diff --git a/tests/test-issue522 b/tests/test-issue522
--- a/tests/test-issue522
+++ b/tests/test-issue522
@@ -27,5 +27,5 @@
 hg ci -d '0 0' -m 'merge'
 
 hg manifest --debug | grep foo
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 
diff --git a/tests/test-merge-commit b/tests/test-merge-commit
--- a/tests/test-merge-commit
+++ b/tests/test-merge-commit
@@ -23,9 +23,9 @@
 echo '% contents of bar should be line0 line1 line2'
 cat bar
 hg ci -m '3: merge with local rename' -d '0 0'
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 hg debugrename bar
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 
 # revert the content change from rev 2
 hg up -C 2
@@ -39,7 +39,7 @@
 echo '% contents of bar should be line1 line2'
 cat bar
 hg ci -m '5: merge' -d '0 0'
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 
 
 # same thing, but with the merge on 3 having the rename on the remote parent
@@ -54,9 +54,9 @@
 echo '% contents of bar should be line0 line1 line2'
 cat bar
 hg ci -m '3: merge with remote rename' -d '0 0'
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 hg debugrename bar
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
 
 # revert the content change from rev 2
 hg up -C 2
@@ -70,5 +70,5 @@
 echo '% contents of bar should be line1 line2'
 cat bar
 hg ci -m '5: merge' -d '0 0'
-hg debugindex .hg/store/data/bar.i
+hg debugindex .hg/store/data/_bar.i
 
diff --git a/tests/test-merge7 b/tests/test-merge7
--- a/tests/test-merge7
+++ b/tests/test-merge7
@@ -61,6 +61,6 @@
 
 cat test.txt
 
-hg debugindex .hg/store/data/test.txt.i
+hg debugindex .hg/store/data/_test.txt.i
 
 hg log
diff --git a/tests/test-permissions b/tests/test-permissions
--- a/tests/test-permissions
+++ b/tests/test-permissions
@@ -6,11 +6,11 @@
 hg add a
 hg commit -m "1" -d "1000000 0"
 hg verify
-chmod -r .hg/store/data/a.i
+chmod -r .hg/store/data/_a.i
 hg verify 2>/dev/null || echo verify failed
-chmod +r .hg/store/data/a.i
+chmod +r .hg/store/data/_a.i
 hg verify 2>/dev/null || echo verify failed
-chmod -w .hg/store/data/a.i
+chmod -w .hg/store/data/_a.i
 echo barber > a
 hg commit -m "2" -d "1000000 0" 2>/dev/null || echo commit failed
 chmod -w .
diff --git a/tests/test-push-r b/tests/test-push-r
--- a/tests/test-push-r
+++ b/tests/test-push-r
@@ -41,10 +41,10 @@
 hg update -C 3
 hg mv afile anotherfile
 hg commit -m "0.3m"
-hg debugindex .hg/store/data/afile.i
-hg debugindex .hg/store/data/adifferentfile.i
-hg debugindex .hg/store/data/anotherfile.i
-hg debugindex .hg/store/data/fred.i
+hg debugindex .hg/store/data/_afile.i
+hg debugindex .hg/store/data/_adifferentfile.i
+hg debugindex .hg/store/data/_anotherfile.i
+hg debugindex .hg/store/data/_fred.i
 hg debugindex .hg/store/00manifest.i
 hg verify
 cd ..
diff --git a/tests/test-rename-merge1 b/tests/test-rename-merge1
--- a/tests/test-rename-merge1
+++ b/tests/test-rename-merge1
@@ -23,5 +23,5 @@
 hg status -AC
 cat b
 hg ci -m "merge" -d "0 0"
-hg debugindex .hg/store/data/b.i
+hg debugindex .hg/store/data/_b.i
 hg debugrename b
\ No newline at end of file
diff --git a/tests/test-revlog-packentry b/tests/test-revlog-packentry
--- a/tests/test-revlog-packentry
+++ b/tests/test-revlog-packentry
@@ -11,4 +11,4 @@
 echo foo bar baz > foo
 hg ci -Am 'add foo again'
 
-hg debugindex .hg/store/data/foo.i
+hg debugindex .hg/store/data/_foo.i
diff --git a/tests/test-ssh-clone-r b/tests/test-ssh-clone-r
--- a/tests/test-ssh-clone-r
+++ b/tests/test-ssh-clone-r
@@ -67,10 +67,10 @@
 hg update -C 3
 hg mv afile anotherfile
 hg commit -m "0.3m"
-hg debugindex .hg/store/data/afile.i
-hg debugindex .hg/store/data/adifferentfile.i
-hg debugindex .hg/store/data/anotherfile.i
-hg debugindex .hg/store/data/fred.i
+hg debugindex .hg/store/data/_afile.i
+hg debugindex .hg/store/data/_adifferentfile.i
+hg debugindex .hg/store/data/_anotherfile.i
+hg debugindex .hg/store/data/_fred.i
 hg debugindex .hg/store/00manifest.i
 hg verify
 cd ..
diff --git a/tests/test-strip-cross.out b/tests/test-strip-cross.out
--- a/tests/test-strip-cross.out
+++ b/tests/test-strip-cross.out
@@ -6,43 +6,43 @@
      3       291     122      1       2 f0ef8726ac4f 000000000000 000000000000
      4       413      87      4       4 0b76e38b4070 000000000000 000000000000
 
-crossed/.hg/store/data/012.i
+crossed/.hg/store/data/_012.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       0 b8e02f643373 000000000000 000000000000
      1         3       3      1       1 5d9299349fc0 000000000000 000000000000
      2         6       3      2       2 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/021.i
+crossed/.hg/store/data/_021.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       0 b8e02f643373 000000000000 000000000000
      1         3       3      1       2 5d9299349fc0 000000000000 000000000000
      2         6       3      2       1 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/102.i
+crossed/.hg/store/data/_102.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       1 b8e02f643373 000000000000 000000000000
      1         3       3      1       0 5d9299349fc0 000000000000 000000000000
      2         6       3      2       2 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/120.i
+crossed/.hg/store/data/_120.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       1 b8e02f643373 000000000000 000000000000
      1         3       3      1       2 5d9299349fc0 000000000000 000000000000
      2         6       3      2       0 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/201.i
+crossed/.hg/store/data/_201.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       2 b8e02f643373 000000000000 000000000000
      1         3       3      1       0 5d9299349fc0 000000000000 000000000000
      2         6       3      2       1 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/210.i
+crossed/.hg/store/data/_210.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       2 b8e02f643373 000000000000 000000000000
      1         3       3      1       1 5d9299349fc0 000000000000 000000000000
      2         6       3      2       0 2661d26c6496 000000000000 000000000000
 
-crossed/.hg/store/data/manifest-file.i
+crossed/.hg/store/data/_manifest-file.i
    rev    offset  length   base linkrev nodeid       p1           p2
      0         0       3      0       3 b8e02f643373 000000000000 000000000000
      1         3       3      1       4 5d9299349fc0 000000000000 000000000000


More information about the Mercurial-devel mailing list