changeset 2262:3d48eb68f3ee

merge with crew.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Thu, 11 May 2006 08:48:52 -0700
parents 20cf545b4725 (current diff) 99d6cae511f7 (diff)
children 2f64cbaa1e92 fdb699b5e132
files mercurial/util.py
diffstat 15 files changed, 499 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags
+++ b/.hgtags
@@ -10,3 +10,4 @@ eac9c8efcd9bd8244e72fb6821f769f450457a32
 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
 3a56574f329a368d645853e0f9e09472aee62349 0.8
 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
+35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,25 @@ PREFIX=/usr/local
 export PREFIX
 PYTHON=python
 
-all: local build doc
+help:
+	@echo 'Commonly used make targets:'
+	@echo '  all          - build program and documentation'
+	@echo '  install      - install program and man pages to PREFIX ($(PREFIX))'
+	@echo '  install-home - install with setup.py install --home=HOME ($(HOME))'
+	@echo '  local        - build C extensions for inplace usage'
+	@echo '  tests        - run all tests in the automatic test suite'
+	@echo '  test-foo     - run only specified tests (e.g. test-merge1)'
+	@echo '  dist         - run all tests and create a source tarball in dist/'
+	@echo '  clean        - remove files created by other targets'
+	@echo '                 (except installed files or dist source tarball)'
+	@echo
+	@echo 'Example for a system-wide installation under /usr/local:'
+	@echo '  make all && su -c "make install" && hg version'
+	@echo
+	@echo 'Example for a local installation (usable in this directory):'
+	@echo '  make local && ./hg version'
+
+all: build doc
 
 local:
 	$(PYTHON) setup.py build_ext -i
@@ -16,6 +34,7 @@ doc:
 clean:
 	-$(PYTHON) setup.py clean --all # ignore errors of this command
 	find . -name '*.py[co]' -exec rm -f '{}' ';'
