Merge with crew
authorBrendan Cully <brendan@kublai.com>
Fri, 12 Dec 2008 12:34:57 -0800
changeset 7511 f43a8b0ca3e8
parent 7510 21009e85ee78 (current diff)
parent 7508 b3ae5d52c405 (diff)
child 7518 dd66d161a14b
Merge with crew
hgext/convert/cvsps
--- a/doc/hgrc.5.txt	Thu Dec 04 11:21:31 2008 -0800
+++ b/doc/hgrc.5.txt	Fri Dec 12 12:34:57 2008 -0800
@@ -219,7 +219,7 @@
     convenient for recipients. Addresses, headers, and parts not
     containing patches of outgoing messages will be encoded in
     the first charset to which conversion from local encoding
-    (ui.encoding, ui.fallbackencoding) succeeds. If correct
+    ($HGENCODING, ui.fallbackencoding) succeeds. If correct
     conversion fails, the text in question is sent as is.
     Defaults to empty (explicit) list.
 
@@ -228,7 +228,7 @@
     us-ascii             always first, regardless of settings
     email.charsets       in order given by user
     ui.fallbackencoding  if not in email.charsets
-    ui.encoding          if not in email.charsets
+    $HGENCODING          if not in email.charsets
     utf-8                always last, regardless of settings
 
   Email example:
--- a/hgext/bookmarks.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/bookmarks.py	Fri Dec 12 12:34:57 2008 -0800
@@ -14,9 +14,19 @@
 
 It is possible to use bookmark names in every revision lookup (e.g. hg
 merge, hg update).
+
+The bookmark extension offers the possiblity to have a more git-like experience
+by adding the following configuration option to your .hgrc:
+
+[bookmarks]
+track.current = True
+
+This will cause bookmarks to track the bookmark that you are currently on, and
+just updates it. This is similar to git's approach of branching.
 '''
 
 from mercurial.commands import templateopts, hex, short
+from mercurial import extensions
 from mercurial.i18n import _
 from mercurial import cmdutil, util, commands, changelog
 from mercurial.node import nullid, nullrev
@@ -55,10 +65,53 @@
     if os.path.exists(repo.join('bookmarks')):
         util.copyfile(repo.join('bookmarks'), repo.join('undo.bookmarks'))
     file = repo.opener('bookmarks', 'w+')
+    if current(repo) not in refs:
+        setcurrent(repo, None)
     for refspec, node in refs.items():
         file.write("%s %s\n" % (hex(node), refspec))
     file.close()
 
+def current(repo):
+    '''Get the current bookmark
+
+    If we use gittishsh branches we have a current bookmark that
+    we are on. This function returns the name of the bookmark. It
+    is stored in .hg/bookmarks.current
+    '''
+    if repo._bookmarkcurrent:
+        return repo._bookmarkcurrent
+    mark = None
+    if os.path.exists(repo.join('bookmarks.current')):
+        file = repo.opener('bookmarks.current')
+        mark = file.readline()
+        if mark == '':
+            mark = None
+        file.close()
+    repo._bookmarkcurrent = mark
+    return mark
+
+def setcurrent(repo, mark):
+    '''Set the name of the bookmark that we are currently on
+
+    Set the name of the bookmark that we are on (hg update <bookmark>).
+    The name is recoreded in .hg/bookmarks.current
+    '''
+    if current(repo) == mark:
+        return
+
+    refs = parse(repo)
+
+    # do not update if we do update to a rev equal to the current bookmark
+    if (mark not in refs and
+        current(repo) and refs[current(repo)] == repo.changectx('.').node()):
+        return
+    if mark not in refs:
+        mark = ''
+    file = repo.opener('bookmarks.current', 'w+')
+    file.write(mark)
+    file.close()
+    repo._bookmarkcurrent = mark
+
 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
     '''mercurial bookmarks
 
@@ -121,7 +174,11 @@
             ui.status("no bookmarks set\n")
         else:
             for bmark, n in marks.iteritems():
-                prefix = (n == cur) and '*' or ' '
+                if ui.configbool('bookmarks', 'track.current'):
+                    prefix = (bmark == current(repo) and n == cur) and '*' or ' '
+                else:
+                    prefix = (n == cur) and '*' or ' '
+
                 ui.write(" %s %-25s %d:%s\n" % (
                     prefix, bmark, repo.changelog.rev(n), hexfn(n)))
         return
@@ -166,6 +223,7 @@
     # init a bookmark cache as otherwise we would get a infinite reading
     # in lookup()
     repo._bookmarks = None
+    repo._bookmarkcurrent = None
 
     class bookmark_repo(repo.__class__):
         def rollback(self):
@@ -192,9 +250,14 @@
             marks = parse(repo)
             update = False
             for mark, n in marks.items():
-                if n in parents:
-                    marks[mark] = node
-                    update = True
+                if ui.configbool('bookmarks', 'track.current'):
+                    if mark == current(repo) and n in parents:
+                        marks[mark] = node
+                        update = True
+                else:
+                    if n in parents:
+                        marks[mark] = node
+                        update = True
             if update:
                 write(repo, marks)
             return node
@@ -218,8 +281,35 @@
                 write(repo, marks)
             return result
 
+        def tags(self):
+            """Merge bookmarks with normal tags"""
+            if self.tagscache:
+                return self.tagscache
+
+            tagscache = super(bookmark_repo, self).tags()
+            tagscache.update(parse(repo))
+            return tagscache
+
     repo.__class__ = bookmark_repo
 
