changeset 2:d25e9dd2fcb6

tests: use mercurial's run-tests.py to run tests - move tests from the makefile to tests/*.t files - change the makefile to support running tests with multiple hg versions - use a script to generate the list of versions to test from mercurial tags - split the tests so some can be skipped when required features are not present
author jcoomes
date Mon, 20 Dec 2010 13:27:14 -0800
parents ecf1aa057cc2
children 04c4cfd17ff4
files .hgignore makefile tests/hgext-test.gmk tests/hgrc tests/test-trees-local-x.t tests/test-trees-local.t tests/test-trees-remote.t tests/verlist.py trees.py
diffstat 9 files changed, 1207 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,4 @@
+syntax: glob
+*.pyc
+tests/*.t.err
+tests/hg-versions
--- a/makefile	Fri Dec 17 10:22:38 2010 -0800
+++ b/makefile	Mon Dec 20 13:27:14 2010 -0800
@@ -21,222 +21,29 @@
 # questions.
 # 
 
-# Use $hg from the environment, if set.
-HG		:= $(word 1,${hg} hg)
-
-# Installation.
-PREFIX		:= ${HG_INSTALL_BASE}/hg
-SRC_D		:= .
-TREES_PY	:= ${SRC_D}/trees.py
-SRC_F		:= trees.py
-GET_PY_VER	:= import sys; print ".".join(sys.version.split(".")[0:2])
-PY_VER		:= $(shell python -c '${GET_PY_VER}')
-DST_D		= ${PREFIX}/lib/python${PY_VER}/site-packages/hgext
-DST_F		= $(addprefix ${DST_D}/,${SRC_F})
+PWD		:= $(shell pwd)
+SRC_DIR		:= ${PWD}
+DST_DIR		:= ${HOME}/.hgfiles
 
-# Testing.
-TEST_RESULTS	:= test-results
-TR		:= ${TEST_RESULTS}
-TEST_CMDS1	= list paths st up
-TEST_CMDS2	= in out pull push
-TESTS_1		:= $(foreach r,r1 r2 r3 r4,$(addprefix ${r}.,${TEST_CMDS1}))
-TESTS_2		:= $(foreach r,r1 r2,$(addprefix ${r}.,${TEST_CMDS2}))
-TESTS		= $(TESTS_1) $(TESTS_2) r4.config hs.paths
-
-HGRC		:= ${TR}/hgrc
-RUN_HG		:= HGRCPATH=${HGRC} ${HG}
-
-QUIET		:= @
-
-.PHONY:  all install test version ${TESTS} r1.cset r2.cset FORCE
+.PHONY:  all clean install
 
 all:
-	${QUIET} echo '${MAKE} install [PREFIX=...]'
-	${QUIET} echo '${MAKE} test [ARGS=...]'
-	${QUIET} echo '${MAKE} ${TESTS_1} [ARGS=...]'
-	${QUIET} echo '${MAKE} ${TESTS_2} [ARGS=...]'
-	${QUIET} echo '${MAKE} r4.config hs.paths [ARGS=...]'
+	@ echo 'Try one of the following:'
+	@ echo '${MAKE} install [DST_DIR=...]'
+	@ echo '${MAKE} test             # run tests with the default hg'
+	@ echo '${MAKE} test-hg-versions # run tests with multiple hg versions'
 
 clean:
-	rm -fr "${TR}" "${SRC_D}"/*.pyc
-
-install:  ${DST_F}
-
-# File still seen as out of date, even with cp -p.  Grrr.
-${DST_D}/%: ${SRC_D}/%
-	cp -p '$^' '$@' && touch '$@'
-
-test:  ${TESTS}
-
-version:
-	${RUN_HG} version
-
-${TR}:
-	mkdir -p ${TR}
-
-${HGRC}:  ${SRC_D}/tests/hgrc makefile
-	${QUIET} [ -d '${TR}' ] || mkdir -p '${TR}'
-	${QUIET} cp '$<' '$@'
-	${QUIET} \
-	{ \
-	echo; \
-	echo '[extensions]'; \
-	echo 'trees = ${TREES_PY}'; \
-	echo; \
-	echo '[trees]'; \
-	echo 's1s2 = s1 s2'; \
-	echo 'hs-closed = src/closed test/closed'; \
-	} >> '$@'
+	rm -f "${SRC_DIR}"/*.pyc "${SRC_DIR}"/tests/*.t.err
 
-${TR}/r1:  ${HGRC}
-	rm -fr '$@'
-	${QUIET} echo creating '$@' ...
-	${QUIET} \
-	all=''; \
-	for r in '$@' \
-		'$@/s1' \
-		'$@/s1/s1.1 with spaces' \
-		'$@/s2' \
-		'$@/s2/s2.1' \
-		'$@/s2/s2.2' \
-		'$@/s2/s2.2/s2.2.1'; \
-	do \
-		${RUN_HG} init "$$r" && \
-		echo $$r > "$$r/x" && \
-		${RUN_HG} -R "$$r" ci -qAm "$$r"; \
-		if [ -n "$$all" ]; \
-		then \
-			all="$$all\n$${r:-.}"; \
-		else \
-			all="$${r:-.}"; \
-		fi; \
-	done; \
-	root=`${RUN_HG} -R $@ root`; \
-	echo "$$all" | sed 's!$@!'"$$root"'!' > '$@.list.ref'
-	${QUIET} { \
-		echo s1; echo s2; \
-	} >> '$@'/.hg/trees
-	${QUIET} { \
-		echo 's1.1 with spaces'; \
-	} >> '$@'/s1/.hg/trees
-	${QUIET} { \
-		echo s2.1; echo s2.2; echo s2.2/s2.2.1; \
-	} >> '$@'/s2/.hg/trees
+install:  ${DST_DIR}/trees.py
 
-${TR}/r2:  ${TR}/r1 ${TREES_PY}
-	rm -fr '$@'
-	${RUN_HG} tclone ${ARGS} $< '$@'
-	${QUIET} sed 's!$<!$@!' ${<}.list.ref > ${@}.list.ref
-	${QUIET} cp -p ${<}.list.ref ${@}.paths.ref
-	@ echo
-
-${TR}/r3:  ${TR}/r1 ${TR}/r2 ${TREES_PY}
-	rm -fr '$@'
-	${RUN_HG} tclone $< '$@' s1 file:${TR}/r2 s2
-	${QUIET} sed 's!$<!$@!' ${<}.list.ref > ${@}.list.ref
-	${QUIET} sed 's!$</s2!${TR}/r2/s2!' ${<}.list.ref > ${@}.paths.ref
-	@ echo
-
-${TR}/r4:  ${TR}/r1 ${TR}/r2 ${TREES_PY}
-	rm -fr '$@'
-	${RUN_HG} tclone $< '$@' s1 file:${TR}/r2 s2
-	${QUIET} sed 's!$<!$@!' ${<}.list.ref > ${@}.list.ref
-	@ echo
+${DST_DIR}/%:  ${SRC_DIR}/%
+	cp -p '$^' '$@'
 
-%.up:	rev	= tip
-r1.%:	rlocal	= '${TR}/r1'
-r1.%:	rother	= '${TR}/r2'
-r2.%:	rlocal	= '${TR}/r2'
-r2.%:	rother	=
-r3.%:	rlocal	= '${TR}/r3'
-r4.%:	rlocal	= '${TR}/r4'
-
-rx_treecmd	= t$(subst $(basename $@).,,$@)
-rx_redirect	= 2>&1 | tee ${TR}/${@}.raw
-rx_pathsfilt	= sed -n 's/default[ 	]*=[ 	]*//p' ${TR}/${@}.raw > ${TR}/${@}.out
-rx_diff		= if [ -f ${TR}/${@}.ref ]; then diff -u ${TR}/${@}.ref ${TR}/${@}.out; fi
-
-r1.cset: ${TR}/r1 FORCE
-	${QUIET} for r in s2 s2/s2.2; \
-	do \
-		echo $$r >> ${rlocal}/$$r/w; \
-		${RUN_HG} -R ${rlocal}/$$r ci -qAm "$@ $$r w"; \
-		echo $$r >> ${rlocal}/$$r/x; \
-		${RUN_HG} -R ${rlocal}/$$r ci -qAm "$@ $$r x"; \
-	done
-
-r2.cset: ${TR}/r2 FORCE
-	${QUIET} for r in s1 s2/s2.1 s2/s2.2/s2.2.1; \
-	do \
-		echo $$r >> ${rlocal}/$$r/y; \
-		${RUN_HG} -R ${rlocal}/$$r ci -qAm "$@ $$r y"; \
-		echo $$r >> ${rlocal}/$$r/z; \
-		${RUN_HG} -R ${rlocal}/$$r ci -qAm "$@ $$r z"; \
-	done
-
-${TESTS_1}:  ${TR}/r3 ${TR}/r4
-	${RUN_HG} -R ${rlocal} ${rx_treecmd} ${ARGS} ${rev} ${rx_redirect}
-	${QUIET} \
-	case "$@" in \
-	*.paths) ${rx_pathsfilt};; \
-	*) mv ${TR}/${@}.raw ${TR}/${@}.out;; \
-	esac
-	${QUIET} ${rx_diff}
-	@ echo
-
-r4.config: ${TR}/r4
-	rm -fr ${rlocal}/s3
-	${RUN_HG} init ${rlocal}/s3
-
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
+HGEXT_TEST	:= tests
+EXTENSION_PY	:= ${SRC_DIR}/trees.py
+HG_VERSIONS	:= 1.6:
 
