Merge 0.4.
authorJelmer Vernooij <jelmer@samba.org>
Wed, 4 Jun 2008 18:56:53 +0000 (20:56 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Wed, 4 Jun 2008 18:56:53 +0000 (20:56 +0200)
23 files changed:
1  2 
NEWS
__init__.py
branch.py
commit.py
convert.py
fetch.py
format.py
logwalker.py
mapping.py
mapping3/__init__.py
remote.py
repository.py
tests/test_checkout.py
tests/test_commit.py
tests/test_convert.py
tests/test_errors.py
tests/test_push.py
tests/test_radir.py
tests/test_repository.py
tests/test_workingtree.py
transport.py
tree.py
workingtree.py

diff --cc NEWS
index 3cae5dc8db46c3192dc4634958867103b50651c4,4f10119e33c74c20439242a3fc510b4b08e87e5a..d95d1da388c46fef87ef68222bf397bc57d3fffd
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,14 -2,8 +2,16 @@@ bzr-svn 0.4.11 UNRELEASE
  
    CHANGES
  
 +   * bzr-svn now comes with its own Python bindings for the Subversion 
 +     libraries, removing the need for a unreleased version of Subversion and 
 +       improving performance.
 +
 +       It does however mean the extensions have to be built. This requires 
 +       the Subversion development libraries and should be possible by 
 +       simply running ``make`` from the plugin directory.
 +
+    * Now uses absolute imports and no longer adds plugin directory to the system path.
    BUG FIXES
  
     * Raise appropriate errors when using annotate.
diff --cc __init__.py
Simple merge
diff --cc branch.py
index ccbb5fd650ae7daccda6b91af2fe0129cd017f7c,aae7ada0bf63b568bb7ad81adb8ffa906c2a413f..4d77f213427076ba18f5671c4743bda3ebc7f14d
+++ b/branch.py
@@@ -24,16 -24,15 +24,14 @@@ from bzrlib.inventory import (Inventory
  from bzrlib.revision import is_null, ensure_null, NULL_REVISION
  from bzrlib.workingtree import WorkingTree
  
- import core
- from core import SubversionException
- import constants
 -import svn.client, svn.core
 -from svn.core import SubversionException
--
- from commit import push
- from config import BranchConfig
- from errors import NotSvnBranchPath
- from format import get_rich_root_format
- from repository import SvnRepository
- from transport import bzr_to_svn_url
++from bzrlib.plugins.svn import constants, core
+ from bzrlib.plugins.svn.commit import push
+ from bzrlib.plugins.svn.config import BranchConfig
++from bzrlib.plugins.svn.core import SubversionException
+ from bzrlib.plugins.svn.errors import NotSvnBranchPath
+ from bzrlib.plugins.svn.format import get_rich_root_format
+ from bzrlib.plugins.svn.repository import SvnRepository
 -from bzrlib.plugins.svn.transport import bzr_to_svn_url, create_svn_client
++from bzrlib.plugins.svn.transport import bzr_to_svn_url
  
  
  class FakeControlFiles(object):
diff --cc commit.py
index 4acd0a120225250d61cded3da7ca30b1a769de7f,916ee845700e0d72e46a429aa1007073aa203290..c12745e2fa89a29caa6abd50f255a9c667c90593
+++ b/commit.py
@@@ -31,14 -31,13 +31,16 @@@ from bzrlib.trace import mutter, warnin
  from bzrlib.plugins.svn import util
  
  from cStringIO import StringIO
- from errors import ChangesRootLHSHistory, MissingPrefix, RevpropChangeFailed
- from ra import txdelta_send_stream
- from svk import (generate_svk_feature, serialize_svk_features, 
++
++from bzrlib.plugins.svn import constants
+ from bzrlib.plugins.svn.errors import ChangesRootLHSHistory, MissingPrefix, RevpropChangeFailed
+ from bzrlib.plugins.svn.svk import (generate_svk_feature, serialize_svk_features, 
                   parse_svk_features, SVN_PROP_SVK_MERGE)
- import constants
- from logwalker import lazy_dict
+ from bzrlib.plugins.svn.logwalker import lazy_dict
  from bzrlib.plugins.svn.mapping import parse_revision_id
- from repository import SvnRepositoryFormat, SvnRepository
++from bzrlib.plugins.svn.ra import txdelta_send_stream
+ from bzrlib.plugins.svn.repository import SvnRepositoryFormat, SvnRepository
  import urllib
  
  
diff --cc convert.py
index 3ad6ad5fde8e4977fb9e1955a5f9cebf18f87461,65ccf7950f16b24887da38c7d3560d856a495b42..36ba976f2273949c33224e968fd56951e60fa4e1
@@@ -23,9 -23,9 +23,9 @@@ from bzrlib.repository import InterRepo
  from bzrlib.revision import ensure_null
  from bzrlib.transport import get_transport
  
- from format import get_rich_root_format
+ from bzrlib.plugins.svn.format import get_rich_root_format
  
 -import svn.core, svn.repos
 +import core, repos, constants
  
  def transport_makedirs(transport, location_url):
      """Create missing directories.
diff --cc fetch.py
index 3c09a647d713959ba61593bd9cdec2eccc466562,44d8356f82aba0204f5ac67078ba02b7f51e0031..16f17f34b03eb57b54fa7246615282061bf306ae
+++ b/fetch.py
@@@ -25,20 -25,21 +25,21 @@@ from bzrlib.trace import mutte
  from cStringIO import StringIO
  import md5
  
 -from svn.core import Pool
 -import svn.core
 +import constants
  
++from bzrlib.plugins.svn.delta import apply_txdelta_handler
  from bzrlib.plugins.svn.errors import InvalidFileName
- from logwalker import lazy_dict
+ from bzrlib.plugins.svn.logwalker import lazy_dict
  from bzrlib.plugins.svn.mapping import (SVN_PROP_BZR_MERGE, 
                       SVN_PROP_BZR_PREFIX, SVN_PROP_BZR_REVISION_INFO, 
                       SVN_PROP_BZR_REVISION_ID,
                       SVN_PROP_BZR_FILEIDS, SVN_REVPROP_BZR_SIGNATURE,
                       parse_merge_property,
                       parse_revision_metadata)
- from repository import SvnRepository, SvnRepositoryFormat
- from svk import SVN_PROP_SVK_MERGE
- from delta import apply_txdelta_handler
- from tree import (parse_externals_description, inventory_add_external)
+ from bzrlib.plugins.svn.repository import SvnRepository, SvnRepositoryFormat
+ from bzrlib.plugins.svn.svk import SVN_PROP_SVK_MERGE
 -from bzrlib.plugins.svn.tree import (apply_txdelta_handler, parse_externals_description, 
++from bzrlib.plugins.svn.tree import (parse_externals_description, 
+                   inventory_add_external)
  
  
  def _escape_commit_message(message):
diff --cc format.py
index cdab1acffc28585bde79dad82da887841568c4c7,799ff1dde317ba72b2dd7f90fa4aa175265ea9db..5cea113906c3793979a014c01237d0f23b582a5e
+++ b/format.py
@@@ -23,9 -23,8 +23,7 @@@ from bzrlib.lockable_files import Trans
  import os
  
  lazy_import(globals(), """
- import errors
- import remote
- import constants
 -from bzrlib.plugins.svn import errors
 -from bzrlib.plugins.svn import remote
++from bzrlib.plugins.svn import constants, errors, remote
  
  from bzrlib import errors as bzr_errors
  """)
diff --cc logwalker.py
index 2bde789362cbbe4023f62d5925cca6051343db28,a5361b4cb6be5990e8c416c5aba8d91ff2a79d58..2b4d42d7a825332293e8b851f6eb9e2c0e517969
@@@ -20,14 -20,15 +20,14 @@@ from bzrlib.errors import NoSuchRevisio
  from bzrlib.trace import mutter
  import bzrlib.ui as ui
  
 -from svn.core import SubversionException, Pool
 +from core import SubversionException
  from transport import SvnRaTransport
 -import svn.core
 +import core
 +import constants
  
- from cache import CacheTable
- import changes
+ from bzrlib.plugins.svn.cache import CacheTable
from bzrlib.plugins.svn import changes
  
 -LOG_CHUNK_LIMIT = 0
 -
  class lazy_dict(object):
      def __init__(self, initial, create_fn, *args):
          self.initial = initial
diff --cc mapping.py
index 3fc5ac983cc52def044cfd1a9745670197d443ba,e8c5393c712bae19fd88774afcdba05fd2223f33..971f8f3d5a12336bab65f68b91b3e8cbf07dc130
@@@ -19,14 -19,11 +19,10 @@@ from bzrlib import osutils, registr
  from bzrlib.errors import InvalidRevisionId
  from bzrlib.trace import mutter
  
- from bzrlib.plugins.svn import version_info
 -from bzrlib.plugins.svn import version_info, errors
++from bzrlib.plugins.svn import core, constants, version_info, constants, errors
  import calendar
- import core
- import errors
 -import svn
 -import time
 +import sha
- import time
  import urllib
- import constants
  
  MAPPING_VERSION = 3
  
index 19c99bcf219593dd5e6b5738e8d8efc62c680a38,9534e69b28c17626db658276045a0da544e15229..881ca7f1cca22bb3ee22892ece62554cd37709f1
  from bzrlib import osutils, ui
  from bzrlib.errors import InvalidRevisionId
  from bzrlib.trace import mutter
--from bzrlib.plugins.svn import mapping
- from layout import RepositoryLayout
- from mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path, 
++from bzrlib.plugins.svn import core, constants, mapping
+ from bzrlib.plugins.svn.layout import RepositoryLayout
+ from bzrlib.plugins.svn.mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path, 
                               guess_scheme_from_history, ListBranchingScheme, 
                               parse_list_scheme_text, NoBranchingScheme,
                               TrunkBranchingScheme, ListBranchingScheme)
- import sha, core
- import constants
 -import sha, svn
 -from svn.core import SubversionException
++import sha
  
  SVN_PROP_BZR_BRANCHING_SCHEME = 'bzr:branching-scheme'
  
diff --cc remote.py
index 75eb07e867ace7627158178a0b94cd9eefa95554,9c5c5de7f0f83e4fe612a0ccc8678228adc367eb..85815d21b5d04a9d09ef6fa628cfd6c57c5d6f9d
+++ b/remote.py
@@@ -21,13 -22,13 +22,13 @@@ from bzrlib.errors import (NotBranchErr
                             NoWorkingTree, AlreadyBranchError)
  from bzrlib.transport.local import LocalTransport
  
 -from svn.core import SubversionException
 -import svn.core, svn.repos
 +from core import SubversionException
 +import core 
  
- from errors import NoSvnRepositoryPresent
- from format import get_rich_root_format, SvnRemoteFormat
- from repository import SvnRepository
- from transport import bzr_to_svn_url, get_svn_ra_transport
+ from bzrlib.plugins.svn.errors import NoSvnRepositoryPresent
+ from bzrlib.plugins.svn.format import get_rich_root_format, SvnRemoteFormat
+ from bzrlib.plugins.svn.repository import SvnRepository
+ from bzrlib.plugins.svn.transport import bzr_to_svn_url, get_svn_ra_transport
  
  
  class SvnRemoteAccess(BzrDir):
diff --cc repository.py
Simple merge
Simple merge
index 0bd2adb8d73cf4bb9eb2321e8742be54d37d0769,20113028a08dd1495be5b28b354fb9643c65fcfd..4c89d9a2704da7904cfe1c8afcd5cf5d856d4145
@@@ -25,14 -25,14 +25,14 @@@ from bzrlib.tests import TestCas
  from bzrlib.trace import mutter
  from bzrlib.workingtree import WorkingTree
  
- from commit import set_svn_revprops, _revision_id_to_svk_feature
+ from bzrlib.plugins.svn.commit import set_svn_revprops, _revision_id_to_svk_feature
  from copy import copy
- from errors import RevpropChangeFailed
+ from bzrlib.plugins.svn.errors import RevpropChangeFailed
  import os
- from transport import SvnRaTransport
- from tests import TestCaseWithSubversionRepository
+ from bzrlib.plugins.svn.transport import SvnRaTransport
+ from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
  
 -from svn.core import svn_time_to_cstring
 +from core import time_to_cstring
  
  class TestNativeCommit(TestCaseWithSubversionRepository):
      def test_simple_commit(self):
index ec06e81d45b98ddb8d3e90b1a7d35a99c896c9fc,ac42c4645fb6d005125cc7779f2c145244b76ded..7b63fa6ce4f8b6c93801f7a5a5ddcd7064186939
@@@ -25,13 -25,13 +25,13 @@@ from bzrlib.tests import TestCaseInTemp
  from bzrlib.trace import mutter
  
  import os, sys
- from convert import convert_repository, NotDumpFile, load_dumpfile
- from format import get_rich_root_format
- from mapping3 import set_branching_scheme
- from mapping3.scheme import TrunkBranchingScheme, NoBranchingScheme
- from tests import TestCaseWithSubversionRepository
+ from bzrlib.plugins.svn.convert import convert_repository, NotDumpFile, load_dumpfile
+ from bzrlib.plugins.svn.format import get_rich_root_format
+ from bzrlib.plugins.svn.mapping3 import set_branching_scheme
+ from bzrlib.plugins.svn.mapping3.scheme import TrunkBranchingScheme, NoBranchingScheme
+ from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
  
 -import svn.repos
 +import repos
  
  class TestLoadDumpfile(TestCaseInTempDir):
      def test_loaddumpfile(self):
index 1ae91a4ef2de84a3e4ad59c2c795dc0cc72ef75f,0a7c5569449a2479277fdb41828048ed4df4b05a..fd471d79201f8cd8335114e6f70fb53fa12df56e
@@@ -19,11 -19,12 +19,11 @@@ from bzrlib.errors import (ConnectionEr
                             UnexpectedEndOfContainerError)
  from bzrlib.tests import TestCase
  
- from errors import (convert_svn_error, convert_error, InvalidPropertyValue, 
++from bzrlib.plugins.svn import constants
++from bzrlib.plugins.svn.core import SubversionException
+ from bzrlib.plugins.svn.errors import (convert_svn_error, convert_error, InvalidPropertyValue, 
 -                    NotSvnBranchPath, InvalidSvnBranchPath,
 -                    SVN_ERR_UNKNOWN_HOSTNAME)
 +                    InvalidSvnBranchPath, NotSvnBranchPath)
- import constants
  
- from core import SubversionException
 -import svn.core
 -from svn.core import SubversionException
  
  class TestConvertError(TestCase):
      def test_decorator_unknown(self):
index 8e32ca3ab06272e3015b914eb09c3778821be82f,4053bab73205a8ca25b46fe7da6827dfceec72f3..7d72d59733efbd1d8af52baa48b31b62fc5a937e
@@@ -29,12 -29,13 +29,13 @@@ from bzrlib.trace import mutte
  from bzrlib.workingtree import WorkingTree
  
  import os
- import format
- from bzrlib.plugins.svn.errors import ChangesRootLHSHistory, MissingPrefix
 +from time import sleep
- from commit import push
- from mapping import SVN_PROP_BZR_REVISION_ID
- from tests import TestCaseWithSubversionRepository
++
+ from bzrlib.plugins.svn import format
 -import svn.core
+ from bzrlib.plugins.svn.errors import ChangesRootLHSHistory, MissingPrefix
 -from time import sleep
+ from bzrlib.plugins.svn.commit import push
+ from bzrlib.plugins.svn.mapping import SVN_PROP_BZR_REVISION_ID
+ from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
  
  class TestPush(TestCaseWithSubversionRepository):
      def setUp(self):
index db49ad461f291fba50afd524cfb30dc9cf6c9703,2fe8bf736c7dddcaa8f769433e26081f15a66c0e..506b7c34fd66e19d688078c0f529f92498fd79a9
@@@ -22,9 -22,11 +22,9 @@@ from bzrlib.bzrdir import BzrDir, forma
  from bzrlib.errors import (NoRepositoryPresent, NotBranchError, NotLocalUrl,
                             NoWorkingTree, AlreadyBranchError)
  
- from format import SvnRemoteFormat
- from tests import TestCaseWithSubversionRepository
- from transport import SvnRaTransport
 -import svn
 -
+ from bzrlib.plugins.svn.format import SvnRemoteFormat
+ from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
+ from bzrlib.plugins.svn.transport import SvnRaTransport
  
  class TestRemoteAccess(TestCaseWithSubversionRepository):
      def test_clone(self):
index 00824713d99e2a8b8b037863cfe6939a4a59372c,0000000000000000000000000000000000000000..bc8aa22ffbe9da6cf9168241dc38e6666c2894c5
mode 100644,000000..100644
--- /dev/null
@@@ -1,1232 -1,0 +1,1232 @@@
- import format
- from mapping import (escape_svn_path, unescape_svn_path, 
 +# -*- coding: utf-8 -*-
 +
 +# Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
 +
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
 +# the Free Software Foundation; either version 3 of the License, or
 +# (at your option) any later version.
 +
 +# This program is distributed in the hope that it will be useful,
 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +# GNU General Public License for more details.
 +
 +# You should have received a copy of the GNU General Public License
 +# along with this program; if not, write to the Free Software
 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 +
 +"""Subversion repository tests."""
 +
 +from bzrlib import urlutils
 +from bzrlib.branch import Branch
 +from bzrlib.bzrdir import BzrDir, format_registry
 +from bzrlib.config import GlobalConfig
 +from bzrlib.errors import NoSuchRevision, UninitializableFormat, BzrError
 +from bzrlib.inventory import Inventory
 +from bzrlib.osutils import has_symlinks
 +from bzrlib.repository import Repository
 +from bzrlib.revision import NULL_REVISION, Revision
 +from bzrlib.tests import TestCase
 +
 +import os, sys
 +
- from mapping3 import (SVN_PROP_BZR_BRANCHING_SCHEME, set_branching_scheme,
++from bzrlib.plugins.svn import format
++from bzrlib.plugins.svn.mapping import (escape_svn_path, unescape_svn_path, 
 +                     SVN_PROP_BZR_REVISION_ID)
- from mapping3.scheme import (TrunkBranchingScheme, NoBranchingScheme, 
++from bzrlib.plugins.svn.mapping3 import (SVN_PROP_BZR_BRANCHING_SCHEME, set_branching_scheme,
 +                      set_property_scheme, BzrSvnMappingv3)
- from transport import SvnRaTransport
- from tests import TestCaseWithSubversionRepository
- from repository import SvnRepositoryFormat
++from bzrlib.plugins.svn.mapping3.scheme import (TrunkBranchingScheme, NoBranchingScheme, 
 +                    ListBranchingScheme, SingleBranchingScheme)
++from bzrlib.plugins.svn.transport import SvnRaTransport
++from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
++from bzrlib.plugins.svn.repository import SvnRepositoryFormat
 +
 +
 +class TestSubversionRepositoryWorks(TestCaseWithSubversionRepository):
 +    def test_format(self):
 +        """ Test repository format is correct """
 +        bzrdir = self.make_local_bzrdir('a', 'ac')
 +        self.assertEqual(bzrdir._format.get_format_string(), \
 +                "Subversion Local Checkout")
 +        
 +        self.assertEqual(bzrdir._format.get_format_description(), \
 +                "Subversion Local Checkout")
 +
 +    def test_get_branch_log(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +
 +        repos = Repository.open(repos_url)
 +
 +        self.assertEqual([
 +            ('', {'foo': ('A', None, -1)}, 1), 
 +            ('', {'': ('A', None, -1)}, 0)],
 +            [(l.branch_path, l.paths, l.revnum) for l in repos.iter_reverse_branch_changes("", 1, NoBranchingScheme())])
 +
 +    def test_make_working_trees(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertFalse(repos.make_working_trees())
 +
 +    def test_get_config_global_set(self):
 +        repos_url = self.make_client("a", "dc")
 +        cfg = GlobalConfig()
 +        cfg.set_user_option("foo", "Still Life")
 +
 +        repos = Repository.open(repos_url)
 +        self.assertEquals("Still Life", 
 +                repos.get_config().get_user_option("foo"))
 +
 +    def test_get_config(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        repos.get_config().set_user_option("foo", "Van Der Graaf Generator")
 +
 +        repos = Repository.open(repos_url)
 +        self.assertEquals("Van Der Graaf Generator", 
 +                repos.get_config().get_user_option("foo"))
 +
 +
 +    def test_get_physical_lock_status(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertFalse(repos.get_physical_lock_status())
 +
 +    def test_iter_changes_parent_rename(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/foo/bar': None})
 +        self.client_add('dc/foo')
 +        self.client_commit('dc', 'a')
 +        self.client_update('dc')
 +        self.client_copy('dc/foo', 'dc/bla')
 +        self.client_commit('dc', 'b')
 +        repos = Repository.open(repos_url)
 +        ret = list(repos.iter_changes('bla/bar', 2, BzrSvnMappingv3(SingleBranchingScheme('bla/bar'))))
 +        self.assertEquals(1, len(ret))
 +        self.assertEquals("bla/bar", ret[0][0])
 +
 +    def test_set_make_working_trees(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        repos.set_make_working_trees(True)
 +        self.assertFalse(repos.make_working_trees())
 +
 +    def test_get_fileid_map(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        mapping = repos.get_mapping()
 +        self.assertEqual({u"": (mapping.generate_file_id(repos.uuid, 0, "", u""), mapping.generate_revision_id(repos.uuid, 0, ""))}, repos.get_fileid_map(0, "", mapping))
 +
 +    def test_generate_revision_id_forced_revid(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", 
 +                             "2 someid\n")
 +        self.client_commit("dc", "set id")
 +        repos = Repository.open(repos_url)
 +        revid = repos.generate_revision_id(1, "", repos.get_mapping())
 +        self.assertEquals("someid", revid)
 +
 +    def test_generate_revision_id_forced_revid_invalid(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", 
 +                             "corrupt-id\n")
 +        self.client_commit("dc", "set id")
 +        repos = Repository.open(repos_url)
 +        revid = repos.generate_revision_id(1, "", repos.get_mapping())
 +        self.assertEquals(
 +                repos.get_mapping().generate_revision_id(repos.uuid, 1, ""),
 +                revid)
 +
 +    def test_add_revision(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertRaises(NotImplementedError, repos.add_revision, "revid", 
 +                None)
 +
 +    def test_has_signature_for_revision_id_no(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertFalse(repos.has_signature_for_revision_id("foo"))
 +
 +    def test_set_signature(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.build_tree({"dc/foo": "bar"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "msg")
 +        revid = repos.get_mapping().generate_revision_id(repos.uuid, 1, "")
 +        repos.add_signature_text(revid, "TEXT")
 +        self.assertTrue(repos.has_signature_for_revision_id(revid))
 +        self.assertEquals(repos.get_signature_text(revid), "TEXT")
 +
 +    def test_repr(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +
 +        repos = Repository.open(repos_url)
 +
 +        self.assertEqual("SvnRepository('%s/')" % urlutils.local_path_to_url(urlutils.join(self.test_dir, "a")), repos.__repr__())
 +
 +    def test_get_branch_invalid_revision(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertRaises(NoSuchRevision, list, 
 +               repos.iter_reverse_branch_changes("/", 20, NoBranchingScheme()))
 +
 +    def test_follow_branch_switched_parents(self):
 +        repos_url = self.make_client('a', 'dc')
 +        self.build_tree({'dc/pykleur/trunk/pykleur': None})
 +        self.client_add("dc/pykleur")
 +        self.client_commit("dc", "initial")
 +        self.build_tree({'dc/pykleur/trunk/pykleur/afile': 'contents'})
 +        self.client_add("dc/pykleur/trunk/pykleur/afile")
 +        self.client_commit("dc", "add file")
 +        self.client_copy("dc/pykleur", "dc/pygments", 1)
 +        self.client_delete('dc/pykleur')
 +        self.client_update("dc")
 +        self.client_commit("dc", "commit")
 +        repos = Repository.open(repos_url)
 +        self.assertEquals([
 +            ('pygments/trunk', {'pygments': (u'A', 'pykleur', 1),
 +                                'pygments/trunk': (u'R', 'pykleur/trunk', 2),
 +                                'pykleur': (u'D', None, -1)}, 3),
 +            ('pykleur/trunk', {'pykleur/trunk/pykleur/afile': (u'A', None, -1)}, 2),
 +            ('pykleur/trunk',
 +                    {'pykleur': (u'A', None, -1),
 +                     'pykleur/trunk': (u'A', None, -1),
 +                     'pykleur/trunk/pykleur': (u'A', None, -1)},
 +             1)],
 +            [(l.branch_path, l.paths, l.revnum) for l in repos.iter_reverse_branch_changes("pygments/trunk", 3, TrunkBranchingScheme(1))])
 +
 +    def test_follow_branch_move_single(self):
 +        repos_url = self.make_client('a', 'dc')
 +        self.build_tree({'dc/pykleur/bla': None})
 +        self.client_add("dc/pykleur")
 +        self.client_commit("dc", "initial")
 +        self.client_copy("dc/pykleur", "dc/pygments", 1)
 +        self.client_update("dc")
 +        self.client_commit("dc", "commit")
 +        repos = Repository.open(repos_url)
 +        changes = repos.iter_reverse_branch_changes("pygments", 2, SingleBranchingScheme("pygments"))
 +        self.assertEquals([('pygments',
 +              {'pygments/bla': ('A', None, -1), 'pygments': ('A', None, -1)},
 +                2)],
 +                [(l.branch_path, l.paths, l.revnum) for l in changes])
 +
 +    def test_history_all(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
 +        self.client_add("dc/trunk")
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +
 +        repos = Repository.open(repos_url)
 +
 +        self.assertEqual(2, 
 +                   len(list(repos.all_revision_ids(repos.get_layout()))))
 +
 +    def test_all_revs_empty(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +        self.assertEqual([], list(repos.all_revision_ids()))
 +
 +    def test_all_revs(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
 +        self.client_add("dc/trunk")
 +        self.client_commit("dc", "add trunk")
 +        self.build_tree({'dc/branches/somebranch/somefile': 'data'})
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "add a branch")
 +        self.client_delete("dc/branches/somebranch")
 +        self.client_commit("dc", "remove branch")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +        mapping = repos.get_mapping()
 +        self.assertEqual([
 +            repos.generate_revision_id(1, "trunk", mapping), 
 +            repos.generate_revision_id(2, "branches/somebranch", mapping)],
 +            list(repos.all_revision_ids()))
 +
 +    def test_follow_history_empty(self):
 +        repos_url = self.make_client("a", "dc")
 +        repos = Repository.open(repos_url)
 +        self.assertEqual([repos.generate_revision_id(0, '', repos.get_mapping())], 
 +              list(repos.all_revision_ids(repos.get_layout())))
 +
 +    def test_follow_history_empty_branch(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
 +        self.client_add("dc/trunk")
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +        self.assertEqual([repos.generate_revision_id(1, 'trunk', repos.get_mapping())], 
 +                list(repos.all_revision_ids(repos.get_layout())))
 +
 +    def test_follow_history_follow(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
 +        self.client_add("dc/trunk")
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +
 +        self.client_copy("dc/trunk", "dc/branches/abranch")
 +        self.client_commit("dc", "Create branch")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        items = list(repos.all_revision_ids(repos.get_layout()))
 +        self.assertEqual([repos.generate_revision_id(1, 'trunk', repos.get_mapping()),
 +                          repos.generate_revision_id(2, 'branches/abranch', repos.get_mapping())
 +                          ], items)
 +
 +    def test_branch_log_specific(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/branches': None,
 +            'dc/branches/brancha': None,
 +            'dc/branches/branchab': None,
 +            'dc/branches/brancha/data': "data", 
 +            "dc/branches/branchab/data":"data"})
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.assertEqual(1, len(list(repos.iter_reverse_branch_changes("branches/brancha",
 +            1, TrunkBranchingScheme()))))
 +
 +    def test_branch_log_specific_ignore(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/branches': None})
 +        self.client_add("dc/branches")
 +        self.build_tree({
 +            'dc/branches/brancha': None,
 +            'dc/branches/branchab': None,
 +            'dc/branches/brancha/data': "data", 
 +            "dc/branches/branchab/data":"data"})
 +        self.client_add("dc/branches/brancha")
 +        self.client_commit("dc", "My Message")
 +
 +        self.client_add("dc/branches/branchab")
 +        self.client_commit("dc", "My Message2")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.assertEqual(1, len(list(repos.iter_reverse_branch_changes("branches/brancha",
 +            2, TrunkBranchingScheme()))))
 +
 +    def test_find_branches(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/branches/brancha': None,
 +            'dc/branches/branchab': None,
 +            'dc/branches/brancha/data': "data", 
 +            "dc/branches/branchab/data":"data"})
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +        branches = repos.find_branches()
 +        self.assertEquals(2, len(branches))
 +        self.assertEquals(urlutils.join(repos.base, "branches/brancha"), 
 +                          branches[1].base)
 +        self.assertEquals(urlutils.join(repos.base, "branches/branchab"), 
 +                          branches[0].base)
 +
 +    def test_find_branchpaths_moved(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/tmp/branches/brancha': None,
 +            'dc/tmp/branches/branchab': None,
 +            'dc/tmp/branches/brancha/data': "data", 
 +            "dc/tmp/branches/branchab/data":"data"})
 +        self.client_add("dc/tmp")
 +        self.client_commit("dc", "My Message")
 +        self.client_copy("dc/tmp/branches", "dc/tags")
 +        self.client_commit("dc", "My Message 2")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.assertEqual([("tags/branchab", 2, True), 
 +                          ("tags/brancha", 2, True)], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), to_revnum=2)))
 +
 +    def test_find_branchpaths_start_revno(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({'dc/branches/brancha': None})
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +        self.build_tree({'dc/branches/branchb': None})
 +        self.client_add("dc/branches/branchb")
 +        self.client_commit("dc", "My Message 2")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.assertEqual([("branches/branchb", 2, True)],
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), from_revnum=2, 
 +                    to_revnum=2)))
 +
 +    def test_find_branchpaths_file_moved_from_nobranch(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/tmp/trunk': None,
 +            'dc/bla/somefile': "contents"})
 +        self.client_add("dc/tmp")
 +        self.client_add("dc/bla")
 +        self.client_commit("dc", "My Message")
 +        self.client_copy("dc/bla", "dc/tmp/branches")
 +        self.client_delete("dc/tmp/branches/somefile")
 +        self.client_commit("dc", "My Message 2")
 +
 +        Repository.open(repos_url).find_branchpaths(TrunkBranchingScheme(2))
 +
 +    def test_find_branchpaths_deleted_from_nobranch(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/tmp/trunk': None,
 +            'dc/bla/somefile': "contents"})
 +        self.client_add("dc/tmp")
 +        self.client_add("dc/bla")
 +        self.client_commit("dc", "My Message")
 +        self.client_copy("dc/bla", "dc/tmp/branches")
 +        self.client_delete("dc/tmp/branches/somefile")
 +        self.client_commit("dc", "My Message 2")
 +
 +        Repository.open(repos_url).find_branchpaths(TrunkBranchingScheme(1))
 +
 +    def test_find_branchpaths_moved_nobranch(self):
 +        repos_url = self.make_client("a", "dc")
 +        self.build_tree({
 +            'dc/tmp/nested/foobar': None,
 +            'dc/tmp/nested/branches/brancha': None,
 +            'dc/tmp/nested/branches/branchab': None,
 +            'dc/tmp/nested/branches/brancha/data': "data", 
 +            "dc/tmp/nested/branches/branchab/data":"data"})
 +        self.client_add("dc/tmp")
 +        self.client_commit("dc", "My Message")
 +        self.client_copy("dc/tmp/nested", "dc/t2")
 +        self.client_commit("dc", "My Message 2")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme(1))
 +
 +        self.assertEqual([("t2/branches/brancha", 2, True), 
 +                          ("t2/branches/branchab", 2, True)], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(1), to_revnum=2)))
 +
 +    def test_find_branchpaths_no(self):
 +        repos_url = self.make_client("a", "dc")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, NoBranchingScheme())
 +
 +        self.assertEqual([("", 0, True)], 
 +                list(repos.find_branchpaths(NoBranchingScheme(), to_revnum=0)))
 +
 +    def test_find_branchpaths_no_later(self):
 +        repos_url = self.make_client("a", "dc")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, NoBranchingScheme())
 +
 +        self.assertEqual([("", 0, True)], 
 +                list(repos.find_branchpaths(NoBranchingScheme(), to_revnum=0)))
 +
 +    def test_find_branchpaths_trunk_empty(self):
 +        repos_url = self.make_client("a", "dc")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.assertEqual([], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), to_revnum=0)))
 +
 +    def test_find_branchpaths_trunk_one(self):
 +        repos_url = self.make_client("a", "dc")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.build_tree({'dc/trunk/foo': "data"})
 +        self.client_add("dc/trunk")
 +        self.client_commit("dc", "My Message")
 +
 +        self.assertEqual([("trunk", 1, True)], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), to_revnum=1)))
 +
 +    def test_find_branchpaths_removed(self):
 +        repos_url = self.make_client("a", "dc")
 +
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +
 +        self.build_tree({'dc/trunk/foo': "data"})
 +        self.client_add("dc/trunk")
 +        self.client_commit("dc", "My Message")
 +
 +        self.client_delete("dc/trunk")
 +        self.client_commit("dc", "remove")
 +
 +        self.assertEqual([("trunk", 1, True)], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), to_revnum=1)))
 +        self.assertEqual([("trunk", 1, False)], 
 +                list(repos.find_branchpaths(TrunkBranchingScheme(), to_revnum=2)))
 +
 +    def test_url(self):
 +        """ Test repository URL is kept """
 +        bzrdir = self.make_local_bzrdir('b', 'bc')
 +        self.assertTrue(isinstance(bzrdir, BzrDir))
 +
 +    def test_uuid(self):
 +        """ Test UUID is retrieved correctly """
 +        bzrdir = self.make_local_bzrdir('c', 'cc')
 +        self.assertTrue(isinstance(bzrdir, BzrDir))
 +        repository = bzrdir._find_repository()
 +        fs = self.open_fs('c')
 +        self.assertEqual(fs.get_uuid(fs), repository.uuid)
 +
 +    def test_get_inventory_weave(self):
 +        bzrdir = self.make_client_and_bzrdir('d', 'dc')
 +        repository = bzrdir.find_repository()
 +        self.assertRaises(NotImplementedError, repository.get_inventory_weave)
 +
 +    def test_has_revision(self):
 +        bzrdir = self.make_client_and_bzrdir('d', 'dc')
 +        repository = bzrdir.find_repository()
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.assertTrue(repository.has_revision(
 +            repository.generate_revision_id(1, "", repository.get_mapping())))
 +        self.assertFalse(repository.has_revision("some-other-revision"))
 +
 +    def test_has_revision_none(self):
 +        bzrdir = self.make_client_and_bzrdir('d', 'dc')
 +        repository = bzrdir.find_repository()
 +        self.assertTrue(repository.has_revision(None))
 +
 +    def test_has_revision_future(self):
 +        bzrdir = self.make_client_and_bzrdir('d', 'dc')
 +        repository = bzrdir.find_repository()
 +        self.assertFalse(repository.has_revision(
 +            repository.get_mapping().generate_revision_id(repository.uuid, 5, "")))
 +
 +    def test_get_parent_map(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        revid = repository.generate_revision_id(0, "", mapping)
 +        self.assertEqual({revid: (NULL_REVISION,)}, repository.get_parent_map([revid]))
 +        revid = repository.generate_revision_id(1, "", mapping)
 +        self.assertEqual({revid: (repository.generate_revision_id(0, "", mapping),)}, repository.get_parent_map([revid]))
 +        revid = repository.generate_revision_id(2, "", mapping)
 +        self.assertEqual({revid: (repository.generate_revision_id(1, "", mapping),)},
 +            repository.get_parent_map([revid]))
 +        self.assertEqual({}, repository.get_parent_map(["notexisting"]))
 +
 +    def test_revision_fileidmap(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_set_prop("dc", "bzr:revision-info", "")
 +        self.client_set_prop("dc", "bzr:file-ids", "foo\tsomeid\n")
 +        self.client_commit("dc", "My Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        tree = repository.revision_tree(Branch.open(repos_url).last_revision())
 +        self.assertEqual("someid", tree.inventory.path2id("foo"))
 +        self.assertFalse("1@%s::foo" % repository.uuid in tree.inventory)
 +
 +    def test_revision_ghost_parents(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_set_prop("dc", "bzr:ancestry:v3-none", "ghostparent\n")
 +        self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual((),
 +                repository.get_revision(
 +                    repository.generate_revision_id(0, "", mapping)).parent_ids)
 +        self.assertEqual((repository.generate_revision_id(0, "", mapping),),
 +                repository.get_revision(
 +                    repository.generate_revision_id(1, "", mapping)).parent_ids)
 +        self.assertEqual((repository.generate_revision_id(1, "", mapping),
 +            "ghostparent"), 
 +                repository.get_revision(
 +                    repository.generate_revision_id(2, "", mapping)).parent_ids)
 + 
 +    def test_revision_svk_parent(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/trunk/foo': "data", 'dc/branches/foo': None})
 +        self.client_add("dc/trunk")
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "My Message")
 +        self.client_update("dc")
 +        self.build_tree({'dc/trunk/foo': "data2"})
 +        repository = Repository.open("svn+%s" % repos_url)
 +        set_branching_scheme(repository, TrunkBranchingScheme())
 +        self.client_set_prop("dc/trunk", "svk:merge", 
 +            "%s:/branches/foo:1\n" % repository.uuid)
 +        self.client_commit("dc", "Second Message")
 +        mapping = repository.get_mapping()
 +        self.assertEqual((repository.generate_revision_id(1, "trunk", mapping),
 +            repository.generate_revision_id(1, "branches/foo", mapping)), 
 +                repository.get_revision(
 +                    repository.generate_revision_id(2, "trunk", mapping)).parent_ids)
 +    
 +    def test_get_revision(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, repository.get_revision, 
 +                "nonexisting")
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data2"})
 +        (num, date, author) = self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        rev = repository.get_revision(
 +            repository.generate_revision_id(2, "", mapping))
 +        self.assertEqual((repository.generate_revision_id(1, "", mapping),),
 +                rev.parent_ids)
 +        self.assertEqual(rev.revision_id, 
 +                repository.generate_revision_id(2, "", mapping))
 +        self.assertEqual(author, rev.committer)
 +        self.assertIsInstance(rev.properties, dict)
 +
 +    def test_get_revision_id_overriden(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_set_prop("dc", "bzr:revision-id:v3-none", 
 +                            "3 myrevid\n")
 +        self.client_update("dc")
 +        (num, date, author) = self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        revid = mapping.generate_revision_id(repository.uuid, 2, "")
 +        rev = repository.get_revision("myrevid")
 +        self.assertEqual((repository.generate_revision_id(1, "", mapping),),
 +                rev.parent_ids)
 +        self.assertEqual(rev.revision_id, 
 +                         repository.generate_revision_id(2, "", mapping))
 +        self.assertEqual(author, rev.committer)
 +        self.assertIsInstance(rev.properties, dict)
 +
 +    def test_get_revision_zero(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        rev = repository.get_revision(
 +            repository.generate_revision_id(0, "", mapping))
 +        self.assertEqual(repository.generate_revision_id(0, "", mapping), 
 +                         rev.revision_id)
 +        self.assertEqual("", rev.committer)
 +        self.assertEqual({}, rev.properties)
 +        self.assertEqual(None, rev.timezone)
 +
 +    def test_store_branching_scheme(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open(repos_url)
 +        set_branching_scheme(repository, TrunkBranchingScheme(42))
 +        repository = Repository.open(repos_url)
 +        self.assertEquals("trunk42", str(repository.get_mapping().scheme))
 +
 +    def test_get_ancestry(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_commit("dc", "Second Message")
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data3"})
 +        self.client_commit("dc", "Third Message")
 +        self.client_update("dc")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual([None, 
 +            repository.generate_revision_id(0, "", mapping),
 +            repository.generate_revision_id(1, "", mapping),
 +            repository.generate_revision_id(2, "", mapping),
 +            repository.generate_revision_id(3, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(3, "", mapping)))
 +        self.assertEqual([None, 
 +            repository.generate_revision_id(0, "", mapping),
 +            repository.generate_revision_id(1, "", mapping),
 +            repository.generate_revision_id(2, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(2, "", mapping)))
 +        self.assertEqual([None,
 +                    repository.generate_revision_id(0, "", mapping),
 +                    repository.generate_revision_id(1, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(1, "", mapping)))
 +        self.assertEqual([None, repository.generate_revision_id(0, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(0, "", mapping)))
 +        self.assertEqual([None], repository.get_ancestry(NULL_REVISION))
 +
 +    def test_get_ancestry2(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual([None, repository.generate_revision_id(0, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(0, "", mapping)))
 +        self.assertEqual([None, repository.generate_revision_id(0, "", mapping),
 +            repository.generate_revision_id(1, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(1, "", mapping)))
 +        self.assertEqual([None, 
 +            repository.generate_revision_id(0, "", mapping),
 +            repository.generate_revision_id(1, "", mapping),
 +            repository.generate_revision_id(2, "", mapping)], 
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(2, "", mapping)))
 +
 +    def test_get_ancestry_merged(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.client_update("dc")
 +        self.client_set_prop("dc", "bzr:ancestry:v3-none", "a-parent\n")
 +        self.build_tree({'dc/foo': "data2"})
 +        self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual([None, repository.generate_revision_id(0, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(0, "", mapping)))
 +        self.assertEqual([None, repository.generate_revision_id(0, "", mapping),
 +            repository.generate_revision_id(1, "", mapping)],
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(1, "", mapping)))
 +        self.assertEqual([None, 
 +            repository.generate_revision_id(0, "", mapping), "a-parent", 
 +            repository.generate_revision_id(1, "", mapping), 
 +                  repository.generate_revision_id(2, "", mapping)], 
 +                repository.get_ancestry(
 +                    repository.generate_revision_id(2, "", mapping)))
 +
 +    def test_get_inventory(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, repository.get_inventory, 
 +                "nonexisting")
 +        self.build_tree({'dc/foo': "data", 'dc/blah': "other data"})
 +        self.client_add("dc/foo")
 +        self.client_add("dc/blah")
 +        self.client_commit("dc", "My Message") #1
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data2", "dc/bar/foo": "data3"})
 +        self.client_add("dc/bar")
 +        self.client_commit("dc", "Second Message") #2
 +        self.client_update("dc")
 +        self.build_tree({'dc/foo': "data3"})
 +        self.client_commit("dc", "Third Message") #3
 +        self.client_update("dc")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        inv = repository.get_inventory(
 +                repository.generate_revision_id(1, "", mapping))
 +        self.assertIsInstance(inv, Inventory)
 +        self.assertIsInstance(inv.path2id("foo"), basestring)
 +        inv = repository.get_inventory(
 +            repository.generate_revision_id(2, "", mapping))
 +        self.assertEqual(repository.generate_revision_id(2, "", mapping), 
 +                         inv[inv.path2id("foo")].revision)
 +        self.assertEqual(repository.generate_revision_id(1, "", mapping), 
 +                         inv[inv.path2id("blah")].revision)
 +        self.assertIsInstance(inv, Inventory)
 +        self.assertIsInstance(inv.path2id("foo"), basestring)
 +        self.assertIsInstance(inv.path2id("bar"), basestring)
 +        self.assertIsInstance(inv.path2id("bar/foo"), basestring)
 +
 +    def test_generate_revision_id(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bla/bloe': None})
 +        self.client_add("dc/bla")
 +        self.client_commit("dc", "bla")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual(
 +               mapping.generate_revision_id(repository.uuid, 1, "bla/bloe"), 
 +            repository.generate_revision_id(1, "bla/bloe", mapping))
 +
 +    def test_generate_revision_id_zero(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual(mapping.generate_revision_id(repository.uuid, 0, ""), 
 +                repository.generate_revision_id(0, "", mapping))
 +
 +    def test_lookup_revision_id(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bloe': None})
 +        self.client_add("dc/bloe")
 +        self.client_commit("dc", "foobar")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, repository.lookup_revision_id, 
 +            "nonexisting")
 +        mapping = repository.get_mapping()
 +        self.assertEqual(("bloe", 1), 
 +            repository.lookup_revision_id(
 +                repository.generate_revision_id(1, "bloe", mapping))[:2])
 +
 +    def test_lookup_revision_id_overridden(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bloe': None})
 +        self.client_add("dc/bloe")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", "2 myid\n")
 +        self.client_commit("dc", "foobar")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual(("", 1), repository.lookup_revision_id( 
 +            mapping.generate_revision_id(repository.uuid, 1, ""))[:2])
 +        self.assertEqual(("", 1), 
 +                repository.lookup_revision_id("myid")[:2])
 +
 +    def test_lookup_revision_id_overridden_invalid(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bloe': None})
 +        self.client_add("dc/bloe")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", 
 +                             "corrupt-entry\n")
 +        self.client_commit("dc", "foobar")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual(("", 1), repository.lookup_revision_id( 
 +            mapping.generate_revision_id(repository.uuid, 1, ""))[:2])
 +        self.assertRaises(NoSuchRevision, repository.lookup_revision_id, 
 +            "corrupt-entry")
 +
 +    def test_lookup_revision_id_overridden_invalid_dup(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bloe': None})
 +        self.client_add("dc/bloe")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", 
 +                             "corrupt-entry\n")
 +        self.client_commit("dc", "foobar")
 +        self.build_tree({'dc/bla': None})
 +        self.client_add("dc/bla")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", 
 +                "corrupt-entry\n2 corrupt-entry\n")
 +        self.client_commit("dc", "foobar")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertEqual(("", 2), repository.lookup_revision_id( 
 +            mapping.generate_revision_id(repository.uuid, 2, ""))[:2])
 +        self.assertEqual(("", 1), repository.lookup_revision_id( 
 +            mapping.generate_revision_id(repository.uuid, 1, ""))[:2])
 +        self.assertEqual(("", 2), repository.lookup_revision_id( 
 +            "corrupt-entry")[:2])
 +
 +    def test_lookup_revision_id_overridden_not_found(self):
 +        """Make sure a revision id that is looked up but doesn't exist 
 +        doesn't accidently end up in the revid cache."""
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/bloe': None})
 +        self.client_add("dc/bloe")
 +        self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none", "2 myid\n")
 +        self.client_commit("dc", "foobar")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertRaises(NoSuchRevision, 
 +                repository.lookup_revision_id, "foobar")
 +
 +    def test_set_branching_scheme_property(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.client_set_prop("dc", SVN_PROP_BZR_BRANCHING_SCHEME, 
 +            "trunk\nbranches/*\nbranches/tmp/*")
 +        self.client_commit("dc", "set scheme")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertEquals(ListBranchingScheme(["trunk", "branches/*", "branches/tmp/*"]).branch_list,
 +                          repository.get_mapping().scheme.branch_list)
 +
 +    def test_set_property_scheme(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repos = Repository.open(repos_url)
 +        set_property_scheme(repos, ListBranchingScheme(["bla/*"]))
 +        self.client_update("dc")
 +        self.assertEquals("bla/*\n", 
 +                   self.client_get_prop("dc", SVN_PROP_BZR_BRANCHING_SCHEME))
 +        self.assertEquals("Updating branching scheme for Bazaar.", 
 +                self.client_log("dc", 1, 1)[1][3])
 +
 +    def test_lookup_revision_id_invalid_uuid(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        self.assertRaises(NoSuchRevision, 
 +            repository.lookup_revision_id, 
 +                mapping.generate_revision_id("invaliduuid", 0, ""))
 +        
 +    def test_check(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +        repository.check([
 +            repository.generate_revision_id(0, "", mapping), 
 +            repository.generate_revision_id(1, "", mapping)])
 +
 +    def test_copy_contents_into(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo/bla': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
 +        self.client_add("dc/foo/blo")
 +        self.client_add("dc/bar")
 +        self.client_commit("dc", "Second Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        mapping = repository.get_mapping()
 +
 +        to_bzrdir = BzrDir.create("e", format.get_rich_root_format())
 +        to_repos = to_bzrdir.create_repository()
 +
 +        repository.copy_content_into(to_repos, 
 +                repository.generate_revision_id(2, "", mapping))
 +
 +        self.assertTrue(repository.has_revision(
 +            repository.generate_revision_id(2, "", mapping)))
 +        self.assertTrue(repository.has_revision(
 +            repository.generate_revision_id(1, "", mapping)))
 +
 +    def test_is_shared(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo/bla': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        repository = Repository.open("svn+%s" % repos_url)
 +        self.assertTrue(repository.is_shared())
 +
 +    def test_fetch_property_change_only_trunk(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/trunk/bla': "data"})
 +        self.client_add("dc/trunk")
 +        self.client_commit("dc", "My Message")
 +        self.client_set_prop("dc/trunk", "some:property", "some data\n")
 +        self.client_commit("dc", "My 3")
 +        self.client_set_prop("dc/trunk", "some2:property", "some data\n")
 +        self.client_commit("dc", "My 2")
 +        self.client_set_prop("dc/trunk", "some:property", "some other data\n")
 +        self.client_commit("dc", "My 4")
 +        oldrepos = Repository.open("svn+"+repos_url)
 +        self.assertEquals([('trunk', {'trunk': (u'M', None, -1)}, 3), 
 +                           ('trunk', {'trunk': (u'M', None, -1)}, 2), 
 +                           ('trunk', {'trunk/bla': (u'A', None, -1), 'trunk': (u'A', None, -1)}, 1)], 
 +                   [(l.branch_path, l.paths, l.revnum) for l in oldrepos.iter_reverse_branch_changes("trunk", 3, TrunkBranchingScheme())])
 +
 +    def test_control_code_msg(self):
 +        repos_url = self.make_client('d', 'dc')
 +
 +        self.build_tree({'dc/trunk': None})
 +        self.client_add("dc/trunk")
 +        self.client_commit("dc", "\x24")
 +
 +        self.build_tree({'dc/trunk/hosts': 'hej2'})
 +        self.client_add("dc/trunk/hosts")
 +        self.client_commit("dc", "bla\xfcbla") #2
 +
 +        self.build_tree({'dc/trunk/hosts': 'hej3'})
 +        self.client_commit("dc", "a\x0cb") #3
 +
 +        self.build_tree({'dc/branches/foobranch/file': 'foohosts'})
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "foohosts") #4
 +
 +        oldrepos = Repository.open("svn+"+repos_url)
 +        set_branching_scheme(oldrepos, TrunkBranchingScheme())
 +        dir = BzrDir.create("f",format=format.get_rich_root_format())
 +        newrepos = dir.create_repository()
 +        oldrepos.copy_content_into(newrepos)
 +
 +        mapping = oldrepos.get_mapping()
 +
 +        self.assertTrue(newrepos.has_revision(
 +            oldrepos.generate_revision_id(1, "trunk", mapping)))
 +        self.assertTrue(newrepos.has_revision(
 +            oldrepos.generate_revision_id(2, "trunk", mapping)))
 +        self.assertTrue(newrepos.has_revision(
 +            oldrepos.generate_revision_id(3, "trunk", mapping)))
 +        self.assertTrue(newrepos.has_revision(
 +            oldrepos.generate_revision_id(4, "branches/foobranch", mapping)))
 +        self.assertFalse(newrepos.has_revision(
 +            oldrepos.generate_revision_id(4, "trunk", mapping)))
 +        self.assertFalse(newrepos.has_revision(
 +            oldrepos.generate_revision_id(2, "", mapping)))
 +
 +        rev = newrepos.get_revision(oldrepos.generate_revision_id(1, "trunk", mapping))
 +        self.assertEqual("$", rev.message)
 +
 +        rev = newrepos.get_revision(
 +            oldrepos.generate_revision_id(2, "trunk", mapping))
 +        self.assertEqual('bla\xc3\xbcbla', rev.message.encode("utf-8"))
 +
 +        rev = newrepos.get_revision(oldrepos.generate_revision_id(3, "trunk", mapping))
 +        self.assertEqual(u"a\\x0cb", rev.message)
 +
 +    def test_set_branching_scheme(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, NoBranchingScheme())
 +
 +    def testlhs_revision_parent_none(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, NoBranchingScheme())
 +        self.assertEquals(NULL_REVISION, repos.lhs_revision_parent("", 0, NoBranchingScheme()))
 +
 +    def testlhs_revision_parent_first(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, NoBranchingScheme())
 +        self.build_tree({'dc/adir/afile': "data"})
 +        self.client_add("dc/adir")
 +        self.client_commit("dc", "Initial commit")
 +        mapping = repos.get_mapping()
 +        self.assertEquals(repos.generate_revision_id(0, "", mapping), \
 +                repos.lhs_revision_parent("", 1, mapping))
 +
 +    def testlhs_revision_parent_simple(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/trunk/adir/afile': "data", 
 +                         'dc/trunk/adir/stationary': None,
 +                         'dc/branches/abranch': None})
 +        self.client_add("dc/trunk")
 +        self.client_add("dc/branches")
 +        self.client_commit("dc", "Initial commit")
 +        self.build_tree({'dc/trunk/adir/afile': "bla"})
 +        self.client_commit("dc", "Incremental commit")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme())
 +        mapping = repos.get_mapping()
 +        self.assertEquals(repos.generate_revision_id(1, "trunk", mapping), \
 +                repos.lhs_revision_parent("trunk", 2, mapping))
 +
 +    def testlhs_revision_parent_copied(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/py/trunk/adir/afile': "data", 
 +                         'dc/py/trunk/adir/stationary': None})
 +        self.client_add("dc/py")
 +        self.client_commit("dc", "Initial commit")
 +        self.client_copy("dc/py", "dc/de")
 +        self.client_commit("dc", "Incremental commit")
 +        self.build_tree({'dc/de/trunk/adir/afile': "bla"})
 +        self.client_commit("dc", "Change de")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme(1))
 +        mapping = repos.get_mapping()
 +        self.assertEquals(repos.generate_revision_id(1, "py/trunk", mapping), \
 +                repos.lhs_revision_parent("de/trunk", 3, mapping))
 +
 +    def test_mainline_revision_copied(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/py/trunk/adir/afile': "data", 
 +                         'dc/py/trunk/adir/stationary': None})
 +        self.client_add("dc/py")
 +        self.client_commit("dc", "Initial commit")
 +        self.build_tree({'dc/de':None})
 +        self.client_add("dc/de")
 +        self.client_copy("dc/py/trunk", "dc/de/trunk")
 +        self.client_commit("dc", "Copy trunk")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme(1))
 +        mapping = repos.get_mapping()
 +        self.assertEquals(repos.generate_revision_id(1, "py/trunk", mapping), \
 +                repos.lhs_revision_parent("de/trunk", 2, mapping))
 +
 +    def test_mainline_revision_nested_deleted(self):
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/py/trunk/adir/afile': "data", 
 +                         'dc/py/trunk/adir/stationary': None})
 +        self.client_add("dc/py")
 +        self.client_commit("dc", "Initial commit")
 +        self.client_copy("dc/py", "dc/de")
 +        self.client_commit("dc", "Incremental commit")
 +        self.client_delete("dc/de/trunk/adir")
 +        self.client_commit("dc", "Another incremental commit")
 +        repos = Repository.open(repos_url)
 +        set_branching_scheme(repos, TrunkBranchingScheme(1))
 +        mapping = repos.get_mapping()
 +        self.assertEquals(repos.generate_revision_id(1, "py/trunk", mapping), \
 +                repos.lhs_revision_parent("de/trunk", 3, mapping))
 +
 +    def test_mainline_revision_missing(self):
 +        repos_url = self.make_client('d', 'dc')
 +        repos = Repository.open(repos_url)
 +        self.build_tree({'dc/py/trunk/adir/afile': "data", 
 +                         'dc/py/trunk/adir/stationary': None})
 +        self.client_add("dc/py")
 +        self.client_commit("dc", "Initial commit")
 +        self.assertRaises(NoSuchRevision, 
 +                lambda: repos.lhs_revision_parent("trunk", 2, repos.get_mapping()))
 +
 +
 +class TestSvnRevisionTree(TestCaseWithSubversionRepository):
 +    def setUp(self):
 +        super(TestSvnRevisionTree, self).setUp()
 +        repos_url = self.make_client('d', 'dc')
 +        self.build_tree({'dc/foo/bla': "data"})
 +        self.client_add("dc/foo")
 +        self.client_commit("dc", "My Message")
 +        self.repos = Repository.open(repos_url)
 +        mapping = self.repos.get_mapping()
 +        self.inventory = self.repos.get_inventory(
 +                self.repos.generate_revision_id(1, "", mapping))
 +        self.tree = self.repos.revision_tree(
 +                self.repos.generate_revision_id(1, "", mapping))
 +
 +    def test_inventory(self):
 +        self.assertIsInstance(self.tree.inventory, Inventory)
 +        self.assertEqual(self.inventory, self.tree.inventory)
 +
 +    def test_get_parent_ids(self):
 +        mapping = self.repos.get_mapping()
 +        self.assertEqual((self.repos.generate_revision_id(0, "", mapping),), self.tree.get_parent_ids())
 +
 +    def test_get_parent_ids_zero(self):
 +        mapping = self.repos.get_mapping()
 +        tree = self.repos.revision_tree(
 +                self.repos.generate_revision_id(0, "", mapping))
 +        self.assertEqual((), tree.get_parent_ids())
 +
 +    def test_get_revision_id(self):
 +        mapping = self.repos.get_mapping()
 +        self.assertEqual(self.repos.generate_revision_id(1, "", mapping),
 +                         self.tree.get_revision_id())
 +
 +    def test_get_file_lines(self):
 +        self.assertEqual(["data"], 
 +                self.tree.get_file_lines(self.inventory.path2id("foo/bla")))
 +
 +    def test_executable(self):
 +        self.client_set_prop("dc/foo/bla", "svn:executable", "*")
 +        self.client_commit("dc", "My Message")
 +
 +        mapping = self.repos.get_mapping()
 +        
 +        inventory = self.repos.get_inventory(
 +                self.repos.generate_revision_id(2, "", mapping))
 +
 +        self.assertTrue(inventory[inventory.path2id("foo/bla")].executable)
 +
 +    def test_symlink(self):
 +        if not has_symlinks():
 +            return
 +        os.symlink('foo/bla', 'dc/bar')
 +        self.client_add('dc/bar')
 +        self.client_commit("dc", "My Message")
 +
 +        mapping = self.repos.get_mapping()
 +        
 +        inventory = self.repos.get_inventory(
 +                self.repos.generate_revision_id(2, "", mapping))
 +
 +        self.assertEqual('symlink', inventory[inventory.path2id("bar")].kind)
 +        self.assertEqual('foo/bla', 
 +                inventory[inventory.path2id("bar")].symlink_target)
 +
 +    def test_not_executable(self):
 +        self.assertFalse(self.inventory[
 +            self.inventory.path2id("foo/bla")].executable)
 +
 +
 +class EscapeTest(TestCase):
 +    def test_escape_svn_path_none(self):      
 +        self.assertEqual("", escape_svn_path(""))
 +
 +    def test_escape_svn_path_simple(self):
 +        self.assertEqual("ab", escape_svn_path("ab"))
 +
 +    def test_escape_svn_path_percent(self):
 +        self.assertEqual("a%25b", escape_svn_path("a%b"))
 +
 +    def test_escape_svn_path_whitespace(self):
 +        self.assertEqual("foobar%20", escape_svn_path("foobar "))
 +
 +    def test_escape_svn_path_slash(self):
 +        self.assertEqual("foobar%2F", escape_svn_path("foobar/"))
 +
 +    def test_escape_svn_path_special_char(self):
 +        self.assertEqual("foobar%8A", escape_svn_path("foobar\x8a"))
 +
 +    def test_unescape_svn_path_slash(self):
 +        self.assertEqual("foobar/", unescape_svn_path("foobar%2F"))
 +
 +    def test_unescape_svn_path_none(self):
 +        self.assertEqual("foobar", unescape_svn_path("foobar"))
 +
 +    def test_unescape_svn_path_percent(self):
 +        self.assertEqual("foobar%b", unescape_svn_path("foobar%25b"))
 +
 +    def test_escape_svn_path_nordic(self):
 +        self.assertEqual("foobar%C3%A6", escape_svn_path(u"foobar\xe6".encode("utf-8")))
 +
 +
 +class SvnRepositoryFormatTests(TestCase):
 +    def setUp(self):
 +        self.format = SvnRepositoryFormat()
 +
 +    def test_initialize(self):
 +        self.assertRaises(UninitializableFormat, self.format.initialize, None)
 +
 +    def test_get_format_description(self):
 +        self.assertEqual("Subversion Repository", 
 +                         self.format.get_format_description())
 +
 +    def test_conversion_target_self(self):
 +        self.assertTrue(self.format.check_conversion_target(self.format))
 +
 +    def test_conversion_target_incompatible(self):
 +        self.assertFalse(self.format.check_conversion_target(
 +              format_registry.make_bzrdir('weave').repository_format))
 +
 +    def test_conversion_target_compatible(self):
 +        self.assertTrue(self.format.check_conversion_target(
 +          format_registry.make_bzrdir('rich-root').repository_format))
 +
 +
 +
Simple merge
diff --cc transport.py
index 172d8a5b97e9fc86b05729bf630cd74f418061d2,9efb04fccfe35028601ca3123bee43b038b6bbfb..0f2ed772d6221d8d35fb48a49ede8eef76267a74
@@@ -21,13 -21,12 +21,13 @@@ from bzrlib.errors import (NoSuchFile, 
  from bzrlib.trace import mutter
  from bzrlib.transport import Transport
  
 -from svn.core import SubversionException, Pool
 -import svn.ra
 -import svn.core
 -import svn.client
 +from core import SubversionException
 +from auth import create_auth_baton
 +import ra
 +import core
 +import constants
  
- from errors import convert_svn_error, NoSvnRepositoryPresent
+ from bzrlib.plugins.svn.errors import convert_svn_error, NoSvnRepositoryPresent
  import urlparse
  import urllib
  
diff --cc tree.py
index 4811f491b8734ac0f574ee0a2f94f0e04c098773,af3e63c315caceb85ea7f9b472a792912dfd432c..6573b6d225db702cfee674996c708864be9c965c
+++ b/tree.py
@@@ -28,10 -28,10 +28,8 @@@ import md
  from cStringIO import StringIO
  import urllib
  
- import constants
- import core, wc
- from delta import apply_txdelta_handler
- import errors
 -import svn.core, svn.wc, svn.delta
 -from svn.core import Pool
 -
 -from bzrlib.plugins.svn import errors
++from bzrlib.plugins.svn.delta import apply_txdelta_handler
++from bzrlib.plugins.svn import core, constants, errors, wc
  
  def parse_externals_description(base_url, val):
      """Parse an svn:externals property value.
diff --cc workingtree.py
index 9f566ebab3bf7232e6d9f6e7197d495d9a353fb5,1b85de73e814e22739d4aedb21d9aad74b9ffc62..bf93e2a3726d668116be2f7547bb7e99ef9ad061
@@@ -31,28 -32,29 +31,28 @@@ from bzrlib.revisiontree import Revisio
  from bzrlib.transport.local import LocalTransport
  from bzrlib.workingtree import WorkingTree, WorkingTreeFormat
  
- from branch import SvnBranch
- from commit import _revision_id_to_svk_feature
- import constants
- from convert import SvnConverter
- from errors import NoSvnRepositoryPresent
++from bzrlib.plugins.svn import constants
+ from bzrlib.plugins.svn.branch import SvnBranch
+ from bzrlib.plugins.svn.commit import _revision_id_to_svk_feature
+ from bzrlib.plugins.svn.convert import SvnConverter
+ from bzrlib.plugins.svn.errors import LocalCommitsUnsupported, NoSvnRepositoryPresent
  from bzrlib.plugins.svn.mapping import (SVN_PROP_BZR_ANCESTRY, SVN_PROP_BZR_FILEIDS, 
                       SVN_PROP_BZR_REVISION_ID, SVN_PROP_BZR_REVISION_INFO,
                       generate_revision_metadata)
- from remote import SvnRemoteAccess
- from repository import SvnRepository
- from svk import SVN_PROP_SVK_MERGE, parse_svk_features, serialize_svk_features
+ from bzrlib.plugins.svn.remote import SvnRemoteAccess
+ from bzrlib.plugins.svn.repository import SvnRepository
+ from bzrlib.plugins.svn.svk import SVN_PROP_SVK_MERGE, parse_svk_features, serialize_svk_features
  from bzrlib.plugins.svn.mapping import escape_svn_path
- from transport import (SvnRaTransport, bzr_to_svn_url, svn_config) 
- from tree import SvnBasisTree
 -from bzrlib.plugins.svn.transport import (SvnRaTransport, bzr_to_svn_url, create_svn_client,
 -                       svn_config) 
++from bzrlib.plugins.svn.transport import (SvnRaTransport, bzr_to_svn_url, svn_config) 
+ from bzrlib.plugins.svn.tree import SvnBasisTree
  
  import os
  import urllib
  
 -import svn.core, svn.wc
 -from svn.core import SubversionException
 +import core, wc
 +from core import SubversionException, time_to_cstring
  
- from format import get_rich_root_format
 -from bzrlib.plugins.svn.errors import NoCheckoutSupport
+ from bzrlib.plugins.svn.format import get_rich_root_format
  
  def generate_ignore_list(ignore_map):
      """Create a list of ignores, ordered by directory.