+def updatecurbookmark(orig, ui, repo, *args, **opts):
+    '''Set the current bookmark
+
+    If the user updates to a bookmark we update the .hg/bookmarks.current
+    file.
+    '''
+    res = orig(ui, repo, *args, **opts)
+    rev = opts['rev']
+    if not rev and len(args) > 0:
+        rev = args[0]
+    setcurrent(repo, rev)
+    return res
+
+def uisetup(ui):
+    'Replace push with a decorator to provide --non-bookmarked option'
+    if ui.configbool('bookmarks', 'track.current'):
+        extensions.wrapcommand(commands.table, 'update', updatecurbookmark)
+
 cmdtable = {
     "bookmarks":
         (bookmark,
--- a/hgext/bugzilla.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/bugzilla.py	Fri Dec 12 12:34:57 2008 -0800
@@ -4,53 +4,107 @@
 #
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
-#
-# hook extension to update comments of bugzilla bugs when changesets
-# that refer to bugs by id are seen.  this hook does not change bug
-# status, only comments.
-#
-# to configure, add items to '[bugzilla]' section of hgrc.
-#
-# to use, configure bugzilla extension and enable like this:
-#
-#   [extensions]
-#   hgext.bugzilla =
-#
-#   [hooks]
-#   # run bugzilla hook on every change pulled or pushed in here
-#   incoming.bugzilla = python:hgext.bugzilla.hook
-#
-# config items:
-#
-# section name is 'bugzilla'.
-#  [bugzilla]
-#
-# REQUIRED:
-#   host = bugzilla # mysql server where bugzilla database lives
-#   password = **   # user's password
-#   version = 2.16  # version of bugzilla installed
-#
-# OPTIONAL:
-#   bzuser = ...    # fallback bugzilla user name to record comments with
-#   db = bugs       # database to connect to
-#   notify = ...    # command to run to get bugzilla to send mail
-#   regexp = ...    # regexp to match bug ids (must contain one "()" group)
-#   strip = 0       # number of slashes to strip for url paths
-#   style = ...     # style file to use when formatting comments
-#   template = ...  # template to use when formatting comments
-#   timeout = 5     # database connection timeout (seconds)
-#   user = bugs     # user to connect to database as
-#   [web]
-#   baseurl = http://hgserver/... # root of hg web site for browsing commits
-#
-# if hg committer names are not same as bugzilla user names, use
-# "usermap" feature to map from committer email to bugzilla user name.
-# usermap can be in hgrc or separate config file.
-#
-#   [bugzilla]
-#   usermap = filename # cfg file with "committer"="bugzilla user" info
-#   [usermap]
-#   committer_email = bugzilla_user_name
+
+'''Bugzilla integration
+
+This hook extension adds comments on bugs in Bugzilla when changesets
+that refer to bugs by Bugzilla ID are seen. The hook does not change bug
+status.
+
+The hook updates the Bugzilla database directly. Only Bugzilla installations
+using MySQL are supported.
+
+The hook relies on a Bugzilla script to send bug change notification emails.
+That script changes between Bugzilla versions; the 'processmail' script used
+prior to 2.18 is replaced in 2.18 and subsequent versions by
+'config/sendbugmail.pl'. Note that these will be run by Mercurial as the user
+pushing the change; you will need to ensure the Bugzilla install file
+permissions are set appropriately.
+
+Configuring the extension:
+
+    [bugzilla]
+    host       Hostname of the MySQL server holding the Bugzilla database.
+    db         Name of the Bugzilla database in MySQL. Default 'bugs'.
+    user       Username to use to access MySQL server. Default 'bugs'.
+    password   Password to use to access MySQL server.
+    timeout    Database connection timeout (seconds). Default 5.
+    version    Bugzilla version. Specify '3.0' for Bugzilla versions from
+               3.0 onwards, and '2.16' for versions prior to 3.0.
+    bzuser     Fallback Bugzilla user name to record comments with, if
+               changeset committer cannot be found as a Bugzilla user.
+    notify     The command to run to get Bugzilla to send bug change
+               notification emails. Substitutes one string parameter,
+               the bug ID. Default 'cd /var/www/html/bugzilla && '
+                                   './processmail %s nobody@nowhere.com'.
+    regexp     Regular expression to match bug IDs in changeset commit message.
+               Must contain one "()" group. The default expression matches
+               'Bug 1234', 'Bug no. 1234', 'Bug number 1234',
+               'Bugs 1234,5678', 'Bug 1234 and 5678' and variations thereof.
+               Matching is case insensitive.
+    style      The style file to use when formatting comments.
+    template   Template to use when formatting comments. Overrides
+               style if specified. In addition to the usual Mercurial
+               keywords, the extension specifies:
+                   {bug}       The Bugzilla bug ID.
+                   {root}      The full pathname of the Mercurial repository.
+                   {webroot}   Stripped pathname of the Mercurial repository.
+                   {hgweb}     Base URL for browsing Mercurial repositories.
+               Default 'changeset {node|short} in repo {root} refers '
+                       'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'
+    strip      The number of slashes to strip from the front of {root}
+               to produce {webroot}. Default 0.
+    usermap    Path of file containing Mercurial committer ID to Bugzilla user
+               ID mappings. If specified, the file should contain one mapping
+               per line, "committer"="Bugzilla user". See also the
+               [usermap] section.
+
+    [usermap]
+    Any entries in this section specify mappings of Mercurial committer ID
+    to Bugzilla user ID. See also [bugzilla].usermap.
+    "committer"="Bugzilla user"
+
+    [web]
+    baseurl    Base URL for browsing Mercurial repositories. Reference from
+               templates as {hgweb}.
+
+Activating the extension:
+
+    [extensions]
+    hgext.bugzilla =
+
+    [hooks]
+    # run bugzilla hook on every change pulled or pushed in here
+    incoming.bugzilla = python:hgext.bugzilla.hook
+
+Example configuration:
+
+This example configuration is for a collection of Mercurial repositories
+in /var/local/hg/repos/ used with a local Bugzilla 3.2 installation in
+/opt/bugzilla-3.2.
+
+    [bugzilla]
+    host=localhost
+    password=XYZZY
+    version=3.0
+    bzuser=unknown@domain.com
+    notify=cd /opt/bugzilla-3.2 && perl -T contrib/sendbugmail.pl %%s bugmail@domain.com
+    template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/rev/{node|short}\\n\\n{desc}\\n
+    strip=5
+
+    [web]
+    baseurl=http://dev.domain.com/hg
+
+    [usermap]
+    user@emaildomain.com=user.name@bugzilladomain.com
+
+Commits add a comment to the Bugzilla bug record of the form:
+
+    Changeset 3b16791d6642 in repository-name.
+    http://dev.domain.com/hg/repository-name/rev/3b16791d6642
+
+    Changeset commit comment. Bug 1234.
+'''
 
 from mercurial.i18n import _
 from mercurial.node import short
@@ -185,6 +239,7 @@
         self.run('''insert into bugs_activity (bug_id, who, bug_when, fieldid)
                     values (%s, %s, %s, %s)''',
                  (bugid, userid, now, self.longdesc_id))
+        self.conn.commit()
 
 class bugzilla_3_0(bugzilla_2_16):
     '''support for bugzilla 3.0 series.'''
--- a/hgext/convert/__init__.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/convert/__init__.py	Fri Dec 12 12:34:57 2008 -0800
@@ -7,6 +7,7 @@
 '''converting foreign VCS repositories to Mercurial'''
 
 import convcmd
+import cvsps
 from mercurial import commands
 from mercurial.i18n import _
 
@@ -183,7 +184,18 @@
 def debugsvnlog(ui, **opts):
     return convcmd.debugsvnlog(ui, **opts)
 
-commands.norepo += " convert debugsvnlog"
+def debugcvsps(ui, *args, **opts):
+    '''Create changeset information from CVS
+
+    This command is intended as a debugging tool for the CVS to Mercurial
+    converter, and can be used as a direct replacement for cvsps.
+
+    Hg debugcvsps reads the CVS rlog for current directory (or any named
+    directory) in the CVS repository, and converts the log to a series of
+    changesets based on matching commit log entries and dates.'''
+    return cvsps.debugcvsps(ui, *args, **opts)
+
+commands.norepo += " convert debugsvnlog debugcvsps"
 
 cmdtable = {
     "convert":
@@ -200,4 +212,22 @@
         (debugsvnlog,
          [],
          'hg debugsvnlog'),
+    "debugcvsps":
+        (debugcvsps,
+         [
+          # Main options shared with cvsps-2.1
+          ('b', 'branches', [], _('Only return changes on specified branches')),
+          ('p', 'prefix', '', _('Prefix to remove from file names')),
+          ('r', 'revisions', [], _('Only return changes after or between specified tags')),
+          ('u', 'update-cache', None, _("Update cvs log cache")),
+          ('x', 'new-cache', None, _("Create new cvs log cache")),
+          ('z', 'fuzz', 60, _('Set commit time fuzz in seconds')),
+          ('', 'root', '', _('Specify cvsroot')),
+          # Options specific to builtin cvsps
+          ('', 'parents', '', _('Show parent changesets')),
+          ('', 'ancestors', '', _('Show current changeset in ancestor branches')),
+          # Options that are ignored for compatibility with cvsps-2.1
+          ('A', 'cvs-direct', None, 'Ignored for compatibility'),
+         ],
+         'hg debugcvsps [OPTION]... [PATH]...'),
 }
--- a/hgext/convert/cvs.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/convert/cvs.py	Fri Dec 12 12:34:57 2008 -0800
@@ -144,11 +144,11 @@
                             if branch == "HEAD":
                                 branch = ""
                             if branch:
-                                latest = None
+                                latest = 0
                                 # the last changeset that contains a base
                                 # file is our parent
                                 for r in oldrevs:
-                                    latest = max(filerevids.get(r, None), latest)
+                                    latest = max(filerevids.get(r, 0), latest)
                                 if latest:
                                     p = [latest]
 
--- a/hgext/convert/cvsps	Thu Dec 04 11:21:31 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-#
-# Commandline front-end for cvsps.py
-#
-# Copyright 2008, Frank Kingswood <frank@kingswood-consulting.co.uk>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
-
-import sys
-from mercurial import util
-from mercurial.i18n import _
-from optparse import OptionParser, SUPPRESS_HELP
-from hgext.convert.cvsps import createlog, createchangeset, logerror
-
-def main():
-    '''Main program to mimic cvsps.'''
-
-    op = OptionParser(usage='%prog [-bpruvxz] path',
-                      description='Read CVS rlog for current directory or named '
-                                  'path in repository, and convert the log to changesets '
-                                  'based on matching commit log entries and dates.')
-
-    # Options that are ignored for compatibility with cvsps-2.1
-    op.add_option('-A', dest='Ignore', action='store_true', help=SUPPRESS_HELP)
-    op.add_option('--cvs-direct', dest='Ignore', action='store_true', help=SUPPRESS_HELP)
-    op.add_option('-q', dest='Ignore', action='store_true', help=SUPPRESS_HELP)
-
-    # Main options shared with cvsps-2.1
-    op.add_option('-b', dest='Branches', action='append', default=[],
-                  help='Only return changes on specified branches')
-    op.add_option('-p', dest='Prefix', action='store', default='',
-                  help='Prefix to remove from file names')
-    op.add_option('-r', dest='Revisions', action='append', default=[],
-                  help='Only return changes after or between specified tags')
-    op.add_option('-u', dest='Cache', action='store_const', const='update',
-                  help="Update cvs log cache")
-    op.add_option('-v', dest='Verbose', action='count', default=0,
-                  help='Be verbose')
-    op.add_option('-x', dest='Cache', action='store_const', const='write',
-                  help="Create new cvs log cache")
-    op.add_option('-z', dest='Fuzz', action='store', type='int', default=60,
-                  help='Set commit time fuzz', metavar='seconds')
-    op.add_option('--root', dest='Root', action='store', default='',
-                  help='Specify cvsroot', metavar='cvsroot')
-
-    # Options specific to this version
-    op.add_option('--parents', dest='Parents', action='store_true',
-                  help='Show parent changesets')
-    op.add_option('--ancestors', dest='Ancestors', action='store_true',
-                  help='Show current changeset in ancestor branches')
-
-    options, args = op.parse_args()
-
-    # Create a ui object for printing progress messages
-    class UI:
-        def __init__(self, verbose):
-            if verbose:
-                self.status = self.message
-            if verbose>1:
-                self.note = self.message
-            if verbose>2:
-                self.debug = self.message
-        def message(self, msg):
-            sys.stderr.write(msg)
-        def nomessage(self, msg):
-            pass
-        status = nomessage
-        note = nomessage
-        debug = nomessage
-    ui = UI(options.Verbose)
-
-    try:
-        if args:
-            log = []
-            for d in args:
-                log += createlog(ui, d, root=options.Root, cache=options.Cache)
-        else:
-            log = createlog(ui, root=options.Root, cache=options.Cache)
-    except logerror, e:
-        print e
-        return
-
-    changesets = createchangeset(ui, log, options.Fuzz)
-    del log
-
-    # Print changesets (optionally filtered)
-
-    off = len(options.Revisions)
-    branches = {}    # latest version number in each branch
-    ancestors = {}   # parent branch
-    for cs in changesets:
-
-        if options.Ancestors:
-            if cs.branch not in branches and cs.parents and cs.parents[0].id:
-                ancestors[cs.branch] = changesets[cs.parents[0].id-1].branch, cs.parents[0].id
-            branches[cs.branch] = cs.id
-
-        # limit by branches
-        if options.Branches and (cs.branch or 'HEAD') not in options.Branches:
-            continue
-
-        if not off:
-            # Note: trailing spaces on several lines here are needed to have
-            #       bug-for-bug compatibility with cvsps.
-            print '---------------------'
-            print 'PatchSet %d ' % cs.id
-            print 'Date: %s' % util.datestr(cs.date, '%Y/%m/%d %H:%M:%S %1%2')
-            print 'Author: %s' % cs.author
-            print 'Branch: %s' % (cs.branch or 'HEAD')
-            print 'Tag%s: %s ' % (['', 's'][len(cs.tags)>1],
-                                  ','.join(cs.tags) or '(none)')
-            if options.Parents and cs.parents:
-                if len(cs.parents)>1:
-                    print 'Parents: %s' % (','.join([str(p.id) for p in cs.parents]))
-                else:
-                    print 'Parent: %d' % cs.parents[0].id
-
-            if options.Ancestors:
-                b = cs.branch
-                r = []
-                while b:
-                    b, c = ancestors[b]
-                    r.append('%s:%d:%d' % (b or "HEAD", c, branches[b]))
-                if r:
-                    print 'Ancestors: %s' % (','.join(r))
-
-            print 'Log:'
-            print cs.comment
-            print
-            print 'Members: '
-            for f in cs.entries:
-                fn = f.file
-                if fn.startswith(options.Prefix):
-                    fn = fn[len(options.Prefix):]
-                print '\t%s:%s->%s%s ' % (fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL',
-                                          '.'.join([str(x) for x in f.revision]), ['', '(DEAD)'][f.dead])
-            print
-
-        # have we seen the start tag?
-        if options.Revisions and off:
-            if options.Revisions[0] == str(cs.id) or \
-                options.Revisions[0] in cs.tags:
-                off = False
-
-        # see if we reached the end tag
-        if len(options.Revisions)>1 and not off:
-            if options.Revisions[1] == str(cs.id) or \
-                options.Revisions[1] in cs.tags:
-                break
-
-
-if __name__ == '__main__':
-    main()
--- a/hgext/convert/cvsps.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/convert/cvsps.py	Fri Dec 12 12:34:57 2008 -0800
@@ -584,3 +584,95 @@
     ui.status(_('%d changeset entries\n') % len(changesets))
 
     return changesets
+
+
+def debugcvsps(ui, *args, **opts):
+    '''Read CVS rlog for current directory or named path in repository, and 
+    convert the log to changesets based on matching commit log entries and dates.'''
+
+    if opts["new_cache"]:
+        cache = "write"
+    elif opts["update_cache"]:
+        cache = "update"
+    else:
+        cache = None
+
+    revisions = opts["revisions"]
+
+    try:
+        if args:
+            log = []
+            for d in args:
+                log += createlog(ui, d, root=opts["root"], cache=cache)
+        else:
+            log = createlog(ui, root=opts["root"], cache=cache)
+    except logerror, e:
+        ui.write("%r\n"%e)
+        return
+
+    changesets = createchangeset(ui, log, opts["fuzz"])
+    del log
+
+    # Print changesets (optionally filtered)
+
+    off = len(revisions)
+    branches = {}    # latest version number in each branch
+    ancestors = {}   # parent branch
+    for cs in changesets:
+
+        if opts["ancestors"]:
+            if cs.branch not in branches and cs.parents and cs.parents[0].id:
+                ancestors[cs.branch] = changesets[cs.parents[0].id-1].branch, cs.parents[0].id
+            branches[cs.branch] = cs.id
+
+        # limit by branches
+        if opts["branches"] and (cs.branch or 'HEAD') not in opts["branches"]:
+            continue
+
+        if not off:
+            # Note: trailing spaces on several lines here are needed to have
+            #       bug-for-bug compatibility with cvsps.
+            ui.write('---------------------\n')
+            ui.write('PatchSet %d \n' % cs.id)
+            ui.write('Date: %s\n' % util.datestr(cs.date, '%Y/%m/%d %H:%M:%S %1%2'))
+            ui.write('Author: %s\n' % cs.author)
+            ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
+            ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags)>1],
+                                  ','.join(cs.tags) or '(none)'))
+            if opts["parents"] and cs.parents:
+                if len(cs.parents)>1:
+                    ui.write('Parents: %s\n' % (','.join([str(p.id) for p in cs.parents])))
+                else:
+                    ui.write('Parent: %d\n' % cs.parents[0].id)
+
+            if opts["ancestors"]:
+                b = cs.branch
+                r = []
+                while b:
+                    b, c = ancestors[b]
+                    r.append('%s:%d:%d' % (b or "HEAD", c, branches[b]))
+                if r:
+                    ui.write('Ancestors: %s\n' % (','.join(r)))
+
+            ui.write('Log:\n')
+            ui.write('%s\n\n' % cs.comment)
+            ui.write('Members: \n')
+            for f in cs.entries:
+                fn = f.file
+                if fn.startswith(opts["prefix"]):
+                    fn = fn[len(opts["prefix"]):]
+                ui.write('\t%s:%s->%s%s \n' % (fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL',
+                                          '.'.join([str(x) for x in f.revision]), ['', '(DEAD)'][f.dead]))
+            ui.write('\n')
+
+        # have we seen the start tag?
+        if revisions and off:
+            if revisions[0] == str(cs.id) or \
+                revisions[0] in cs.tags:
+                off = False
+
+        # see if we reached the end tag
+        if len(revisions)>1 and not off:
+            if revisions[1] == str(cs.id) or \
+                revisions[1] in cs.tags:
+                break
--- a/hgext/convert/subversion.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/convert/subversion.py	Fri Dec 12 12:34:57 2008 -0800
@@ -724,12 +724,6 @@
 
         self.child_cset = None
 