-	${RUN_HG} tconfig -R ${rlocal} -a s3
-	if ${RUN_HG} tconfig -R ${rlocal} -a s3; then exit 1; fi
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
-
-	${RUN_HG} tconfig -R ${rlocal} -s s1 s2
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
-
-	${RUN_HG} tconfig -R ${rlocal} -s
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
-
-	${RUN_HG} tconfig -R ${rlocal} -s s1 s2 s3
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
-
-	${RUN_HG} tconfig -R ${rlocal} -d s1
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
-
-	${RUN_HG} tconfig -R ${rlocal} -sw
-	cat ${rlocal}/.hg/trees
-	${RUN_HG} tconfig -R ${rlocal}
+-include ${HGEXT_TEST}/hgext-test.gmk
 
-r1.in r1.pull r2.out r2.push:  r2.cset
-	${RUN_HG} -R ${rlocal} ${rx_treecmd} ${ARGS} ${rother}
-r1.out r1.push r2.in r2.pull:  r1.cset
-	${RUN_HG} -R ${rlocal} ${rx_treecmd} ${ARGS} ${rother}
-
-# combine repos from different trees (http)
-hs_url_o	= http://hg.openjdk.java.net/jdk7/hotspot
-hs_url_c	= http://closedjdk.sfbay.sun.com/jdk7/hotspot
-${TR}/hs:  ${HGRC} ${TREES_PY}
-	rm -fr '$@'
-	${RUN_HG} tclone '${hs_url_o}' '$@' pubs '${hs_url_c}-gc' hs-closed
-	${QUIET} \
-	for p in '${hs_url_o}' '${hs_url_o}'/pubs \
-		'${hs_url_c}-gc/src/closed' '${hs_url_c}-gc/test/closed'; \
-	do \
-		echo "$$p"; \
-	done > $@.paths.ref
-
-	@ echo
-
-hs.paths:  ${TR}/hs
-	${RUN_HG} -R '$<' tpaths ${ARGS} ${rx_redirect}
-	${QUIET} ${rx_pathsfilt}
-	${QUIET} ${rx_diff}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/hgext-test.gmk	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,145 @@
+# 
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+
+# Test an hg extension against multiple hg versions.  Mercurial's run-tests.py
+# is used to run the tests, so the tests should be written as mercurial
+# "unified" tests (see the mercurial web site).
+#
+# Testing requires a private clone of the mercurial repo, since it is modified
+# when running tests.  Use "gmake clone-hg" before running tests the first time
+# to create a clone.
+#
+# Once the clone exists, run "gmake test-hg-versions" to test against multiple
+# hg versions.
+#
+# Required variables (must be set before including this makefile):
+# 
+#     HGEXT_TEST   = the directory containing this makefile and the
+#                    verlist extension
+#     EXTENSION_PY = the absolute path to the extension to be tested
+# 
+# Optional variables:
+# 
+#     HG_VERSIONS  = a list of revision ranges specifying the mercurial versions
+#                    to test (e.g., 0.9.4 1.0:1.3.2 1.5:)
+#     HG_REPO      = absolute path of the mercurial clone 
+#     TEST_DIR     = directory where the extension's unified tests are kept
+#     TEST_VER_DIR = directory where the output from test-hg-versions is stored
+#
+# Example:
+# 
+# HGEXT_TEST   = ../hgext-test
+# EXTENSION_PY = $(SOURCE_DIR)/myextension.py
+# HG_VERSIONS = 1.1:   # test 1.1 and later
+# 
+# include ${HGEXT_TEST}/hgext-test.gmk
+
+HG		?= hg
+
+HG_URL		?= http://selenic.com/repo/hg
+# Working clone of ${HG_URL} (modified when running tests).
+HG_REPO		?= $(shell pwd)/hg-repo
+
+TEST_DIR	?= tests
+TEST_VER_DIR	?= ${TEST_DIR}/hg-versions
+TESTS		?= *.t
+
+# Command to list the hg versions tested by the 'test-hg-versions' target.  The
+# list is generated from the tags in ${HG_REPO} using the verlist extension.
+VERLIST_EXT	= ${HGEXT_TEST}/verlist.py
+VERLIST_CFG	= --config extensions.verlist=${VERLIST_EXT}
+VERLIST_ARGS	= ${VERLIST_CFG} verlist -l ${HG_VERSIONS}
+VERLIST_CMD	= ${HG} -R ${HG_REPO} ${VERLIST_ARGS}
+VERLIST_TARGETS	= $(if $(wildcard ${HG_REPO}),\
+		    $(addprefix ${TEST_VER_DIR}/,$(shell ${VERLIST_CMD})))
+
+Q		:= @
+
+RUN_TESTS_PY	:= ${HG_REPO}/tests/run-tests.py
+KILLDAEMONS_PY	:= ${HG_REPO}/tests/killdaemons.py
+
+changelog	:= .hg/store/00changelog.i
+
+define test-hg-failed
+{						\
+rc=$$?;						\
+f="${@}-`date +%Y%m%d%H%M%S`";			\
+mv "$@" "$$f";					\
+echo "$$f:"; 					\
+tail "$$f"; 					\
+exit $$rc;					\
+}
+endef
+
+# The working dir of ${HG_REPO} is updated to different hg versions to test with
+# those versions.  Get the most recent run-tests.py and killdaemons.py to run
+# the tests.
+define test-hg-prep-run-tests
+${Q} ${HG} -R ${HG_REPO} cat -r tip ${RUN_TESTS_PY} > ${RUN_TESTS_PY}
+${Q} ${HG} -R ${HG_REPO} cat -r tip ${KILLDAEMONS_PY} > ${KILLDAEMONS_PY}
+endef
+
+define test-hg-ver-commands
+@    echo "----------------------------------------"
+@    echo "running tests with hg $(notdir $@):"
+${Q} mkdir -p '$(dir $@)'
+${Q} ${HG} -R ${HG_REPO} up -q -C $(notdir $@)
+${Q} ${HG} -R ${HG_REPO} log -r . > $@
+${Q} ${MAKE} test >> $@ 2>&1 || ${test-hg-failed}
+${Q} grep '^# Ran ' $@
+endef
+
+.PHONY:  clean-tests clean-test-repo clone-hg test test-hg-versions FORCE
+
+test:  clone-hg
+	${test-hg-prep-run-tests}
+	cd ${TEST_DIR} && EXTENSION_PY=${EXTENSION_PY} ${RUN_TESTS_PY} ${TESTS}
+
+clone-hg: ${HG_REPO}/.hg/requires
+
+clean-hg-versions:
+	rm -fr "${TEST_VER_DIR}"
+
+clean-hg-repo:  
+	rm -fr "${HG_REPO}"
+
+# Run the tests with multiple hg versions.
+test-hg-versions:  ${HG_REPO}/${changelog} ${VERLIST_TARGETS}
+
+# The tags in the mercurial repo (aside from tip) do not change, so no need to
+# retest with old hg versions unless trees.py has changed.  Use .hg/requires
+# as a dependency to trigger a clone if it doesn't exist (using ${HG_REPO}
+# directly would repeat tests unnecessarily, as it changes on each 'hg update').
+${TEST_VER_DIR}/%:  ${EXTENSION_PY} ${HG_REPO}/.hg/requires
+	${test-hg-ver-commands}
+
+# Retest tip whenever new mercurial changesets show up.
+${TEST_VER_DIR}/tip:  ${EXTENSION_PY} ${HG_REPO}/${changelog}
+	${test-hg-ver-commands}
+
+${HG_REPO}/.hg/requires:
+	${HG} clone ${HG_URL} ${HG_REPO}
+
+${HG_REPO}/${changelog}:  ${HG_REPO}/.hg/requires FORCE
+	${Q} ${HG} -R ${HG_REPO} up -q -C tip
+	${Q} ${HG} -R ${HG_REPO} pull -q -u ${HG_URL}
--- a/tests/hgrc	Fri Dec 17 10:22:38 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-[defaults]
-backout = -d "0 0"
-commit = -d "0 0"
-tag = -d "0 0"
-ttag = -d "0 0"
-
-[ui]
-slash = True
-username = anontester
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-trees-local-x.t	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,35 @@
+Pushkey support is required to run this test.
+
+  $ hg init x
+  $ hg debugpushkey x Non-Existent-Namespace || exit 80
+
+Enable the extension; the path to it should be in $EXTENSION_PY.
+
+  $ { echo '[extensions]'; echo "trees=$EXTENSION_PY"; } >> $HGRCPATH
+
+Create test repos.
+
+  $ for r in r1 'r1/s1 has a space' r1/s2 'r1/s3 has a space'
+  > do
+  >     hg init "$r"
+  >     echo "$r" > "$r/x" && hg -R "$r" ci -qAm "$r"
+  > done
+  $ hg tconfig -R r1 --set --walk
+  $ hg tconfig -R r1
+  s1 has a space
+  s2
+  s3 has a space
+
+Check remote tree config w/tdebugkeys--using tclone on an http repo would
+require a real web server.
+
+This requires mercurial w/pushkey support (1.6 and later).
+
+  $ { echo '[extensions]'; echo "trees = $EXTENSION_PY"; } >> r1/.hg/hgrc
+  $ hg -R r1 serve -p $HGPORT  -d --pid-file=r1.pid -E r1.log
+  $ cat r1.pid >> $DAEMON_PIDS
+
+  $ hg tdebugkeys http://localhost:$HGPORT/
+  0: s1 has a space
+  1: s2
+  2: s3 has a space
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-trees-local.t	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,812 @@
+Enable the extension; the path to it should be in $EXTENSION_PY.
+
+  $ { echo '[extensions]'; echo "trees=$EXTENSION_PY"; } >> $HGRCPATH
+  $ { echo '[trees]'; echo 's135 = s1 s3 s5'; } >> $HGRCPATH
+
+Create test repos.
+
+  $ for r in rflat rflat/s1 rflat/s2 rflat/s3 rflat/s4 rflat/s5 rflat/s6 \
+  > r1 r1/s1 'r1/s1/s1.1 with spaces' r1/s2 r1/s2/s2.1 r1/s2/s2.2 \
+  > r1/s2/s2.2/s2.2.1
+  > do
+  >     hg init "$r"
+  >     echo "$r" > "$r/x" && hg -R "$r" ci -qAm "$r"
+  > done
+  $ hg tconfig -R rflat --set --walk
+  $ hg tconfig -R r1    --set s1 s2
+  $ hg tconfig -R r1/s1 --set 's1.1 with spaces'
+  $ hg tconfig -R r1/s2 --set --walk
+
+  $ hg tclone -q r1 r2
+  $ hg tclone -q r1 r3 s1 file:$TESTTMP/r2 s2
+  $ hg tclone    r1 r4 s1 file:$TESTTMP/r3 s2
+  cloning r1
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4
+  
+  cloning $TESTTMP/r1/s1
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s1
+  
+  cloning $TESTTMP/r1/s1/s1.1 with spaces
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s1/s1.1 with spaces
+  
+  cloning $TESTTMP/r3/s2
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s2
+  
+  cloning $TESTTMP/r3/s2/s2.1
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s2/s2.1
+  
+  cloning $TESTTMP/r3/s2/s2.2
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s2/s2.2
+  
+  cloning $TESTTMP/r3/s2/s2.2/s2.2.1
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r4/s2/s2.2/s2.2.1
+
+List the configuration.
+
+  $ hg tconfig -R rflat
+  s1
+  s2
+  s3
+  s4
+  s5
+  s6
+
+  $ hg tconfig -R r1
+  s1
+  s2
+
+  $ for r in r1 r2 r3 r4
+  > do
+  >     echo
+  >     hg tlist -R $r
+  >     hg tpaths -R $r
+  > done
+  
+  $TESTTMP/r1
+  $TESTTMP/r1/s1
+  $TESTTMP/r1/s1/s1.1 with spaces
+  $TESTTMP/r1/s2
+  $TESTTMP/r1/s2/s2.1
+  $TESTTMP/r1/s2/s2.2
+  $TESTTMP/r1/s2/s2.2/s2.2.1
+  [$TESTTMP/r1]:
+  
+  [$TESTTMP/r1/s1]:
+  
+  [$TESTTMP/r1/s1/s1.1 with spaces]:
+  
+  [$TESTTMP/r1/s2]:
+  
+  [$TESTTMP/r1/s2/s2.1]:
+  
+  [$TESTTMP/r1/s2/s2.2]:
+  
+  [$TESTTMP/r1/s2/s2.2/s2.2.1]:
+  
+  $TESTTMP/r2
+  $TESTTMP/r2/s1
+  $TESTTMP/r2/s1/s1.1 with spaces
+  $TESTTMP/r2/s2
+  $TESTTMP/r2/s2/s2.1
+  $TESTTMP/r2/s2/s2.2
+  $TESTTMP/r2/s2/s2.2/s2.2.1
+  [$TESTTMP/r2]:
+  default = $TESTTMP/r1
+  
+  [$TESTTMP/r2/s1]:
+  default = $TESTTMP/r1/s1
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  default = $TESTTMP/r1/s1/s1.1 with spaces
+  
+  [$TESTTMP/r2/s2]:
+  default = $TESTTMP/r1/s2
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  default = $TESTTMP/r1/s2/s2.1
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  default = $TESTTMP/r1/s2/s2.2
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  default = $TESTTMP/r1/s2/s2.2/s2.2.1
+  
+  $TESTTMP/r3
+  $TESTTMP/r3/s1
+  $TESTTMP/r3/s1/s1.1 with spaces
+  $TESTTMP/r3/s2
+  $TESTTMP/r3/s2/s2.1
+  $TESTTMP/r3/s2/s2.2
+  $TESTTMP/r3/s2/s2.2/s2.2.1
+  [$TESTTMP/r3]:
+  default = $TESTTMP/r1
+  
+  [$TESTTMP/r3/s1]:
+  default = $TESTTMP/r1/s1
+  
+  [$TESTTMP/r3/s1/s1.1 with spaces]:
+  default = $TESTTMP/r1/s1/s1.1 with spaces
+  
+  [$TESTTMP/r3/s2]:
+  default = $TESTTMP/r2/s2
+  
+  [$TESTTMP/r3/s2/s2.1]:
+  default = $TESTTMP/r2/s2/s2.1
+  
+  [$TESTTMP/r3/s2/s2.2]:
+  default = $TESTTMP/r2/s2/s2.2
+  
+  [$TESTTMP/r3/s2/s2.2/s2.2.1]:
+  default = $TESTTMP/r2/s2/s2.2/s2.2.1
+  
+  $TESTTMP/r4
+  $TESTTMP/r4/s1
+  $TESTTMP/r4/s1/s1.1 with spaces
+  $TESTTMP/r4/s2
+  $TESTTMP/r4/s2/s2.1
+  $TESTTMP/r4/s2/s2.2
+  $TESTTMP/r4/s2/s2.2/s2.2.1
+  [$TESTTMP/r4]:
+  default = $TESTTMP/r1
+  
+  [$TESTTMP/r4/s1]:
+  default = $TESTTMP/r1/s1
+  
+  [$TESTTMP/r4/s1/s1.1 with spaces]:
+  default = $TESTTMP/r1/s1/s1.1 with spaces
+  
+  [$TESTTMP/r4/s2]:
+  default = $TESTTMP/r3/s2
+  
+  [$TESTTMP/r4/s2/s2.1]:
+  default = $TESTTMP/r3/s2/s2.1
+  
+  [$TESTTMP/r4/s2/s2.2]:
+  default = $TESTTMP/r3/s2/s2.2
+  
+  [$TESTTMP/r4/s2/s2.2/s2.2.1]:
+  default = $TESTTMP/r3/s2/s2.2/s2.2.1
+
+Test tconfig command.
+
+  $ hg init r4/s3
+  $ hg tconfig -R r4
+  s1
+  s2
+
+  $ hg tconfig -R r4 -a s3
+  $ hg tconfig -R r4
+  s1
+  s2
+  s3
+  $ hg tconfig -R r4 -a s3 # should fail
+  abort: subtree s3 already configured
+  [255]
+  $ hg tconfig -R r4 -d s0 # should fail
+  abort: no subtree s0
+  [255]
+
+  $ hg tconfig -R r4 -s s1 s2
+  $ hg tconfig -R r4
+  s1
+  s2
+
+  $ hg tconfig -R r4 -s
+  abort: use either --walk or subtrees (but not both)
+  [255]
+  $ hg tconfig -R r4 -d --all
+  $ hg tconfig -R r4
+
+  $ hg tconfig -R r4 -s s1 s2 s3
+  $ hg tconfig -R r4
+  s1
+  s2
+  s3
+
+  $ hg tconfig -R r4 -d s1
+  $ hg tconfig -R r4
+  s2
+  s3
+
+  $ hg tconfig -R r4 -s s1 s2
+  $ hg tconfig -R r4
+  s1
+  s2
+
+  $ hg tlist -R r4
+  $TESTTMP/r4
+  $TESTTMP/r4/s1
+  $TESTTMP/r4/s1/s1.1 with spaces
+  $TESTTMP/r4/s2
+  $TESTTMP/r4/s2/s2.1
+  $TESTTMP/r4/s2/s2.2
+  $TESTTMP/r4/s2/s2.2/s2.2.1
+  $ hg tlist -R r4 -w
+  $TESTTMP/r4
+  $TESTTMP/r4/s1
+  $TESTTMP/r4/s1/s1.1 with spaces
+  $TESTTMP/r4/s2
+  $TESTTMP/r4/s2/s2.1
+  $TESTTMP/r4/s2/s2.2
+  $TESTTMP/r4/s2/s2.2/s2.2.1
+  $TESTTMP/r4/s3
+  $ rm -r r4/s3
+
+Create changesets in r1 and r2.
+
+  $ for r in r1 r2
+  > do
+  >     for sr in s2 s2/s2.2 s2/s2.2/s2.2.1
+  >     do
+  >         echo $sr > $r/$sr/file.$r
+  >         hg -R $r/$sr add $r/$sr/file.$r
+  >         hg -R $r/$sr ci -qm "$r/$sr/file.$r"
+  >     done
+  > done
+
+Check incoming & outgoing
+
+  $ hg -R r1 tin r2
+  [$TESTTMP/r1]:
+  comparing with r2
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s1]:
+  comparing with r2/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s1/s1.1 with spaces]:
+  comparing with r2/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s2]:
+  comparing with r2/s2
+  searching for changes
+  changeset:   1:02ac722f677c
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/file.r2
+  
+  
+  [$TESTTMP/r1/s2/s2.1]:
+  comparing with r2/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s2/s2.2]:
+  comparing with r2/s2/s2.2
+  searching for changes
+  changeset:   1:b9139c2dc588
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/s2.2/file.r2
+  
+  
+  [$TESTTMP/r1/s2/s2.2/s2.2.1]:
+  comparing with r2/s2/s2.2/s2.2.1
+  searching for changes
+  changeset:   1:c0662346bf9f
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/s2.2/s2.2.1/file.r2
+  
+  $ hg -R r2 tin
+  [$TESTTMP/r2]:
+  comparing with $TESTTMP/r1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1]:
+  comparing with $TESTTMP/r1/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  comparing with $TESTTMP/r1/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2]:
+  comparing with $TESTTMP/r1/s2
+  searching for changes
+  changeset:   1:e87282477f23
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/file.r1
+  
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  comparing with $TESTTMP/r1/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  comparing with $TESTTMP/r1/s2/s2.2
+  searching for changes
+  changeset:   1:19c35aa89db4
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/s2.2/file.r1
+  
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  comparing with $TESTTMP/r1/s2/s2.2/s2.2.1
+  searching for changes
+  changeset:   1:0830ec9a3521
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/s2.2/s2.2.1/file.r1
+  
+  $ hg -R r1 tout r2
+  [$TESTTMP/r1]:
+  comparing with r2
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s1]:
+  comparing with r2/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s1/s1.1 with spaces]:
+  comparing with r2/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s2]:
+  comparing with r2/s2
+  searching for changes
+  changeset:   1:e87282477f23
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/file.r1
+  
+  
+  [$TESTTMP/r1/s2/s2.1]:
+  comparing with r2/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r1/s2/s2.2]:
+  comparing with r2/s2/s2.2
+  searching for changes
+  changeset:   1:19c35aa89db4
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/s2.2/file.r1
+  
+  
+  [$TESTTMP/r1/s2/s2.2/s2.2.1]:
+  comparing with r2/s2/s2.2/s2.2.1
+  searching for changes
+  changeset:   1:0830ec9a3521
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r1/s2/s2.2/s2.2.1/file.r1
+  
+  $ hg -R r2 tout
+  [$TESTTMP/r2]:
+  comparing with $TESTTMP/r1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1]:
+  comparing with $TESTTMP/r1/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  comparing with $TESTTMP/r1/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2]:
+  comparing with $TESTTMP/r1/s2
+  searching for changes
+  changeset:   1:02ac722f677c
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/file.r2
+  
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  comparing with $TESTTMP/r1/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  comparing with $TESTTMP/r1/s2/s2.2
+  searching for changes
+  changeset:   1:b9139c2dc588
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/s2.2/file.r2
+  
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  comparing with $TESTTMP/r1/s2/s2.2/s2.2.1
+  searching for changes
+  changeset:   1:c0662346bf9f
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     r2/s2/s2.2/s2.2.1/file.r2
+  
+
+Pull, merge, push.
+
+  $ hg -R r2 tpull
+  [$TESTTMP/r2]:
+  pulling from $TESTTMP/r1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1]:
+  pulling from $TESTTMP/r1/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  pulling from $TESTTMP/r1/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2]:
+  pulling from $TESTTMP/r1/s2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  pulling from $TESTTMP/r1/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  pulling from $TESTTMP/r1/s2/s2.2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  pulling from $TESTTMP/r1/s2/s2.2/s2.2.1
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ for r in r2
+  > do
+  >     for sr in s2 s2/s2.2 s2/s2.2/s2.2.1
+  >     do
+  >         hg -R $r/$sr merge
+  >         hg -R $r/$sr commit -m 'merge with r1'
+  >     done
+  > done
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg -R r2 tpush
+  [$TESTTMP/r2]:
+  pushing to $TESTTMP/r1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1]:
+  pushing to $TESTTMP/r1/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  pushing to $TESTTMP/r1/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2]:
+  pushing to $TESTTMP/r1/s2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 1 files
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  pushing to $TESTTMP/r1/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  pushing to $TESTTMP/r1/s2/s2.2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 1 files
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  pushing to $TESTTMP/r1/s2/s2.2/s2.2.1
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 1 files
+
+  $ for sr in s2 s2/s2.2 s2/s2.2/s2.2.1
+  > do
+  >     hg -R r1/$sr tip
+  > done
+  changeset:   3:3d0a1cb52bf2
+  tag:         tip
+  parent:      2:02ac722f677c
+  parent:      1:e87282477f23
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     merge with r1
+  
+  changeset:   3:76fc250030c4
+  tag:         tip
+  parent:      2:b9139c2dc588
+  parent:      1:19c35aa89db4
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     merge with r1
+  
+  changeset:   3:015d691fdafe
+  tag:         tip
+  parent:      2:c0662346bf9f
+  parent:      1:0830ec9a3521
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     merge with r1
+  
+Run tin & tout again (should be nothing incoming) to check exit code.
+
+  $ hg -R r2 tin
+  [$TESTTMP/r2]:
+  comparing with $TESTTMP/r1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1]:
+  comparing with $TESTTMP/r1/s1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s1/s1.1 with spaces]:
+  comparing with $TESTTMP/r1/s1/s1.1 with spaces
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2]:
+  comparing with $TESTTMP/r1/s2
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.1]:
+  comparing with $TESTTMP/r1/s2/s2.1
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2]:
+  comparing with $TESTTMP/r1/s2/s2.2
+  searching for changes
+  no changes found
+  
+  [$TESTTMP/r2/s2/s2.2/s2.2.1]:
+  comparing with $TESTTMP/r1/s2/s2.2/s2.2.1
+  searching for changes
+  no changes found
+  [1]
+  $ hg -R r2 tout -q
+  [1]
+
+Test tree aliases.
+
+  $ hg tclone rflat r135 s135
+  cloning rflat
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r135
+  
+  cloning $TESTTMP/rflat/s1
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r135/s1
+  
+  cloning $TESTTMP/rflat/s3
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r135/s3
+  
+  cloning $TESTTMP/rflat/s5
+  updating (to branch default|working directory) (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  created $TESTTMP/r135/s5
+  $ hg tpaths -R r135
+  [$TESTTMP/r135]:
+  default = $TESTTMP/rflat
+  
+  [$TESTTMP/r135/s1]:
+  default = $TESTTMP/rflat/s1
+  
+  [$TESTTMP/r135/s3]:
+  default = $TESTTMP/rflat/s3
+  
+  [$TESTTMP/r135/s5]:
+  default = $TESTTMP/rflat/s5
+
+Test tcommand, tstatus, ttag, tupdate.
+
+  $ hg tlist -R r135
+  $TESTTMP/r135
+  $TESTTMP/r135/s1
+  $TESTTMP/r135/s3
+  $TESTTMP/r135/s5
+  $ hg tcomm -R r135 pwd
+  [$TESTTMP/r135]:
+  $TESTTMP/r135
+  
+  [$TESTTMP/r135/s1]:
+  $TESTTMP/r135/s1
+  
+  [$TESTTMP/r135/s3]:
+  $TESTTMP/r135/s3
+  
+  [$TESTTMP/r135/s5]:
+  $TESTTMP/r135/s5
+  $ hg tstat -R r135 -q
+  $ hg tcomm -R r135 -q -- touch xyz
+  $ hg tstat -R r135
+  [$TESTTMP/r135]:
+  ? xyz
+  
+  [$TESTTMP/r135/s1]:
+  ? xyz
+  
+  [$TESTTMP/r135/s3]:
+  ? xyz
+  
+  [$TESTTMP/r135/s5]:
+  ? xyz
+  $ hg tcomm -R r135 -q -- hg add xyz
+  $ hg tstat -R r135
+  [$TESTTMP/r135]:
+  A xyz
+  
+  [$TESTTMP/r135/s1]:
+  A xyz
+  
+  [$TESTTMP/r135/s3]:
+  A xyz
+  
+  [$TESTTMP/r135/s5]:
+  A xyz
+  $ hg tcomm -R r135 -q -- hg commit -m 'add xyz'
+  $ hg tstat -R r135 -q
+  $ hg ttag  -R r135 -d '0 0' xyz
+  [$TESTTMP/r135]:
+  
+  [$TESTTMP/r135/s1]:
+  
+  [$TESTTMP/r135/s3]:
+  
+  [$TESTTMP/r135/s5]:
+  $ hg tcomm -R r135 -- hg log -l 2
+  [$TESTTMP/r135]:
+  changeset:   2:83290f94fb2b
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag xyz for changeset b0a2d2266db8
+  
+  changeset:   1:b0a2d2266db8
+  tag:         xyz
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add xyz
+  
+  
+  [$TESTTMP/r135/s1]:
+  changeset:   2:5e30e7223a0b
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag xyz for changeset f1afd954409a
+  
+  changeset:   1:f1afd954409a
+  tag:         xyz
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add xyz
+  
+  
+  [$TESTTMP/r135/s3]:
+  changeset:   2:8c6b313fb499
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag xyz for changeset e16257c3cacc
+  
+  changeset:   1:e16257c3cacc
+  tag:         xyz
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add xyz
+  
+  
+  [$TESTTMP/r135/s5]:
+  changeset:   2:c2c28aac7653
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag xyz for changeset add70ffe0e61
+  
+  changeset:   1:add70ffe0e61
+  tag:         xyz
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add xyz
+  
+  $ hg tup   -R r135 null
+  [$TESTTMP/r135]:
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s1]:
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s3]:
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s5]:
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg tup   -R r135
+  [$TESTTMP/r135]:
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s1]:
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s3]:
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  
+  [$TESTTMP/r135/s5]:
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-trees-remote.t	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,79 @@
+Enable the extension; the path to it should be in $EXTENSION_PY.
+
+  $ { echo '[extensions]'; echo "trees=$EXTENSION_PY"; } >> $HGRCPATH
+  $ { echo '[trees]'; echo 'subt = corba jaxp'; } >> $HGRCPATH
+
+Filter the output from clone for compatibility with various mercurial versions.
+
+  $ filt() { grep -v '^requesting all changes'; }
+
+Clone with aliases.
+
+  $ hg tclone -r 0 -U http://hg.openjdk.java.net/jdk7/jdk7 jdk7 subt | filt
+  cloning http://hg.openjdk.java.net/jdk7/jdk7
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 25 changes to 25 files
+  created $TESTTMP/jdk7
+  
+  cloning http://hg.openjdk.java.net/jdk7/jdk7/corba
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1368 changes to 1368 files
+  created $TESTTMP/jdk7/corba
+  
+  cloning http://hg.openjdk.java.net/jdk7/jdk7/jaxp
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1972 changes to 1972 files
+  created $TESTTMP/jdk7/jaxp
+
+  $ hg tpaths -R jdk7
+  [$TESTTMP/jdk7]:
+  default = http://hg.openjdk.java.net/jdk7/jdk7
+  
+  [$TESTTMP/jdk7/corba]:
+  default = http://hg.openjdk.java.net/jdk7/jdk7/corba
+  
+  [$TESTTMP/jdk7/jaxp]:
+  default = http://hg.openjdk.java.net/jdk7/jdk7/jaxp
+
+  $ rm -fr jdk7
+
+Clone combining separate trees.
+
+  $ hg tclone -r 0 -U http://hg.openjdk.java.net/jdk7/jdk7 jdk7 \
+  > http://hg.openjdk.java.net/jdk7/hotspot subt | filt
+  cloning http://hg.openjdk.java.net/jdk7/jdk7
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 25 changes to 25 files
+  created $TESTTMP/jdk7
+  
+  cloning http://hg.openjdk.java.net/jdk7/hotspot/corba
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1368 changes to 1368 files
+  created $TESTTMP/jdk7/corba
+  
+  cloning http://hg.openjdk.java.net/jdk7/hotspot/jaxp
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1972 changes to 1972 files
+  created $TESTTMP/jdk7/jaxp
+
+  $ hg tpaths -R jdk7
+  [$TESTTMP/jdk7]:
+  default = http://hg.openjdk.java.net/jdk7/jdk7
+  
+  [$TESTTMP/jdk7/corba]:
+  default = http://hg.openjdk.java.net/jdk7/hotspot/corba
+  
+  [$TESTTMP/jdk7/jaxp]:
+  default = http://hg.openjdk.java.net/jdk7/hotspot/jaxp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/verlist.py	Mon Dec 20 13:27:14 2010 -0800
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+"""verlist extension, to list mercurial repository tags
+
+List the tags in a mercurial repo, separated by spaces.  The tags can be
+restricted to a specified range and certain "uninteresting" tags skipped.  The
+intended use is to generate a list of mercurial versions that should be tested.
+
+"""
+
+from mercurial import commands
+from mercurial import context
+from mercurial import ui
+from mercurial.i18n import _
+
+def splitrevspec(revspec):
+    """revrange is a string, e.g., rev, rev:, rev1:rev2, :rev, :"""
+    idx = revspec.find(':')
+    if idx < 0:
+        return revspec, revspec
+    return revspec[:idx], revspec[idx+1:]
+
+def tagslist(repo, beg_rev, end_rev):
+    tags = repo.tagslist()
+    i = 0
+    while context.changectx(repo, tags[i][1]).rev() < beg_rev:
+        i += 1
+    j = len(tags) - 1
+    while context.changectx(repo, tags[j][1]).rev() > end_rev:
+        j -= 1
+    return tags[i:j + 1]
+        
+def _verlist(repo, revspec):
+    beg, end = splitrevspec(revspec)
+    beg = beg and context.changectx(repo, beg).rev() or 0
+    end = context.changectx(repo, end or 'tip').rev()
+    return tagslist(repo, beg, end)
+
+def _lastmicro(tlist):
+    lastmicro = ''
+    tags = [tlist[0]] # always include the first tag
+    for tag in tlist[1:]:
+        pos = tag.find('.')
+        if pos > 0 and tag.find('.', pos + 1) > 0:
+            lastmicro = tag
+        else:
+            if lastmicro:
+                tags.append(lastmicro)
+                lastmicro = ''
+            tags.append(tag)
+    if lastmicro:
+        tags.append(lastmicro)
+    return tags
+
+def verlist(ui, repo, *pats, **opts):
+    """List the tags in a repo, separated by spaces.
+
+    If one or more rev_ranges are given, limit the tags to the specified ranges.
+    By default, all tags are listed.
+
+    The --lastmicro option causes only list the last micro version within a
+    minor version family to be listed.  Given a repo with tags 1.0, 1.0.1,
+    1.0.2, 1.0.3, and 1.1, 1.1.1, 1.1.2, --lastmicro would list the following
+    tags:  1.0, 1.0.3, 1.1, 1.1.2.
+
+    """
+
+    tags = []
+    for revspec in pats or [':']:
+        tags += _verlist(repo, revspec)
+    tags = [x[0] for x in tags] # Just the tag names
+    if opts.get('lastmicro'):
+        tags = _lastmicro(tags)
+    ui.write(' '.join(tags))
+    ui.write('\n')
+
+cmdtable = {
+    '^verlist':
+        (verlist,
+         [('l', 'lastmicro', None,
+           _('list only the last micro version in a minor version family'))],
+         _('[rev_range] ...'))
+    }
--- a/trees.py	Fri Dec 17 10:22:38 2010 -0800
+++ b/trees.py	Mon Dec 20 13:27:14 2010 -0800
@@ -410,8 +410,14 @@
     ui.status('trees extension (version 0.7)\n')
 
 def debugkeys(ui, src, **opts):
-    repo = hg.repository(ui, src)
-    print(repo.listkeys('trees'))
+    d = hg.repository(ui, src).listkeys('trees')
+    i = 0
+    n = len(d)
+    while i < n:
+        istr = str(i)
+        ui.write("%s: %s\n" % (istr, d[istr]))
+        i += 1
+    return 0
 
 # ----------------------------- mercurial linkage ------------------------------
 
@@ -474,17 +480,17 @@
 
 def _treeslistkeys(repo):
     # trees are ordered, so the keys are the non-negative integers.
-    s = {}
+    d = {}
     i = 0
     try:
         for line in repo.opener('trees'):
-            s[("%d" % i)] = line.rstrip('\n\r')
+            d[("%d" % i)] = line.rstrip('\n\r')
             i += 1
-        return s
+        return d
     except:
         return {}
 
 def reposetup(ui, repo):
-    if r.capable('pushkey'):
+    if repo.capable('pushkey'):
         # Pushing keys is disabled; unclear whether/how it should work.
         pushkey.register('trees', lambda *x: False, _treeslistkeys)