+	rm -f MANIFEST mercurial/__version__.py mercurial/*.so tests/*.err
 	$(MAKE) -C doc clean
 
 install: all
@@ -38,5 +57,5 @@ test-%:
 	cd tests && $(PYTHON) run-tests.py $@
 
 
-.PHONY: all local build doc clean install install-home dist dist-notests tests
+.PHONY: help all local build doc clean install install-home dist dist-notests tests
 
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -50,7 +50,7 @@ class bundlerevlog(revlog.revlog):
                 continue
             for p in (p1, p2):
                 if not p in self.nodemap:
-                    raise RevlogError(_("unknown parent %s") % short(p1))
+                    raise revlog.RevlogError(_("unknown parent %s") % short(p1))
             if linkmapper is None:
                 link = n
             else:
@@ -76,12 +76,12 @@ class bundlerevlog(revlog.revlog):
             return False
         return rev in self.basemap
     def bundlebase(self, rev): return self.basemap[rev]
-    def chunk(self, rev, df=None):
+    def chunk(self, rev, df=None, cachelen=4096):
         # Warning: in case of bundle, the diff is against bundlebase,
         # not against rev - 1
         # XXX: could use some caching
         if not self.bundle(rev):
-            return revlog.revlog.chunk(self, rev)
+            return revlog.revlog.chunk(self, rev, df, cachelen)
         self.bundlefile.seek(self.start(rev))
         return self.bundlefile.read(self.length(rev))
 
@@ -123,8 +123,8 @@ class bundlerevlog(revlog.revlog):
 
         p1, p2 = self.parents(node)
         if node != revlog.hash(text, p1, p2):
-            raise RevlogError(_("integrity check failed on %s:%d")
-                          % (self.datafile, self.rev(node)))
+            raise revlog.RevlogError(_("integrity check failed on %s:%d")
+                                     % (self.datafile, self.rev(node)))
 
         self.cache = (node, self.rev(node), text)
         return text
@@ -160,7 +160,6 @@ class bundlerepository(localrepo.localre
     def __init__(self, ui, path, bundlename):
         localrepo.localrepository.__init__(self, ui, path)
         f = open(bundlename, "rb")
-        s = util.fstat(f)
         self.bundlefile = f
         header = self.bundlefile.read(6)
         if not header.startswith("HG"):
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -756,13 +756,20 @@ def archive(ui, repo, dest, **opts):
 def backout(ui, repo, rev, **opts):
     '''reverse effect of earlier changeset
 
-    Commit the backed out changes as a new changeset.
+    Commit the backed out changes as a new changeset.  The new
+    changeset is a child of the backed out changeset.
 
     If you back out a changeset other than the tip, a new head is
-    created.  The --merge option remembers the parent of the working
-    directory before starting the backout, then merges the new head
-    with it afterwards, to save you from doing this by hand.  The
-    result of this merge is not committed, as for a normal merge.'''
+    created.  This head is the parent of the working directory.  If
+    you back out an old changeset, your working directory will appear
+    old after the backout.  You should merge the backout changeset
+    with another head.
+
+    The --merge option remembers the parent of the working directory
+    before starting the backout, then merges the new head with that
+    changeset afterwards.  This saves you from doing the merge by
+    hand.  The result of this merge is not committed, as for a normal
+    merge.'''
 
     bail_if_changed(repo)
     op1, op2 = repo.dirstate.parents()
@@ -3021,7 +3028,7 @@ table = {
     "recover": (recover, [], _('hg recover')),
     "^remove|rm":
         (remove,
-         [('', 'after', None, _('record remove that has already occurred')),
+         [('A', 'after', None, _('record remove that has already occurred')),
           ('f', 'force', None, _('remove file even if modified')),
           ('I', 'include', [], _('include names matching the given patterns')),
           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
@@ -3096,7 +3103,7 @@ table = {
          [('u', 'update', None,
            _('update the working directory to tip after unbundle'))],
          _('hg unbundle [-u] FILE')),
-    "undo": (undo, [], _('hg undo')),
+    "debugundo|undo": (undo, [], _('hg undo')),
     "^update|up|checkout|co":
         (update,
          [('b', 'branch', '', _('checkout the head of a specific branch')),
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1544,8 +1544,9 @@ class localrepository(object):
                          " with %d changes to %d files%s\n")
                          % (changesets, revisions, files, heads))
 
-        self.hook('pretxnchangegroup', throw=True,
-                  node=hex(self.changelog.node(cor+1)), source=srctype)
+        if changesets > 0:
+            self.hook('pretxnchangegroup', throw=True,
+                      node=hex(self.changelog.node(cor+1)), source=srctype)
 
         tr.close()
 
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -9,6 +9,15 @@ from demandload import demandload
 import struct, bdiff, util, mpatch
 demandload(globals(), "re")
 
+def splitnewlines(text):
+    '''like str.splitlines, but only split on newlines.'''
+    lines = [l + '\n' for l in text.split('\n')]
+    if lines:
+        if lines[-1] == '\n':
+            lines.pop()
+        else:
+            lines[-1] = lines[-1][:-1]
+    return lines
 
 def unidiff(a, ad, b, bd, fn, r=None, text=False,
             showfunc=False, ignorews=False):
@@ -19,7 +28,7 @@ def unidiff(a, ad, b, bd, fn, r=None, te
     if not text and (util.binary(a) or util.binary(b)):
         l = ['Binary file %s has changed\n' % fn]
     elif not a:
-        b = b.splitlines(1)
+        b = splitnewlines(b)
         if a is None:
             l1 = "--- %s\t%s\n" % ("/dev/null", epoch)
         else:
@@ -28,7 +37,7 @@ def unidiff(a, ad, b, bd, fn, r=None, te
         l3 = "@@ -0,0 +1,%d @@\n" % len(b)
         l = [l1, l2, l3] + ["+" + e for e in b]
     elif not b:
-        a = a.splitlines(1)
+        a = splitnewlines(a)
         l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
         if b is None:
             l2 = "+++ %s\t%s\n" % ("/dev/null", epoch)
@@ -37,8 +46,8 @@ def unidiff(a, ad, b, bd, fn, r=None, te
         l3 = "@@ -1,%d +0,0 @@\n" % len(a)
         l = [l1, l2, l3] + ["-" + e for e in a]
     else:
-        al = a.splitlines(1)
-        bl = b.splitlines(1)
+        al = splitnewlines(a)
+        bl = splitnewlines(b)
         l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
                           showfunc=showfunc, ignorews=ignorews))
         if not l: return ""
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -87,6 +87,13 @@ class lazyparser(object):
     """
     this class avoids the need to parse the entirety of large indices
     """
+
+    # lazyparser is not safe to use on windows if win32 extensions not
+    # available. it keeps file handle open, which make it not possible
+    # to break hardlinks on local cloned repos.
+    safe_to_use = os.name != 'nt' or (not util.is_win_9x() and
+                                      hasattr(util, 'win32api'))
+
     def __init__(self, dataf, size, indexformat, shaoffset):
         self.dataf = dataf
         self.format = indexformat
@@ -362,18 +369,14 @@ class revlog(object):
             shaoffset = ngshaoffset
 
         if i:
-            if not self.inlinedata() and st and st.st_size > 10000:
+            if (lazyparser.safe_to_use and not self.inlinedata() and
+                st and st.st_size > 10000):
                 # big index, let's parse it on demand
                 parser = lazyparser(f, st.st_size, self.indexformat, shaoffset)
                 self.index = lazyindex(parser)
                 self.nodemap = lazymap(parser)
             else:
-                i = f.read()
-                self.parseindex(i)
-            if self.inlinedata():
-                # we've already got the entire data file read in, save it
-                # in the chunk data
-                self.chunkcache = (0, i)
+                self.parseindex(f, st)
             if self.version != REVLOGV0:
                 e = list(self.index[0])
                 type = self.ngtype(e[0])
@@ -384,22 +387,49 @@ class revlog(object):
             self.index = []
 
 
-    def parseindex(self, data):
+    def parseindex(self, fp, st):
         s = struct.calcsize(self.indexformat)
-        l = len(data)
         self.index = []
         self.nodemap =  {nullid: -1}
         inline = self.inlinedata()
-        off = 0
         n = 0
-        while off < l:
-            e = struct.unpack(self.indexformat, data[off:off + s])
-            self.index.append(e)
-            self.nodemap[e[-1]] = n
-            n += 1
-            off += s
-            if inline:
-                off += e[1]
+        leftover = None
+        while True:
+            if st:
+                data = fp.read(65536)
+            else:
+                # hack for httprangereader, it doesn't do partial reads well
+                data = fp.read()
+            if not data:
+                break
+            if n == 0 and self.inlinedata():
+                # cache the first chunk
+                self.chunkcache = (0, data)
+            off = 0
+            l = len(data)
+            while off < l:
+                if l - off < s:
+                    leftover = data[off:]
+                    break
+                if leftover:
+                    cur = leftover + data[off:off + s - len(leftover)]
+                    off += s - len(leftover)
+                    leftover = None
+                else:
+                    cur = data[off:off + s]
+                    off += s
+                e = struct.unpack(self.indexformat, cur)
+                self.index.append(e)
+                self.nodemap[e[-1]] = n
+                n += 1
+                if inline:
+                    off += e[1]
+                    if off > l:
+                        # some things don't seek well, just read it
+                        fp.read(off - l)
+            if not st:
+                break
+                
 
     def ngoffset(self, q):
         if q & 0xFFFF:
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -489,6 +489,13 @@ def fstat(fp):
 
 posixfile = file
 
+def is_win_9x():
+    '''return true if run on windows 95, 98 or me.'''
+    try:
+        return sys.getwindowsversion()[3] == 1
+    except AttributeError:
+        return os.name == 'nt' and 'command' in os.environ.get('comspec', '')
+
 # Platform specific variants
 if os.name == 'nt':
     demandload(globals(), "msvcrt")
@@ -570,6 +577,8 @@ if os.name == 'nt':
     try:
         # override functions with win32 versions if possible
         from util_win32 import *
+        if not is_win_9x():
+            posixfile = posixfile_nt
     except ImportError:
         pass
 
--- a/mercurial/util_win32.py
+++ b/mercurial/util_win32.py
@@ -183,11 +183,11 @@ def system_rcpath_win32():
     filename = win32process.GetModuleFileNameEx(proc, 0)
     return [os.path.join(os.path.dirname(filename), 'mercurial.ini')]
 
-class posixfile(object):
+class posixfile_nt(object):
     '''file object with posix-like semantics.  on windows, normal
     files can not be deleted or renamed if they are open. must open
     with win32file.FILE_SHARE_DELETE. this flag does not exist on
-    windows <= nt.'''
+    windows < nt, so do not use this class there.'''
 
     # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
     # but does not work at all. wrap win32 file api instead.
@@ -220,6 +220,10 @@ class posixfile(object):
         self.name = name
         self.mode = mode
 
+    def __iter__(self):
+        for line in self.read().splitlines(True):
+            yield line
+
     def read(self, count=-1):
         try:
             cs = cStringIO.StringIO()
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -34,10 +34,25 @@ def vlog(*msg):
             print m,
         print
 
+def splitnewlines(text):
+    '''like str.splitlines, but only split on newlines.
+    keep line endings.'''
+    i = 0
+    lines = []
+    while True:
+        n = text.find('\n', i)
+        if n == -1:
+            last = text[i:]
+            if last:
+                lines.append(last)
+            return lines
+        lines.append(text[i:n+1])
+        i = n + 1
+
 def show_diff(expected, output):
     for line in difflib.unified_diff(expected, output,
             "Expected output", "Test output", lineterm=''):
-        print line
+        sys.stdout.write(line)
 
 def find_program(program):
     """Search PATH for a executable program"""
@@ -125,7 +140,7 @@ def output_coverage():
         vlog("# Running: "+cmd)
         os.system(cmd)
 
-def run(cmd, split_lines=True):
+def run(cmd):
     """Run command in a sub-process, capturing the output (stdout and stderr).
     Return the exist code, and output."""
     # TODO: Use subprocess.Popen if we're running on Python 2.4
@@ -141,9 +156,7 @@ def run(cmd, split_lines=True):
         proc.tochild.close()
         output = proc.fromchild.read()
         ret = proc.wait()
-    if split_lines:
-        output = output.splitlines()
-    return ret, output
+    return ret, splitnewlines(output)
 
 def run_one(test):
     vlog("# Test", test)
@@ -180,22 +193,23 @@ def run_one(test):
     # If reference output file exists, check test output against it
     if os.path.exists(ref):
         f = open(ref, "r")
-        ref_out = f.read().splitlines()
+        ref_out = splitnewlines(f.read())
         f.close()
-        if out != ref_out:
-            diffret = 1
-            print "\nERROR: %s output changed" % (test)
-            show_diff(ref_out, out)
+    else:
+        ref_out = ['']
+    if out != ref_out:
+        diffret = 1
+        print "\nERROR: %s output changed" % (test)
+        show_diff(ref_out, out)
     if ret:
         print "\nERROR: %s failed with error code %d" % (test, ret)
     elif diffret:
         ret = diffret
 
     if ret != 0: # Save errors to a file for diagnosis
-        f = open(err, "w")
+        f = open(err, "wb")
         for line in out:
             f.write(line)
-            f.write("\n")
         f.close()
 
     os.chdir(TESTDIR)
@@ -228,24 +242,28 @@ PYTHONDIR = os.path.join(INST, "lib", "p
 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
 
 try:
-    install_hg()
+    try:
+        install_hg()
 
-    tests = 0
-    failed = 0
+        tests = 0
+        failed = 0
 
-    if len(args) == 0:
-        args = os.listdir(".")
-    for test in args:
-        if test.startswith("test-"):
-            if '~' in test or re.search(r'\.(out|err)$', test):
-                continue
-            if not run_one(test):
-                failed += 1
-            tests += 1
+        if len(args) == 0:
+            args = os.listdir(".")
+        for test in args:
+            if test.startswith("test-"):
+                if '~' in test or re.search(r'\.(out|err)$', test):
+                    continue
+                if not run_one(test):
+                    failed += 1
+                tests += 1
 
-    print "\n# Ran %d tests, %d failed." % (tests, failed)
-    if coverage:
-        output_coverage()
+        print "\n# Ran %d tests, %d failed." % (tests, failed)
+        if coverage:
+            output_coverage()
+    except KeyboardInterrupt:
+        failed = True
+        print "\ninterrupted!"
 finally:
     cleanup_exit()
 
new file mode 100755
--- /dev/null
+++ b/tests/test-diff-newlines
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+hg init
+python -c 'print "confuse str.splitlines\nembedded\rnewline"' > a
+hg ci -Ama -d '1 0'
+echo clean diff >> a
+hg ci -mb -d '2 0'
+hg diff -r0 -r1
new file mode 100644
--- /dev/null
+++ b/tests/test-diff-newlines.out
@@ -0,0 +1,8 @@
+adding a
+diff -r 107ba6f817b5 -r 310ce7989cdc a
+--- a/a	Thu Jan 01 00:00:01 1970 +0000
++++ b/a	Thu Jan 01 00:00:02 1970 +0000
+@@ -1,2 +1,3 @@ confuse str.splitlines
+ confuse str.splitlines
+ embedded
newline
++clean diff
--- a/tests/test-help.out
+++ b/tests/test-help.out
@@ -77,7 +77,6 @@ list of commands (use "hg help -v" to sh
  tags       list repository tags
  tip        show the tip revision
  unbundle   apply a changegroup file
- undo       undo the last commit or pull (DEPRECATED)
  update     update or merge working directory
  verify     verify the integrity of the repository
  version    output version and copyright information
@@ -120,7 +119,6 @@ list of commands (use "hg help -v" to sh
  tags       list repository tags
  tip        show the tip revision
  unbundle   apply a changegroup file
- undo       undo the last commit or pull (DEPRECATED)
  update     update or merge working directory
  verify     verify the integrity of the repository
  version    output version and copyright information
new file mode 100755
--- /dev/null
+++ b/tests/test-incoming-outgoing
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+mkdir test
+cd test
+hg init
+for i in 0 1 2 3 4 5 6 7 8; do
+	echo $i >> foo
+	hg commit -A -m $i -d "1000000 0"
+done
+hg verify
+hg serve -p 20059 -d --pid-file=hg.pid
+cd ..
+
+hg init new
+# http incoming
+http_proxy= hg -R new incoming http://localhost:20059/
+# local incoming
+hg -R new incoming test
+
+# test with --bundle
+http_proxy= hg -R new incoming --bundle test.hg http://localhost:20059/
+hg -R new incoming --bundle test2.hg test
+
+# test the resulting bundles
+hg init temp
+hg init temp2
+hg -R temp unbundle test.hg
+hg -R temp2 unbundle test2.hg
+hg -R temp tip
+hg -R temp2 tip
+
+rm -rf temp temp2 new
+
+# test outgoing
+hg clone test test-dev
+cd test-dev
+for i in 9 10 11 12 13; do
+	echo $i >> foo
+	hg commit -A -m $i -d "1000000 0"
+done
+hg verify
+cd ..
+hg -R test-dev outgoing test
+http_proxy= hg -R test-dev outgoing http://localhost:20059/
+
+kill `cat test/hg.pid`
new file mode 100644
--- /dev/null
+++ b/tests/test-incoming-outgoing.out
@@ -0,0 +1,272 @@
+adding foo
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 9 changesets, 9 total revisions
+changeset:   0:9cb21d99fe27
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     0
+
+changeset:   1:d717f5dfad6a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     1
+
+changeset:   2:c0d6b86da426
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     2
+
+changeset:   3:dfacbd43b3fe
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     3
+
+changeset:   4:1f3a964b6022
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     4
+
+changeset:   5:c028bcc7a28a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     5
+
+changeset:   6:a0c0095f3389
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     6
+
+changeset:   7:d4be65f4e891
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     7
+
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+changeset:   0:9cb21d99fe27
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     0
+
+changeset:   1:d717f5dfad6a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     1
+
+changeset:   2:c0d6b86da426
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     2
+
+changeset:   3:dfacbd43b3fe
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     3
+
+changeset:   4:1f3a964b6022
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     4
+
+changeset:   5:c028bcc7a28a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     5
+
+changeset:   6:a0c0095f3389
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     6
+
+changeset:   7:d4be65f4e891
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     7
+
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+changeset:   0:9cb21d99fe27
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     0
+
+changeset:   1:d717f5dfad6a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     1
+
+changeset:   2:c0d6b86da426
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     2
+
+changeset:   3:dfacbd43b3fe
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     3
+
+changeset:   4:1f3a964b6022
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     4
+
+changeset:   5:c028bcc7a28a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     5
+
+changeset:   6:a0c0095f3389
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     6
+
+changeset:   7:d4be65f4e891
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     7
+
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+changeset:   0:9cb21d99fe27
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     0
+
+changeset:   1:d717f5dfad6a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     1
+
+changeset:   2:c0d6b86da426
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     2
+
+changeset:   3:dfacbd43b3fe
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     3
+
+changeset:   4:1f3a964b6022
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     4
+
+changeset:   5:c028bcc7a28a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     5
+
+changeset:   6:a0c0095f3389
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     6
+
+changeset:   7:d4be65f4e891
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     7
+
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+adding changesets
+adding manifests
+adding file changes
+added 9 changesets with 9 changes to 1 files
+(run 'hg update' to get a working copy)
+adding changesets
+adding manifests
+adding file changes
+added 9 changesets with 9 changes to 1 files
+(run 'hg update' to get a working copy)
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+changeset:   8:92b83e334ef8
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     8
+
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 14 changesets, 14 total revisions
+searching for changes
+changeset:   9:3741c3ad1096
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     9
+
+changeset:   10:de4143c8d9a5
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     10
+
+changeset:   11:0e1c188b9a7a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     11
+
+changeset:   12:251354d0fdd3
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     12
+
+changeset:   13:bdaadd969642
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     13
+
+searching for changes
+changeset:   9:3741c3ad1096
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     9
+
+changeset:   10:de4143c8d9a5
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     10
+
+changeset:   11:0e1c188b9a7a
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     11
+
+changeset:   12:251354d0fdd3
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     12
+
+changeset:   13:bdaadd969642
+tag:         tip
+user:        test
+date:        Mon Jan 12 13:46:40 1970 +0000
+summary:     13
+