-        def isdescendantof(parent, child):
-            if not child or not parent or not child.startswith(parent):
-                return False
-            subpath = child[len(parent):]
-            return len(subpath) > 1 and subpath[0] == '/'
-
         def parselogentry(orig_paths, revnum, author, date, message):
             """Return the parsed commit object or None, and True if
             the revision is a branch root.
@@ -752,21 +746,10 @@
             if root_paths:
                 path, ent = root_paths[-1]
                 if ent.copyfrom_path:
-                    # If dir was moved while one of its file was removed
-                    # the log may look like:
-                    # A /dir   (from /dir:x)
-                    # A /dir/a (from /dir/a:y)
-                    # A /dir/b (from /dir/b:z)
-                    # ...
-                    # for all remaining children.
-                    # Let's take the highest child element from rev as source.
-                    copies = [(p,e) for p,e in orig_paths[:-1]
-                          if isdescendantof(ent.copyfrom_path, e.copyfrom_path)]
-                    fromrev = max([e.copyfrom_rev for p,e in copies] + [ent.copyfrom_rev])
                     branched = True
                     newpath = ent.copyfrom_path + self.module[len(path):]
                     # ent.copyfrom_rev may not be the actual last revision
-                    previd = self.latest(newpath, fromrev)
+                    previd = self.latest(newpath, ent.copyfrom_rev)
                     if previd is not None:
                         prevmodule, prevnum = self.revsplit(previd)[1:]
                         if prevnum >= self.startrev:
--- a/hgext/notify.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/notify.py	Fri Dec 12 12:34:57 2008 -0800
@@ -105,6 +105,7 @@
         self.stripcount = int(self.ui.config('notify', 'strip', 0))
         self.root = self.strip(self.repo.root)
         self.domain = self.ui.config('notify', 'domain')
+        self.test = self.ui.configbool('notify', 'test', True)
         self.charsets = mail._charsets(self.ui)
         self.subs = self.subscribers()
 
@@ -157,7 +158,8 @@
                 for user in users.split(','):
                     subs[self.fixmail(user)] = 1
         subs = util.sort(subs)
-        return [mail.addressencode(self.ui, s, self.charsets) for s in subs]
+        return [mail.addressencode(self.ui, s, self.charsets, self.test)
+                for s in subs]
 
     def url(self, path=None):
         return self.ui.config('web', 'baseurl') + (path or self.root)
@@ -186,7 +188,7 @@
         # create fresh mime message from msg body
         text = msg.get_payload()
         # for notification prefer readability over data precision
-        msg = mail.mimeencode(self.ui, text, self.charsets)
+        msg = mail.mimeencode(self.ui, text, self.charsets, self.test)
 
         def fix_subject(subject):
             '''try to make subject line exist and be useful.'''
@@ -201,7 +203,8 @@
             maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
             if maxsubject and len(subject) > maxsubject:
                 subject = subject[:maxsubject-3] + '...'
-            msg['Subject'] = mail.headencode(self.ui, subject, self.charsets)
+            msg['Subject'] = mail.headencode(self.ui, subject,
+                                             self.charsets, self.test)
 
         def fix_sender(sender):
             '''try to make message have proper sender.'''
@@ -210,7 +213,8 @@
                 sender = self.ui.config('email', 'from') or self.ui.username()
             if '@' not in sender or '@localhost' in sender:
                 sender = self.fixmail(sender)
-            msg['From'] = mail.addressencode(self.ui, sender, self.charsets)
+            msg['From'] = mail.addressencode(self.ui, sender,
+                                             self.charsets, self.test)
 
         msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
         fix_subject(subject)
@@ -224,7 +228,7 @@
         msg['To'] = ', '.join(self.subs)
 
         msgtext = msg.as_string(0)
-        if self.ui.configbool('notify', 'test', True):
+        if self.test:
             self.ui.write(msgtext)
             if not msgtext.endswith('\n'):
                 self.ui.write('\n')
--- a/hgext/rebase.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/hgext/rebase.py	Fri Dec 12 12:34:57 2008 -0800
@@ -64,6 +64,14 @@
         contf = opts.get('continue')
         abortf = opts.get('abort')
         collapsef = opts.get('collapse', False)
+        extrafn = opts.get('extrafn')
+        if opts.get('keepbranches', None):
+            if extrafn:
+                raise dispatch.ParseError('rebase',
+                        _('cannot use both keepbranches and extrafn'))
+            def extrafn(ctx, extra):
+                extra['branch'] = ctx.branch()
+
         if contf or abortf:
             if contf and abortf:
                 raise dispatch.ParseError('rebase',
@@ -101,14 +109,14 @@
                 storestatus(repo, originalwd, target, state, collapsef,
                                                                 external)
                 rebasenode(repo, rev, target, state, skipped, targetancestors,
-                                                                collapsef)
+                                                       collapsef, extrafn)
         ui.note(_('rebase merging completed\n'))
 
         if collapsef:
             p1, p2 = defineparents(repo, min(state), target,
                                                         state, targetancestors)
             concludenode(repo, rev, p1, external, state, collapsef,
-                                                last=True, skipped=skipped)
+                         last=True, skipped=skipped, extrafn=extrafn)
 
         if 'qtip' in repo.tags():
             updatemq(repo, state, skipped, **opts)
@@ -131,7 +139,8 @@
     finally:
         del lock, wlock
 
-def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped={}):
+def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped={},
+                 extrafn=None):
     """Skip commit if collapsing has been required and rev is not the last
     revision, commit otherwise
     """
@@ -155,18 +164,22 @@
         else:
             commitmsg = repo[rev].description()
         # Commit might fail if unresolved files exist
+        extra = {'rebase_source': repo[rev].hex()}
+        if extrafn:
+            extrafn(repo[rev], extra)
         newrev = repo.commit(m+a+r,
                             text=commitmsg,
                             user=repo[rev].user(),
                             date=repo[rev].date(),
-                            extra={'rebase_source': repo[rev].hex()})
+                            extra=extra)
         return newrev
     except util.Abort:
         # Invalidate the previous setparents
         repo.dirstate.invalidate()
         raise
 
-def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse):
+def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse,
+               extrafn):
     'Rebase a single revision'
     repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
 
@@ -195,7 +208,8 @@
         repo.ui.debug(_('resuming interrupted rebase\n'))
 
 
-    newrev = concludenode(repo, rev, p1, p2, state, collapse)
+    newrev = concludenode(repo, rev, p1, p2, state, collapse,
+                          extrafn=extrafn)
 
     # Update the state
     if newrev is not None:
@@ -409,6 +423,7 @@
         (rebase,
         [
         ('', 'keep', False, _('keep original revisions')),
+        ('', 'keepbranches', False, _('keep original branches')),
         ('s', 'source', '', _('rebase from a given revision')),
         ('b', 'base', '', _('rebase from the base of a given revision')),
         ('d', 'dest', '', _('rebase onto a given revision')),
--- a/mercurial/changelog.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/changelog.py	Fri Dec 12 12:34:57 2008 -0800
@@ -179,7 +179,7 @@
 
         user = user.strip()
         if "\n" in user:
-            raise RevlogError(_("username %s contains a newline") % `user`)
+            raise RevlogError(_("username %s contains a newline") % repr(user))
         user, desc = util.fromlocal(user), util.fromlocal(desc)
 
         if date:
--- a/mercurial/dispatch.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/dispatch.py	Fri Dec 12 12:34:57 2008 -0800
@@ -90,7 +90,7 @@
             else:
                 raise
     except socket.error, inst:
-        ui.warn(_("abort: %s\n") % inst[-1])
+        ui.warn(_("abort: %s\n") % inst.args[-1])
     except IOError, inst:
         if hasattr(inst, "code"):
             ui.warn(_("abort: %s\n") % inst)
@@ -100,7 +100,7 @@
             except: # it might be anything, for example a string
                 reason = inst.reason
             ui.warn(_("abort: error: %s\n") % reason)
-        elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
+        elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
             if ui.debugflag:
                 ui.warn(_("broken pipe\n"))
         elif getattr(inst, "strerror", None):
@@ -116,13 +116,13 @@
         else:
             ui.warn(_("abort: %s\n") % inst.strerror)
     except util.UnexpectedOutput, inst:
-        ui.warn(_("abort: %s") % inst[0])
-        if not isinstance(inst[1], basestring):
-            ui.warn(" %r\n" % (inst[1],))
-        elif not inst[1]:
+        ui.warn(_("abort: %s") % inst.args[0])
+        if not isinstance(inst.args[1], basestring):
+            ui.warn(" %r\n" % (inst.args[1],))
+        elif not inst.args[1]:
             ui.warn(_(" empty string\n"))
         else:
-            ui.warn("\n%r\n" % util.ellipsis(inst[1]))
+            ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
     except ImportError, inst:
         m = str(inst).split()[-1]
         ui.warn(_("abort: could not import module %s!\n") % m)
--- a/mercurial/patch.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/patch.py	Fri Dec 12 12:34:57 2008 -0800
@@ -22,17 +22,20 @@
 
 # helper functions
 
-def copyfile(src, dst, basedir=None):
-    if not basedir:
-        basedir = os.getcwd()
-
-    abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)]
+def copyfile(src, dst, basedir):
+    abssrc, absdst = [util.canonpath(basedir, basedir, x) for x in [src, dst]]
     if os.path.exists(absdst):
         raise util.Abort(_("cannot create %s: destination already exists") %
                          dst)
 
-    if not os.path.isdir(basedir):
-        os.makedirs(basedir)
+    dstdir = os.path.dirname(absdst)
+    if dstdir and not os.path.isdir(dstdir):
+        try:
+            os.makedirs(dstdir)
+        except IOError:
+            raise util.Abort(
+                _("cannot create %s: unable to create destination directory")
+                % dst)            
 
     util.copyfile(abssrc, absdst)
 
@@ -977,9 +980,7 @@
             cwd = os.getcwd()
             for gp in gitpatches:
                 if gp.op in ('COPY', 'RENAME'):
-                    src, dst = [util.canonpath(cwd, cwd, x)
-                                for x in [gp.oldpath, gp.path]]
-                    copyfile(src, dst)
+                    copyfile(gp.oldpath, gp.path, cwd)
                 changed[gp.path] = gp
         else:
             raise util.Abort(_('unsupported parser state: %s') % state)
--- a/mercurial/ui.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/ui.py	Fri Dec 12 12:34:57 2008 -0800
@@ -350,7 +350,7 @@
         if not user:
             raise util.Abort(_("Please specify a username."))
         if "\n" in user:
-            raise util.Abort(_("username %s contains a newline\n") % `user`)
+            raise util.Abort(_("username %s contains a newline\n") % repr(user))
         return user
 
     def shortuser(self, user):
@@ -407,7 +407,8 @@
                 import readline
                 # force demandimport to really load the module
                 readline.read_history_file
-            except ImportError:
+                # windows sometimes raises something other than ImportError
+            except Exception:
                 pass
         line = raw_input(prompt)
         # When stdin is in binary mode on Windows, it can cause
--- a/mercurial/util.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/util.py	Fri Dec 12 12:34:57 2008 -0800
@@ -705,7 +705,7 @@
         if cwd is not None and oldcwd != cwd:
             os.chdir(oldcwd)
 
-class SignatureError:
+class SignatureError(Exception):
     pass
 
 def checksignature(func):
@@ -1901,7 +1901,7 @@
         _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.remove('.hg') # don't recurse inside the .hg directory
+            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')):
--- a/mercurial/util_win32.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/mercurial/util_win32.py	Fri Dec 12 12:34:57 2008 -0800
@@ -19,7 +19,7 @@
 import util
 from win32com.shell import shell,shellcon
 
-class WinError:
+class WinError(Exception):
     winerror_map = {
         winerror.ERROR_ACCESS_DENIED: errno.EACCES,
         winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/branches.svndump	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,415 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 7b60030a-5a1f-4344-a009-73f0c1c2adf2
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-12-06T12:47:52.296168Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 10
+init projA
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:47:52.342238Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 106
+Content-length: 106
+
+K 7
+svn:log
+V 5
+hello
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:47:53.190046Z
+PROPS-END
+
+Node-path: branches/notinbranch
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: e29311f6f1bf1af907f9ef9f44b8328b
+Content-length: 12
+
+PROPS-END
+d
+
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 12
+
+PROPS-END
+a
+
+
+Node-path: trunk/b
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 3b5d5c3712955042212316173ccf37be
+Content-length: 12
+
+PROPS-END
+b
+
+
+Node-path: trunk/c
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 2cd6ee2c70b0bde53fbe6cac3c8b8bb1
+Content-length: 12
+
+PROPS-END
+c
+
+
+Revision-number: 3
+Prop-content-length: 124
+Content-length: 124
+
+K 7
+svn:log
+V 22
+branch trunk, remove c
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:47:55.188535Z
+PROPS-END
+
+Node-path: branches/old
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Node-path: branches/old/a
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk/a
+Text-copy-source-md5: 60b725f10c9c85c70d97880dfe8191b3
+
+
+Node-path: branches/old/b
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk/b
+Text-copy-source-md5: 3b5d5c3712955042212316173ccf37be
+
+
+Revision-number: 4
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+change a
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:47:57.146347Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 0d227f1abf8c2932d342e9b99cc957eb
+Content-length: 4
+
+a
+a
+
+
+Revision-number: 5
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+change b
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:47:58.150124Z
+PROPS-END
+
+Node-path: branches/old/b
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 06ac26ed8b614fc0b141e4542aa067c2
+Content-length: 4
+
+b
+b
+
+
+Revision-number: 6
+Prop-content-length: 119
+Content-length: 119
+
+K 7
+svn:log
+V 17
+move and update c
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:00.161336Z
+PROPS-END
+
+Node-path: branches/old/c
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 3
+Node-copyfrom-path: trunk/b
+Text-copy-source-md5: 3b5d5c3712955042212316173ccf37be
+Prop-content-length: 34
+Text-content-length: 4
+Text-content-md5: 33cb6785d50937d8d307ebb66d6259a7
+Content-length: 38
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+b
+c
+
+
+Node-path: trunk/b
+Node-action: delete
+
+
+Revision-number: 7
+Prop-content-length: 116
+Content-length: 116
+
+K 7
+svn:log
+V 14
+change b again
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:01.153724Z
+PROPS-END
+
+Node-path: branches/old/b
+Node-kind: file
+Node-action: change
+Text-content-length: 6
+Text-content-md5: cdcfb41554e2d092c13f5e6839e63577
+Content-length: 6
+
+b
+b
+b
+
+
+Revision-number: 8
+Prop-content-length: 114
+Content-length: 114
+
+K 7
+svn:log
+V 12
+move to old2
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:04.150915Z
+PROPS-END
+
+Node-path: branches/old2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 7
+Node-copyfrom-path: branches/old
+
+
+Node-path: branches/old
+Node-action: delete
+
+
+Revision-number: 9
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 16
+move back to old
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:06.149560Z
+PROPS-END
+
+Node-path: branches/old
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 8
+Node-copyfrom-path: branches/old2
+
+
+Node-path: branches/old2
+Node-action: delete
+
+
+Revision-number: 10
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 16
+last change to a
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:07.268498Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 2
+
+a
+
+
+Revision-number: 11
+Prop-content-length: 126
+Content-length: 126
+
+K 7
+svn:log
+V 24
+branch trunk@1 into old3
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T12:48:09.151702Z
+PROPS-END
+
+Node-path: branches/old3
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/move.svndump	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,401 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 0682b859-320d-4a69-a164-a7cab5695072
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-12-06T13:33:36.768573Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 10
+init projA
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:37.083146Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 12
+
+PROPS-END
+a
+
+
+Node-path: trunk/d1
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk/d1/b
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 3b5d5c3712955042212316173ccf37be
+Content-length: 12
+
+PROPS-END
+b
+
+
+Node-path: trunk/d1/c
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 2cd6ee2c70b0bde53fbe6cac3c8b8bb1
+Content-length: 12
+
+PROPS-END
+c
+
+
+Node-path: trunk/d2
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk/d2/d
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: e29311f6f1bf1af907f9ef9f44b8328b
+Content-length: 12
+
+PROPS-END
+d
+
+
+Revision-number: 2
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 16
+commitbeforemove
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:38.152773Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 0d227f1abf8c2932d342e9b99cc957eb
+Content-length: 4
+
+a
+a
+
+
+Node-path: trunk/d1/c
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 63fad9092ad37713ebe26b3193f89c41
+Content-length: 4
+
+c
+c
+
+
+Revision-number: 3
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 10
+movedtrunk
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:39.146388Z
+PROPS-END
+
+Node-path: subproject
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk
+
+
+Node-path: trunk
+Node-action: delete
+
+
+Revision-number: 4
+Prop-content-length: 113
+Content-length: 113
+
+K 7
+svn:log
+V 11
+createtrunk
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:40.179944Z
+PROPS-END
+
+Node-path: subproject/trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 5
+Prop-content-length: 116
+Content-length: 116
+
+K 7
+svn:log
+V 14
+createbranches
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:41.184505Z
+PROPS-END
+
+Node-path: subproject/branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 6
+Prop-content-length: 107
+Content-length: 107
+
+K 7
+svn:log
+V 6
+moved1
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:42.153312Z
+PROPS-END
+
+Node-path: subproject/trunk/d1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 5
+Node-copyfrom-path: subproject/d1
+
+
+Node-path: subproject/d1
+Node-action: delete
+
+
+Revision-number: 7
+Prop-content-length: 107
+Content-length: 107
+
+K 7
+svn:log
+V 6
+moved2
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:42.206313Z
+PROPS-END
+
+Node-path: subproject/trunk/d2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 6
+Node-copyfrom-path: subproject/d2
+
+
+Node-path: subproject/d2
+Node-action: delete
+
+
+Revision-number: 8
+Prop-content-length: 119
+Content-length: 119
+
+K 7
+svn:log
+V 17
+changeb and rm d2
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:43.182355Z
+PROPS-END
+
+Node-path: subproject/trunk/d1/b
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 06ac26ed8b614fc0b141e4542aa067c2
+Content-length: 4
+
+b
+b
+
+
+Node-path: subproject/trunk/d2
+Node-action: delete
+
+
+Revision-number: 9
+Prop-content-length: 113
+Content-length: 113
+
+K 7
+svn:log
+V 11
+moved1again
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:44.153682Z
+PROPS-END
+
+Node-path: subproject/branches/d1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 8
+Node-copyfrom-path: subproject/trunk/d1
+
+
+Node-path: subproject/trunk/d1
+Node-action: delete
+
+
+Revision-number: 10
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 16
+copyfilefrompast
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:44.298011Z
+PROPS-END
+
+Node-path: subproject/trunk/d
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 7
+Node-copyfrom-path: subproject/trunk/d2/d
+Text-copy-source-md5: e29311f6f1bf1af907f9ef9f44b8328b
+
+
+Revision-number: 11
+Prop-content-length: 117
+Content-length: 117
+
+K 7
+svn:log
+V 15
+copydirfrompast
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:33:44.349920Z
+PROPS-END
+
+Node-path: subproject/trunk/d2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 7
+Node-copyfrom-path: subproject/trunk/d2
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/startrev.svndump	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,240 @@
+SVN-fs-dump-format-version: 2
+
+UUID: c731c652-65e9-4325-a17e-fed96a319f22
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-12-06T13:44:21.642421Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 10
+init projA
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:21.759281Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+createab
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:22.179257Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 12
+
+PROPS-END
+a
+
+
+Node-path: trunk/b
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 3b5d5c3712955042212316173ccf37be
+Content-length: 12
+
+PROPS-END
+b
+
+
+Revision-number: 3
+Prop-content-length: 108
+Content-length: 108
+
+K 7
+svn:log
+V 7
+removeb
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:23.176546Z
+PROPS-END
+
+Node-path: trunk/b
+Node-action: delete
+
+
+Revision-number: 4
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+changeaa
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:25.147151Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 0d227f1abf8c2932d342e9b99cc957eb
+Content-length: 4
+
+a
+a
+
+
+Revision-number: 5
+Prop-content-length: 119
+Content-length: 119
+
+K 7
+svn:log
+V 17
+branch, changeaaa
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:28.158475Z
+PROPS-END
+
+Node-path: branches/branch1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 4
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Node-path: branches/branch1/a
+Node-kind: file
+Node-action: change
+Text-content-length: 6
+Text-content-md5: 7d4ebf8f298d22fc349a91725b00af1c
+Content-length: 6
+
+a
+a
+a
+
+
+Revision-number: 6
+Prop-content-length: 117
+Content-length: 117
+
+K 7
+svn:log
+V 15
+addc,changeaaaa
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:44:29.180655Z
+PROPS-END
+
+Node-path: branches/branch1/a
+Node-kind: file
+Node-action: change
+Text-content-length: 8
+Text-content-md5: d12178e74d8774e34361e0a08d1fd2b7
+Content-length: 8
+
+a
+a
+a
+a
+
+
+Node-path: branches/branch1/c
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 2cd6ee2c70b0bde53fbe6cac3c8b8bb1
+Content-length: 12
+
+PROPS-END
+c
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/svndump-branches.sh	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+# Use this script to generate branches.svndump
+#
+
+mkdir temp
+cd temp
+
+mkdir project-orig
+cd project-orig
+mkdir trunk
+mkdir branches
+mkdir tags
+cd ..
+
+svnadmin create svn-repo
+svnurl=file://`pwd`/svn-repo
+svn import project-orig $svnurl -m "init projA"
+
+svn co $svnurl project
+cd project
+echo a > trunk/a
+echo b > trunk/b
+echo c > trunk/c
+# Add a file within branches, used to confuse branch detection
+echo d > branches/notinbranch
+svn add trunk/a trunk/b trunk/c branches/notinbranch
+svn ci -m hello
+
+# Branch to old
+svn copy trunk branches/old
+svn rm branches/old/c
+svn ci -m "branch trunk, remove c"
+svn up
+
+# Update trunk
+echo a >> trunk/a
+svn ci -m "change a"
+
+# Update old branch
+echo b >> branches/old/b
+svn ci -m "change b"
+
+# Create a cross-branch revision
+svn move trunk/b branches/old/c
+echo c >> branches/old/c
+svn ci -m "move and update c"
+
+# Update old branch again
+echo b >> branches/old/b
+svn ci -m "change b again"
+
+# Move back and forth between branch of similar names
+# This used to generate fake copy records
+svn up
+svn move branches/old branches/old2
+svn ci -m "move to old2"
+svn move branches/old2 branches/old
+svn ci -m "move back to old"
+
+# Update trunk again
+echo a > trunk/a
+svn ci -m "last change to a"
+
+# Branch again from a converted revision
+svn copy -r 1 $svnurl/trunk branches/old3
+svn ci -m "branch trunk@1 into old3"
+cd ..
+
+svnadmin dump svn-repo > ../branches.svndump
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/svndump-move.sh	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,62 @@
+#!/bin/sh
+#
+# Use this script to generate move.svndump
+#
+
+mkdir temp
+cd temp
+
+mkdir project-orig
+cd project-orig
+mkdir trunk
+echo a > trunk/a
+mkdir trunk/d1
+mkdir trunk/d2
+echo b > trunk/d1/b
+echo c > trunk/d1/c
+echo d > trunk/d2/d
+cd ..
+
+svnadmin create svn-repo
+svnurl=file://`pwd`/svn-repo
+svn import project-orig $svnurl -m "init projA"
+
+svn co $svnurl project
+cd project
+# Build a module renaming chain which used to confuse the converter.
+# Update svn repository
+echo a >> trunk/a
+echo c >> trunk/d1/c
+svn ci -m commitbeforemove
+svn mv $svnurl/trunk $svnurl/subproject -m movedtrunk
+svn up
+mkdir subproject/trunk
+svn add subproject/trunk
+svn ci -m createtrunk
+mkdir subproject/branches
+svn add subproject/branches
+svn ci -m createbranches
+svn mv $svnurl/subproject/d1 $svnurl/subproject/trunk/d1 -m moved1
+svn mv $svnurl/subproject/d2 $svnurl/subproject/trunk/d2 -m moved2
+svn up
+echo b >> subproject/trunk/d1/b
+
+svn rm subproject/trunk/d2
+svn ci -m "changeb and rm d2"
+svn mv $svnurl/subproject/trunk/d1 $svnurl/subproject/branches/d1 -m moved1again
+
+if svn help copy | grep 'SRC\[@REV\]' > /dev/null 2>&1; then
+    # SVN >= 1.5 replaced the -r REV syntax with @REV
+    # Copy a file from a past revision
+    svn copy $svnurl/subproject/trunk/d2/d@7 $svnurl/subproject/trunk -m copyfilefrompast
+    # Copy a directory from a past revision
+    svn copy $svnurl/subproject/trunk/d2@7 $svnurl/subproject/trunk -m copydirfrompast
+else
+    # Copy a file from a past revision
+    svn copy -r 7 $svnurl/subproject/trunk/d2/d $svnurl/subproject/trunk -m copyfilefrompast
+    # Copy a directory from a past revision
+    svn copy -r 7 $svnurl/subproject/trunk/d2 $svnurl/subproject/trunk -m copydirfrompast
+fi
+cd ..
+
+svnadmin dump svn-repo > ../move.svndump
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/svndump-startrev.sh	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Use this script to generate startrev.svndump
+#
+
+mkdir temp
+cd temp
+
+mkdir project-orig
+cd project-orig
+mkdir trunk
+mkdir branches
+mkdir tags
+cd ..
+
+svnadmin create svn-repo
+svnurl=file://`pwd`/svn-repo
+svn import project-orig $svnurl -m "init projA"
+
+svn co $svnurl project
+cd project
+echo a > trunk/a
+echo b > trunk/b
+svn add trunk/a trunk/b
+svn ci -m createab
+svn rm trunk/b
+svn ci -m removeb
+svn up
+echo a >> trunk/a
+svn ci -m changeaa
+
+# Branch
+svn up
+svn copy trunk branches/branch1
+echo a >> branches/branch1/a
+svn ci -m "branch, changeaaa"
+
+echo a >> branches/branch1/a
+echo c > branches/branch1/c
+svn add branches/branch1/c
+svn ci -m "addc,changeaaaa"
+svn up
+cd ..
+
+svnadmin dump svn-repo > ../startrev.svndump
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/svndump-tags.sh	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Use this script to generate tags.svndump
+#
+
+mkdir temp
+cd temp
+
+mkdir project-orig
+cd project-orig
+mkdir trunk
+mkdir branches
+mkdir tags
+mkdir unrelated
+cd ..
+
+svnadmin create svn-repo
+svnurl=file://`pwd`/svn-repo
+svn import project-orig $svnurl -m "init projA"
+
+svn co $svnurl project
+cd project
+echo a > trunk/a
+svn add trunk/a
+svn ci -m adda
+echo a >> trunk/a
+svn ci -m changea
+echo a >> trunk/a
+svn ci -m changea2
+# Add an unrelated commit to test that tags are bound to the
+# correct "from" revision and not a dummy one
+echo a >> unrelated/dummy
+svn add unrelated/dummy
+svn ci -m unrelatedchange
+# Tag current revision
+svn up
+svn copy trunk tags/trunk.v1
+svn copy trunk tags/trunk.badtag
+svn ci -m "tagging trunk.v1 trunk.badtag"
+echo a >> trunk/a
+svn ci -m changea3
+# Fix the bad tag
+# trunk.badtag should not show in converted tags
+svn up
+svn mv tags/trunk.badtag tags/trunk.goodtag
+svn ci -m "fix trunk.badtag"
+cd ..
+
+svnadmin dump svn-repo > ../tags.svndump
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svn/tags.svndump	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,295 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 65371b91-a2cf-4cb1-a047-08b28c3b4c40
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-12-06T13:50:23.869747Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 10
+init projA
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:23.944361Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: unrelated
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 105
+Content-length: 105
+
+K 7
+svn:log
+V 4
+adda
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:25.174397Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 12
+
+PROPS-END
+a
+
+
+Revision-number: 3
+Prop-content-length: 108
+Content-length: 108
+
+K 7
+svn:log
+V 7
+changea
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:26.148468Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 4
+Text-content-md5: 0d227f1abf8c2932d342e9b99cc957eb
+Content-length: 4
+
+a
+a
+
+
+Revision-number: 4
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+changea2
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:27.147988Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 6
+Text-content-md5: 7d4ebf8f298d22fc349a91725b00af1c
+Content-length: 6
+
+a
+a
+a
+
+
+Revision-number: 5
+Prop-content-length: 117
+Content-length: 117
+
+K 7
+svn:log
+V 15
+unrelatedchange
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:28.174989Z
+PROPS-END
+
+Node-path: unrelated/dummy
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Content-length: 12
+
+PROPS-END
+a
+
+
+Revision-number: 6
+Prop-content-length: 131
+Content-length: 131
+
+K 7
+svn:log
+V 29
+tagging trunk.v1 trunk.badtag
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:32.157783Z
+PROPS-END
+
+Node-path: tags/trunk.badtag
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 5
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Node-path: tags/trunk.v1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 5
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Revision-number: 7
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 8
+changea3
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:33.145803Z
+PROPS-END
+
+Node-path: trunk/a
+Node-kind: file
+Node-action: change
+Text-content-length: 8
+Text-content-md5: d12178e74d8774e34361e0a08d1fd2b7
+Content-length: 8
+
+a
+a
+a
+a
+
+
+Revision-number: 8
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 16
+fix trunk.badtag
+K 10
+svn:author
+V 7
+pmezard
+K 8
+svn:date
+V 27
+2008-12-06T13:50:36.153842Z
+PROPS-END
+
+Node-path: tags/trunk.goodtag
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 7
+Node-copyfrom-path: tags/trunk.badtag
+
+
+Node-path: tags/trunk.badtag
+Node-action: delete
+
+
--- a/tests/test-bdiff	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-bdiff	Fri Dec 12 12:34:57 2008 -0800
@@ -9,13 +9,13 @@
     if d:
         c = mpatch.patches(a, [d])
     if c != b:
-        print "***", `a`, `b`
+        print "***", repr(a), repr(b)
         print "bad:"
-        print `c`[:200]
-        print `d`
+        print repr(c)[:200]
+        print repr(d)
 
 def test(a, b):
-    print "***", `a`, `b`
+    print "***", repr(a), repr(b)
     test1(a, b)
     test1(b, a)
 
--- a/tests/test-bookmarks-rebase.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-bookmarks-rebase.out	Fri Dec 12 12:34:57 2008 -0800
@@ -18,6 +18,8 @@
 rebase completed
 changeset:   3:9163974d1cb5
 tag:         tip
+tag:         two
+tag:         one
 parent:      1:925d80f479bb
 parent:      2:db815d6d32e6
 user:        test
--- a/tests/test-bookmarks.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-bookmarks.out	Fri Dec 12 12:34:57 2008 -0800
@@ -7,6 +7,7 @@
  * X                         0:f7b1eb17ad24
 % look up bookmark
 changeset:   0:f7b1eb17ad24
+tag:         X
 tag:         tip
 user:        test
 date:        Thu Jan 01 00:00:00 1970 +0000
@@ -51,7 +52,10 @@
  * x  y                      2:0316ce92851d
 % look up stripped bookmark name
 changeset:   2:0316ce92851d
+tag:         X2
+tag:         Y
 tag:         tip
+tag:         x  y
 user:        test
 date:        Thu Jan 01 00:00:00 1970 +0000
 summary:     2
--- a/tests/test-convert-cvs-builtincvsps	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-cvs-builtincvsps	Fri Dec 12 12:34:57 2008 -0800
@@ -102,3 +102,7 @@
 
 echo "graphlog = " >> $HGRCPATH
 hg -R src-hg glog --template '#rev# (#branches#) #desc# files: #files#\n'
+
+echo % testing debugcvsps
+cd src
+hg debugcvsps | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/' 
--- a/tests/test-convert-cvs-builtincvsps.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-cvs-builtincvsps.out	Fri Dec 12 12:34:57 2008 -0800
@@ -136,3 +136,71 @@
 |/
 o  0 () Initial revision files: a b/c
 
+% testing debugcvsps
+collecting CVS rlog
+8 log entries
+creating changesets
+5 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+Initial revision
+
+Members: 
+	a:INITIAL->1.1 
+	b/c:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: INITIAL
+Tag: start 
+Log:
+import
+
+Members: 
+	a:1.1->1.1.1.1 
+	b/c:1.1->1.1.1.1 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+ci0
+
+Members: 
+	b/c:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+ci1
+
+Members: 
+	a:1.1->1.2 
+	b/c:1.2->1.3 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: branch
+Tag: (none) 
+Log:
+ci2
+
+Members: 
+	b/c:1.1->1.1.2.1 
+
--- a/tests/test-convert-svn-branches	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-branches	Fri Dec 12 12:34:57 2008 -0800
@@ -12,6 +12,7 @@
 echo "hgext.graphlog =" >> $HGRCPATH
 
 svnadmin create svn-repo
+cat "$TESTDIR/svn/branches.svndump" | svnadmin load svn-repo > /dev/null
 
 svnpath=`pwd | fix_path`
 # SVN wants all paths to start with a slash. Unfortunately,
@@ -20,73 +21,10 @@
 if [ $? -ne 0 ]; then
     svnpath='/'$svnpath
 fi
-
-echo % initial svn import
-mkdir projA
-cd projA
-mkdir trunk
-mkdir branches
-mkdir tags
-cd ..
-
-svnurl=file://$svnpath/svn-repo/projA
-svn import -m "init projA" projA $svnurl | fix_path
-
-echo % update svn repository
-svn co $svnurl A | fix_path
-cd A
-echo a > trunk/a
-echo b > trunk/b
-echo c > trunk/c
-# Add a file within branches, used to confuse branch detection
-echo d > branches/notinbranch
-svn add trunk/a trunk/b trunk/c branches/notinbranch
-svn ci -m hello
-
-echo % branch to old
-svn copy trunk branches/old
-svn rm branches/old/c
-svn ci -m "branch trunk, remove c"
-svn up
-
-echo % update trunk
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m "change a"
-
-echo % update old branch
-"$TESTDIR/svn-safe-append.py" b branches/old/b
-svn ci -m "change b"
-
-echo % create a cross-branch revision
-svn move trunk/b branches/old/c
-"$TESTDIR/svn-safe-append.py" c branches/old/c
-svn ci -m "move and update c"
-
-echo % update old branch again
-"$TESTDIR/svn-safe-append.py" b branches/old/b
-svn ci -m "change b again"
-
-echo % move back and forth between branch of similar names
-# This used to generate fake copy records
-svn up
-svn move branches/old branches/old2
-svn ci -m "move to old2"
-svn move branches/old2 branches/old
-svn ci -m "move back to old"
-
-echo % update trunk again
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m "last change to a"
-cd ..
+svnurl=file://$svnpath/svn-repo
 
 echo % convert trunk and branches
-hg convert --datesort $svnurl A-hg
-
-echo % branch again from a converted revision
-cd A
-svn copy -r 1 $svnurl/trunk branches/old3
-svn ci -m "branch trunk@1 into old3"
-cd ..
+hg convert --datesort -r 10 $svnurl A-hg
 
 echo % convert again
 hg convert --datesort $svnurl A-hg
--- a/tests/test-convert-svn-branches.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-branches.out	Fri Dec 12 12:34:57 2008 -0800
@@ -1,77 +1,3 @@
-% initial svn import
-Adding         projA/trunk
-Adding         projA/branches
-Adding         projA/tags
-
-Committed revision 1.
-% update svn repository
-A    A/trunk
-A    A/branches
-A    A/tags
-Checked out revision 1.
-A         trunk/a
-A         trunk/b
-A         trunk/c
-A         branches/notinbranch
-Adding         branches/notinbranch
-Adding         trunk/a
-Adding         trunk/b
-Adding         trunk/c
-Transmitting file data ....
-Committed revision 2.
-% branch to old
-A         branches/old
-D         branches/old/c
-Adding         branches/old
-Adding         branches/old/a
-Adding         branches/old/b
-Deleting       branches/old/c
-
-Committed revision 3.
-At revision 3.
-% update trunk
-Sending        trunk/a
-Transmitting file data .
-Committed revision 4.
-% update old branch
-Sending        branches/old/b
-Transmitting file data .
-Committed revision 5.
-% create a cross-branch revision
-A         branches/old/c
-D         trunk/b
-Adding         branches/old/c
-Deleting       trunk/b
-Transmitting file data .
-Committed revision 6.
-% update old branch again
-Sending        branches/old/b
-Transmitting file data .
-Committed revision 7.
-% move back and forth between branch of similar names
-At revision 7.
-A         branches/old2
-D         branches/old/a
-D         branches/old/b
-D         branches/old/c
-D         branches/old
-Deleting       branches/old
-Adding         branches/old2
-
-Committed revision 8.
-A         branches/old
-D         branches/old2/a
-D         branches/old2/b
-D         branches/old2/c
-D         branches/old2
-Adding         branches/old
-Deleting       branches/old2
-
-Committed revision 9.
-% update trunk again
-Sending        trunk/a
-Transmitting file data .
-Committed revision 10.
 % convert trunk and branches
 initializing destination A-hg repository
 scanning source...
@@ -88,12 +14,6 @@
 2 move to old2
 1 move back to old
 0 last change to a
-% branch again from a converted revision
-Checked out revision 1.
-A         branches/old3
-Adding         branches/old3
-
-Committed revision 11.
 % convert again
 scanning source...
 sorting...
@@ -117,8 +37,8 @@
 | | |
 | o |  branch= 3 change a files: a
 | | |
-| | o  branch=old 2 branch trunk, remove c files:
-| |/
++---o  branch=old 2 branch trunk, remove c files: a b
+| |
 | o  branch= 1 hello files: a b c
 |/
 o  branch= 0 init projA files:
--- a/tests/test-convert-svn-move	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-move	Fri Dec 12 12:34:57 2008 -0800
@@ -12,6 +12,7 @@
 echo "hgext.graphlog =" >> $HGRCPATH
 
 svnadmin create svn-repo
+cat "$TESTDIR/svn/move.svndump" | svnadmin load svn-repo > /dev/null
 
 svnpath=`pwd | fix_path`
 # SVN wants all paths to start with a slash. Unfortunately,
@@ -20,58 +21,7 @@
 if [ $? -ne 0 ]; then
     svnpath='/'$svnpath
 fi
-
-echo % initial svn import
-mkdir projA
-cd projA
-mkdir trunk
-echo a > trunk/a
-mkdir trunk/d1
-mkdir trunk/d2
-echo b > trunk/d1/b
-echo c > trunk/d1/c
-echo d > trunk/d2/d
-cd ..
-
-svnurl=file://$svnpath/svn-repo/projA
-svn import -m "init projA" projA $svnurl | fix_path
-
-# Build a module renaming chain which used to confuse the converter.
-echo % update svn repository
-svn co $svnurl A | fix_path
-cd A
-"$TESTDIR/svn-safe-append.py" a trunk/a
-"$TESTDIR/svn-safe-append.py" c trunk/d1/c
-svn ci -m commitbeforemove
-svn mv $svnurl/trunk $svnurl/subproject -m movedtrunk
-svn up
-mkdir subproject/trunk
-svn add subproject/trunk
-svn ci -m createtrunk
-mkdir subproject/branches
-svn add subproject/branches
-svn ci -m createbranches
-svn mv $svnurl/subproject/d1 $svnurl/subproject/trunk/d1 -m moved1
-svn mv $svnurl/subproject/d2 $svnurl/subproject/trunk/d2 -m moved2
-svn up
-"$TESTDIR/svn-safe-append.py" b subproject/trunk/d1/b
-svn rm subproject/trunk/d2
-svn ci -m "changeb and rm d2"
-svn mv $svnurl/subproject/trunk/d1 $svnurl/subproject/branches/d1 -m moved1again
-
-if svn help copy | grep 'SRC\[@REV\]' > /dev/null 2>&1; then
-    # SVN >= 1.5 replaced the -r REV syntax with @REV
-    echo % copy a file from a past revision
-    svn copy $svnurl/subproject/trunk/d2/d@7 $svnurl/subproject/trunk -m copyfilefrompast
-    echo % copy a directory from a past revision
-    svn copy $svnurl/subproject/trunk/d2@7 $svnurl/subproject/trunk -m copydirfrompast
-else
-    echo % copy a file from a past revision
-    svn copy -r 7 $svnurl/subproject/trunk/d2/d $svnurl/subproject/trunk -m copyfilefrompast
-    echo % copy a directory from a past revision
-    svn copy -r 7 $svnurl/subproject/trunk/d2 $svnurl/subproject/trunk -m copydirfrompast
-fi
-cd ..
+svnurl=file://$svnpath/svn-repo
 
 echo % convert trunk and branches
 hg convert --datesort $svnurl/subproject A-hg
--- a/tests/test-convert-svn-move.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-move.out	Fri Dec 12 12:34:57 2008 -0800
@@ -1,71 +1,3 @@
-% initial svn import
-Adding         projA/trunk
-Adding         projA/trunk/a
-Adding         projA/trunk/d1
-Adding         projA/trunk/d1/b
-Adding         projA/trunk/d1/c
-Adding         projA/trunk/d2
-Adding         projA/trunk/d2/d
-
-Committed revision 1.
-% update svn repository
-A    A/trunk
-A    A/trunk/a
-A    A/trunk/d1
-A    A/trunk/d1/b
-A    A/trunk/d1/c
-A    A/trunk/d2
-A    A/trunk/d2/d
-Checked out revision 1.
-Sending        trunk/a
-Sending        trunk/d1/c
-Transmitting file data ..
-Committed revision 2.
-
-Committed revision 3.
-D    trunk
-A    subproject
-A    subproject/a
-A    subproject/d1
-A    subproject/d1/b
-A    subproject/d1/c
-A    subproject/d2
-A    subproject/d2/d
-Updated to revision 3.
-A         subproject/trunk
-Adding         subproject/trunk
-
-Committed revision 4.
-A         subproject/branches
-Adding         subproject/branches
-
-Committed revision 5.
-
-Committed revision 6.
-
-Committed revision 7.
-A    subproject/trunk/d1
-A    subproject/trunk/d1/b
-A    subproject/trunk/d1/c
-A    subproject/trunk/d2
-A    subproject/trunk/d2/d
-D    subproject/d1
-D    subproject/d2
-Updated to revision 7.
-D         subproject/trunk/d2/d
-D         subproject/trunk/d2
-Sending        subproject/trunk/d1/b
-Deleting       subproject/trunk/d2
-Transmitting file data .
-Committed revision 8.
-
-Committed revision 9.
-% copy a file from a past revision
-
-Committed revision 10.
-% copy a directory from a past revision
-
-Committed revision 11.
 % convert trunk and branches
 initializing destination A-hg repository
 scanning source...
--- a/tests/test-convert-svn-startrev	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-startrev	Fri Dec 12 12:34:57 2008 -0800
@@ -12,6 +12,7 @@
 echo "hgext.graphlog =" >> $HGRCPATH
 
 svnadmin create svn-repo
+cat "$TESTDIR/svn/startrev.svndump" | svnadmin load svn-repo > /dev/null
 
 svnpath=`pwd | fix_path`
 # SVN wants all paths to start with a slash. Unfortunately,
@@ -20,43 +21,7 @@
 if [ $? -ne 0 ]; then
     svnpath='/'$svnpath
 fi
-
-echo % initial svn import
-mkdir projA
-cd projA
-mkdir trunk
-mkdir branches
-mkdir tags
-cd ..
-
-svnurl=file://$svnpath/svn-repo/projA
-svn import -m "init projA" projA $svnurl | fix_path
-
-echo % update svn repository
-svn co $svnurl A | fix_path
-cd A
-echo a > trunk/a
-echo b > trunk/b
-svn add trunk/a trunk/b
-svn ci -m createab
-svn rm trunk/b
-svn ci -m removeb
-svn up
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m changeaa
-
-echo % branch
-svn up
-svn copy trunk branches/branch1
-"$TESTDIR/svn-safe-append.py" a branches/branch1/a
-svn ci -m "branch, changeaaa"
-
-"$TESTDIR/svn-safe-append.py" a branches/branch1/a
-echo c > branches/branch1/c
-svn add branches/branch1/c
-svn ci -m "addc,changeaaaa"
-svn up
-cd ..
+svnurl=file://$svnpath/svn-repo
 
 convert()
 {
--- a/tests/test-convert-svn-startrev.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-startrev.out	Fri Dec 12 12:34:57 2008 -0800
@@ -1,41 +1,3 @@
-% initial svn import
-Adding         projA/trunk
-Adding         projA/branches
-Adding         projA/tags
-
-Committed revision 1.
-% update svn repository
-A    A/trunk
-A    A/branches
-A    A/tags
-Checked out revision 1.
-A         trunk/a
-A         trunk/b
-Adding         trunk/a
-Adding         trunk/b
-Transmitting file data ..
-Committed revision 2.
-D         trunk/b
-Deleting       trunk/b
-
-Committed revision 3.
-At revision 3.
-Sending        trunk/a
-Transmitting file data .
-Committed revision 4.
-% branch
-At revision 4.
-A         branches/branch1
-Adding         branches/branch1
-Sending        branches/branch1/a
-Transmitting file data .
-Committed revision 5.
-A         branches/branch1/c
-Sending        branches/branch1/a
-Adding         branches/branch1/c
-Transmitting file data ..
-Committed revision 6.
-At revision 6.
 % convert before branching point
 initializing destination A-r3-hg repository
 scanning source...
--- a/tests/test-convert-svn-tags	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-tags	Fri Dec 12 12:34:57 2008 -0800
@@ -12,6 +12,7 @@
 echo "hgext.graphlog =" >> $HGRCPATH
 
 svnadmin create svn-repo
+cat "$TESTDIR/svn/tags.svndump" | svnadmin load svn-repo > /dev/null
 
 svnpath=`pwd | fix_path`
 # SVN wants all paths to start with a slash. Unfortunately,
@@ -20,47 +21,7 @@
 if [ $? -ne 0 ]; then
     svnpath='/'$svnpath
 fi
-
-echo % initial svn import
-mkdir projA
-cd projA
-mkdir trunk
-mkdir branches
-mkdir tags
-mkdir unrelated
-cd ..
-
-svnurl=file://$svnpath/svn-repo/projA
-svn import -m "init projA" projA $svnurl | fix_path | sort
-
-echo % update svn repository
-svn co $svnurl A | fix_path
-cd A
-echo a > trunk/a
-svn add trunk/a
-svn ci -m adda
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m changea
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m changea2
-# Add an unrelated commit to test that tags are bound to the
-# correct "from" revision and not a dummy one
-"$TESTDIR/svn-safe-append.py" a unrelated/dummy
-svn add unrelated/dummy
-svn ci -m unrelatedchange
-echo % tag current revision
-svn up
-svn copy trunk tags/trunk.v1
-svn copy trunk tags/trunk.badtag
-svn ci -m "tagging trunk.v1 trunk.badtag"
-"$TESTDIR/svn-safe-append.py" a trunk/a
-svn ci -m changea3
-echo % fix the bad tag
-# trunk.badtag should not show in converted tags
-svn up
-svn mv tags/trunk.badtag tags/trunk.goodtag
-svn ci -m "fix trunk.badtag"
-cd ..
+svnurl=file://$svnpath/svn-repo
 
 echo % convert
 hg convert --datesort $svnurl A-hg
--- a/tests/test-convert-svn-tags.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-convert-svn-tags.out	Fri Dec 12 12:34:57 2008 -0800
@@ -1,50 +1,3 @@
-% initial svn import
-
-Adding         projA/branches
-Adding         projA/tags
-Adding         projA/trunk
-Adding         projA/unrelated
-Committed revision 1.
-% update svn repository
-A    A/trunk
-A    A/unrelated
-A    A/branches
-A    A/tags
-Checked out revision 1.
-A         trunk/a
-Adding         trunk/a
-Transmitting file data .
-Committed revision 2.
-Sending        trunk/a
-Transmitting file data .
-Committed revision 3.
-Sending        trunk/a
-Transmitting file data .
-Committed revision 4.
-A         unrelated/dummy
-Adding         unrelated/dummy
-Transmitting file data .
-Committed revision 5.
-% tag current revision
-At revision 5.
-A         tags/trunk.v1
-A         tags/trunk.badtag
-Adding         tags/trunk.badtag
-Adding         tags/trunk.v1
-
-Committed revision 6.
-Sending        trunk/a
-Transmitting file data .
-Committed revision 7.
-% fix the bad tag
-At revision 7.
-A         tags/trunk.goodtag
-D         tags/trunk.badtag/a
-D         tags/trunk.badtag
-Deleting       tags/trunk.badtag
-Adding         tags/trunk.goodtag
-
-Committed revision 8.
 % convert
 initializing destination A-hg repository
 scanning source...
--- a/tests/test-hgwebdir	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-hgwebdir	Fri Dec 12 12:34:57 2008 -0800
@@ -16,14 +16,8 @@
 hg init c
 echo c > c/c
 hg --cwd c ci -Amc -d'3 0'
+root=`pwd`
 
-cd b
-hg init d
-echo d > d/d
-hg --cwd d ci -Amd
-cd ..
-
-root=`pwd`
 cd ..
 
 cat > paths.conf <<EOF
@@ -85,7 +79,6 @@
 "$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'
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/c/file/tip/c?style=raw'
-"$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/d/rev/tip/?style=raw'
 
 echo % paths errors 1
 cat error-paths-1.log
--- a/tests/test-hgwebdir.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-hgwebdir.out	Fri Dec 12 12:34:57 2008 -0800
@@ -1,7 +1,6 @@
 adding a
 adding b
 adding c
-adding d
 % should give a 404 - file does not exist
 404 Not Found
 
@@ -32,7 +31,6 @@
 /b/
 /coll/a/
 /coll/b/
-/coll/b/d/
 /coll/c/
 /t/a/
 
@@ -112,7 +110,6 @@
 
 /coll/a/
 /coll/b/
-/coll/b/d/
 /coll/c/
 
 200 Script output follows
@@ -124,7 +121,6 @@
 
 /a/
 /b/
-/b/d/
 /c/
 
 200 Script output follows
@@ -136,21 +132,6 @@
 200 Script output follows
 
 c
-200 Script output follows
-
-
-# HG changeset patch
-# User test
-# Date 0 0
-# Node ID 43cb50608b2ae8635a62e2e8730adefc32a274ee
-
-d
-
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/d	Thu Jan 01 00:00:00 1970 +0000
-@@ -0,0 +1,1 @@
-+d
-
 % paths errors 1
 % paths errors 2
 % collections errors
--- a/tests/test-mq-missingfiles	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-mq-missingfiles	Fri Dec 12 12:34:57 2008 -0800
@@ -71,3 +71,15 @@
 cat b.rej
 cd ..
 
+echo % test push creating directory during git copy or rename
+hg init missingdir
+cd missingdir
+echo a > a
+hg ci -Am adda
+mkdir d
+hg copy a d/a2
+hg mv a d/a
+hg qnew -g -f patch
+hg qpop
+hg qpush
+cd ..
--- a/tests/test-mq-missingfiles.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-mq-missingfiles.out	Fri Dec 12 12:34:57 2008 -0800
@@ -47,3 +47,8 @@
 literal 2
 Jc${No0000400IC2
 
+% test push creating directory during git copy or rename
+adding a
+Patch queue now empty
+applying patch
+Now at: patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-rebase-keep-branch	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "graphlog=" >> $HGRCPATH
+echo "rebase=" >> $HGRCPATH
+
+addcommit () {
+    echo $1 > $1
+    hg add $1
+    hg commit -d "${2} 0" -u test -m $1
+}
+
+hg init a
+cd a
+addcommit "c1" 0
+addcommit "c2" 1
+
+addcommit "l1" 2
+addcommit "l2" 3
+
+hg update -C 1
+hg branch 'notdefault'
+addcommit "r1" 4
+hg glog --template '{rev}:{desc}:{branches}\n'
+
+echo
+echo '% Rebase a branch while preserving the branch name'
+hg update -C 3
+hg rebase -b 4 -d 3 --keepbranches 2>&1 | sed 's/\(saving bundle to \).*/\1/'
+hg glog --template '{rev}:{desc}:{branches}\n'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-rebase-keep-branch.out	Fri Dec 12 12:34:57 2008 -0800
@@ -0,0 +1,33 @@
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+marked working directory as branch notdefault
+created new head
+@  4:r1:notdefault
+|
+| o  3:l2:
+| |
+| o  2:l1:
+|/
+o  1:c2:
+|
+o  0:c1:
+
+
+% Rebase a branch while preserving the branch name
+2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+saving bundle to 
+adding branch
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+rebase completed
+@  4:r1:notdefault
+|
+o  3:l2:
+|
+o  2:l1:
+|
+o  1:c2:
+|
+o  0:c1:
+
--- a/tests/test-rebase-parameters.out	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-rebase-parameters.out	Fri Dec 12 12:34:57 2008 -0800
@@ -15,15 +15,16 @@
 
 options:
 
-    --keep      keep original revisions
- -s --source    rebase from a given revision
- -b --base      rebase from the base of a given revision
- -d --dest      rebase onto a given revision
-    --collapse  collapse the rebased revisions
- -c --continue  continue an interrupted rebase
- -a --abort     abort an interrupted rebase
-    --style     display using template map file
-    --template  display with template
+    --keep          keep original revisions
+    --keepbranches  keep original branches
+ -s --source        rebase from a given revision
+ -b --base          rebase from the base of a given revision
+ -d --dest          rebase onto a given revision
+    --collapse      collapse the rebased revisions
+ -c --continue      continue an interrupted rebase
+ -a --abort         abort an interrupted rebase
+    --style         display using template map file
+    --template      display with template
 
 use "hg -v help rebase" to show global options
 
@@ -42,15 +43,16 @@
 
 options:
 
-    --keep      keep original revisions
- -s --source    rebase from a given revision
- -b --base      rebase from the base of a given revision
- -d --dest      rebase onto a given revision
-    --collapse  collapse the rebased revisions
- -c --continue  continue an interrupted rebase
- -a --abort     abort an interrupted rebase
-    --style     display using template map file
-    --template  display with template
+    --keep          keep original revisions
+    --keepbranches  keep original branches
+ -s --source        rebase from a given revision
+ -b --base          rebase from the base of a given revision
+ -d --dest          rebase onto a given revision
+    --collapse      collapse the rebased revisions
+ -c --continue      continue an interrupted rebase
+ -a --abort         abort an interrupted rebase
+    --style         display using template map file
+    --template      display with template
 
 use "hg -v help rebase" to show global options
 
@@ -69,15 +71,16 @@
 
 options:
 
-    --keep      keep original revisions
- -s --source    rebase from a given revision
- -b --base      rebase from the base of a given revision
- -d --dest      rebase onto a given revision
-    --collapse  collapse the rebased revisions
- -c --continue  continue an interrupted rebase
- -a --abort     abort an interrupted rebase
-    --style     display using template map file
-    --template  display with template
+    --keep          keep original revisions
+    --keepbranches  keep original branches
+ -s --source        rebase from a given revision
+ -b --base          rebase from the base of a given revision
+ -d --dest          rebase onto a given revision
+    --collapse      collapse the rebased revisions
+ -c --continue      continue an interrupted rebase
+ -a --abort         abort an interrupted rebase
+    --style         display using template map file
+    --template      display with template
 
 use "hg -v help rebase" to show global options
 
@@ -96,15 +99,16 @@
 
 options:
 
-    --keep      keep original revisions
- -s --source    rebase from a given revision
- -b --base      rebase from the base of a given revision
- -d --dest      rebase onto a given revision
-    --collapse  collapse the rebased revisions
- -c --continue  continue an interrupted rebase
- -a --abort     abort an interrupted rebase
-    --style     display using template map file
-    --template  display with template
+    --keep          keep original revisions
+    --keepbranches  keep original branches
+ -s --source        rebase from a given revision
+ -b --base          rebase from the base of a given revision
+ -d --dest          rebase onto a given revision
+    --collapse      collapse the rebased revisions
+ -c --continue      continue an interrupted rebase
+ -a --abort         abort an interrupted rebase
+    --style         display using template map file
+    --template      display with template
 
 use "hg -v help rebase" to show global options
 
--- a/tests/test-walkrepo.py	Thu Dec 04 11:21:31 2008 -0800
+++ b/tests/test-walkrepo.py	Fri Dec 12 12:34:57 2008 -0800
@@ -12,12 +12,6 @@
 mkdir('subdir')
 chdir('subdir')
 hg.repository(u, 'sub1', create=1)
-chdir('sub1')
-hg.repository(u, 'inside_sub1', create=1)
-chdir('.hg')
-hg.repository(u, 'patches', create=1)
-chdir(os.path.pardir)
-chdir(os.path.pardir)
 mkdir('subsubdir')
 chdir('subsubdir')
 hg.repository(u, 'subsub1', create=1)
@@ -28,28 +22,28 @@
 
 def runtest():
     reposet = frozenset(walkrepos('.', followsym=True))
-    if sym and (len(reposet) != 5):
+    if sym and (len(reposet) != 3):
         print "reposet = %r" % (reposet,)
-        raise SystemExit(1, "Found %d repositories when I should have found 5" % (len(reposet),))
-    if (not sym) and (len(reposet) != 4):
+        print "Found %d repositories when I should have found 3" % (len(reposet),)
+    if (not sym) and (len(reposet) != 2):
         print "reposet = %r" % (reposet,)
-        raise SystemExit(1, "Found %d repositories when I should have found 4" % (len(reposet),))
+        print "Found %d repositories when I should have found 2" % (len(reposet),)
     sub1set = frozenset((pjoin('.', 'sub1'),
                          pjoin('.', 'circle', 'subdir', 'sub1')))
     if len(sub1set & reposet) != 1:
         print "sub1set = %r" % (sub1set,)
         print "reposet = %r" % (reposet,)
-        raise SystemExit(1, "sub1set and reposet should have exactly one path in common.")
+        print "sub1set and reposet should have exactly one path in common."
     sub2set = frozenset((pjoin('.', 'subsub1'),
                          pjoin('.', 'subsubdir', 'subsub1')))
     if len(sub2set & reposet) != 1:
         print "sub2set = %r" % (sub2set,)
         print "reposet = %r" % (reposet,)
-        raise SystemExit(1, "sub1set and reposet should have exactly one path in common.")
+        print "sub1set and reposet should have exactly one path in common."
     sub3 = pjoin('.', 'circle', 'top1')
     if sym and not (sub3 in reposet):
         print "reposet = %r" % (reposet,)
-        raise SystemExit(1, "Symbolic links are supported and %s is not in reposet" % (sub3,))
+        print "Symbolic links are supported and %s is not in reposet" % (sub3,)
 
 runtest()
 if sym: