--- a/hgwebdir.cgi Tue Dec 16 09:58:41 2008 +0100
+++ b/hgwebdir.cgi Fri Dec 19 08:20:19 2008 +0100
@@ -32,6 +32,7 @@
# virtual/path2 = /real/path2
# virtual/root = /real/root/*
# / = /real/root2/*
+# virtual/root2 = /real/root2/**
#
# [collections]
# /prefix/to/strip/off = /root/of/tree/full/of/repos
@@ -41,15 +42,18 @@
# * First two lines mount one repository into one virtual path, like
# '/real/path1' into 'virtual/path1'.
#
-# * The third entry tells every mercurial repository found in
-# '/real/root', recursively, should be mounted in 'virtual/root'. This
-# format is preferred over the [collections] one, using absolute paths
-# as configuration keys is not supported on every platform (including
-# Windows).
+# * The third entry mounts every mercurial repository found in '/real/root'
+# in 'virtual/root'. This format is preferred over the [collections] one,
+# since using absolute paths as configuration keys is not support on every
+# platform (especially on Windows).
#
-# * The last entry is a special case mounting all repositories in
+# * The fourth entry is a special case mounting all repositories in
# /'real/root2' in the root of the virtual directory.
#
+# * The fifth entry recursively finds all repositories under the real root,
+# and mounts them using their relative path (to given real root) under the
+# virtual root.
+#
# collections example: say directory tree /foo contains repos /foo/bar,
# /foo/quux/baz. Give this config section:
# [collections]
--- a/mercurial/hgweb/hgwebdir_mod.py Tue Dec 16 09:58:41 2008 +0100
+++ b/mercurial/hgweb/hgwebdir_mod.py Fri Dec 19 08:20:19 2008 +0100
@@ -54,13 +54,18 @@
paths = cleannames(cp.items('paths'))
for prefix, root in paths:
roothead, roottail = os.path.split(root)
- if roottail != '*':
+ # "foo = /bar/*" makes every subrepo of /bar/ to be
+ # mounted as foo/subrepo
+ # and "foo = /bar/**" does even recurse inside the
+ # subdirectories, remember to use it without working dir.
+ try:
+ recurse = {'*': False, '**': True}[roottail]
+ except KeyError:
self.repos.append((prefix, root))
continue
- # "foo = /bar/*" makes every subrepo of /bar/ to be
- # mounted as foo/subrepo
roothead = os.path.normpath(roothead)
- for path in util.walkrepos(roothead, followsym=True):
+ for path in util.walkrepos(roothead, followsym=True,
+ recurse=recurse):
path = os.path.normpath(path)
name = util.pconvert(path[len(roothead):]).strip('/')
if prefix:
--- a/mercurial/util.py Tue Dec 16 09:58:41 2008 +0100
+++ b/mercurial/util.py Fri Dec 19 08:20:19 2008 +0100
@@ -1876,7 +1876,7 @@
else:
return "%s..." % (text[:maxlength-3])
-def walkrepos(path, followsym=False, seen_dirs=None):
+def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
'''yield every hg repository under path, recursively.'''
def errhandler(err):
if err.filename == path:
@@ -1901,11 +1901,16 @@
_add_dir_if_not_there(seen_dirs, path)
for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
if '.hg' in dirs:
- dirs[:] = [] # don't descend further
yield root # found a repository
- qroot = os.path.join(root, '.hg', 'patches')
- if os.path.isdir(os.path.join(qroot, '.hg')):
- yield qroot # we have a patch queue repo here
+ if recurse:
+ # avoid recursing inside the .hg directory
+ # the mq repository is added in any case
+ dirs.remove('.hg')
+ qroot = os.path.join(root, '.hg', 'patches')
+ if os.path.isdir(os.path.join(qroot, '.hg')):
+ yield qroot # we have a patch queue repo here
+ else:
+ dirs[:] = [] # don't descend further
elif followsym:
newdirs = []
for d in dirs:
--- a/tests/test-hgwebdir Tue Dec 16 09:58:41 2008 +0100
+++ b/tests/test-hgwebdir Fri Dec 19 08:20:19 2008 +0100
@@ -8,16 +8,25 @@
hg init a
echo a > a/a
hg --cwd a ci -Ama -d'1 0'
+# create a mercurial queue repository
+hg --cwd a qinit --config extensions.hgext.mq= -c
hg init b
echo b > b/b
hg --cwd b ci -Amb -d'2 0'
+# create a nested repository
+cd b
+hg init d
+echo d > d/d
+hg --cwd d ci -Amd -d'3 0'
+cd ..
+
hg init c
echo c > c/c
hg --cwd c ci -Amc -d'3 0'
+
root=`pwd`
-
cd ..
cat > paths.conf <<EOF
@@ -46,6 +55,7 @@
t/a/=$root/a
b=$root/b
coll=$root/*
+rcoll=$root/**
EOF
hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
@@ -64,6 +74,10 @@
# Test [paths] '*' extension
"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/?style=raw'
"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/a/file/tip/a?style=raw'
+#test [paths] '**' extension
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/?style=raw'
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/b/d/file/tip/d?style=raw'
+
cat > collections.conf <<EOF
[collections]
@@ -74,7 +88,7 @@
-A access-collections.log -E error-collections.log
cat hg.pid >> $DAEMON_PIDS
-echo % should succeed
+echo % collections: should succeed
"$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/?style=raw'
"$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw'
"$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/file/tip/b?style=raw'
--- a/tests/test-hgwebdir.out Tue Dec 16 09:58:41 2008 +0100
+++ b/tests/test-hgwebdir.out Fri Dec 19 08:20:19 2008 +0100
@@ -1,5 +1,6 @@
adding a
adding b
+adding d
adding c
% should give a 404 - file does not exist
404 Not Found
@@ -32,6 +33,11 @@
/coll/a/
/coll/b/
/coll/c/
+/rcoll/a/
+/rcoll/a/.hg/patches/
+/rcoll/b/
+/rcoll/b/d/
+/rcoll/c/
/t/a/
200 Script output follows
@@ -115,7 +121,19 @@
200 Script output follows
a
-% should succeed
+200 Script output follows
+
+
+/rcoll/a/
+/rcoll/a/.hg/patches/
+/rcoll/b/
+/rcoll/b/d/
+/rcoll/c/
+
+200 Script output follows
+
+d
+% collections: should succeed
200 Script output follows