1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 """Subversion BzrDir formats."""
19 from bzrlib import urlutils
20 from bzrlib.bzrdir import BzrDirFormat, BzrDir, format_registry
21 from bzrlib.errors import (NotBranchError, NotLocalUrl, NoRepositoryPresent,
22 NoWorkingTree, AlreadyBranchError)
23 from bzrlib.transport.local import LocalTransport
25 from core import SubversionException
28 from bzrlib.plugins.svn import core
29 from bzrlib.plugins.svn.errors import NoSvnRepositoryPresent
30 from bzrlib.plugins.svn.format import get_rich_root_format, SvnRemoteFormat
31 from bzrlib.plugins.svn.repository import SvnRepository
32 from bzrlib.plugins.svn.transport import bzr_to_svn_url, get_svn_ra_transport
35 class SvnRemoteAccess(BzrDir):
36 """BzrDir implementation for Subversion connections.
38 This is used for all non-checkout connections
39 to Subversion repositories.
41 def __init__(self, _transport, _format=None):
42 """See BzrDir.__init__()."""
43 _transport = get_svn_ra_transport(_transport)
45 _format = SvnRemoteFormat()
46 self._format = _format
48 self.root_transport = _transport
50 svn_url = bzr_to_svn_url(self.root_transport.base)
51 self.svn_root_url = _transport.get_svn_repos_root()
52 self.root_url = _transport.get_repos_root()
54 assert svn_url.startswith(self.svn_root_url)
55 self.branch_path = svn_url[len(self.svn_root_url):]
57 def clone(self, url, revision_id=None, force_new_repo=False):
58 """See BzrDir.clone().
60 Not supported on Subversion connections.
62 raise NotImplementedError(SvnRemoteAccess.clone)
64 def open_repository(self, _unsupported=False):
65 """Open the repository associated with this BzrDir.
67 :return: instance of SvnRepository.
69 if self.branch_path == "":
70 return SvnRepository(self, self.root_transport)
71 raise NoSvnRepositoryPresent(self.root_transport.base)
73 def find_repository(self):
74 """Open the repository associated with this BzrDir.
76 :return: instance of SvnRepository.
78 transport = self.root_transport
79 if self.root_url != transport.base:
80 transport = transport.clone_root()
81 return SvnRepository(self, transport, self.branch_path)
83 def cloning_metadir(self):
84 """Produce a metadir suitable for cloning with."""
85 return bzrlib.bzrdir.format_registry.make_bzrdir("rich-root-pack")
87 def open_workingtree(self, _unsupported=False,
88 recommend_upgrade=True):
89 """See BzrDir.open_workingtree().
91 Will always raise NotLocalUrl as this
92 BzrDir can not be associated with working trees.
94 # Working trees never exist on remote Subversion repositories
95 raise NoWorkingTree(self.root_transport.base)
97 def create_workingtree(self, revision_id=None, hardlink=None):
98 """See BzrDir.create_workingtree().
100 Will always raise NotLocalUrl as this
101 BzrDir can not be associated with working trees.
103 raise NotLocalUrl(self.root_transport.base)
105 def needs_format_conversion(self, format=None):
106 """See BzrDir.needs_format_conversion()."""
107 # if the format is not the same as the system default,
108 # an upgrade is needed.
110 format = BzrDirFormat.get_default_format()
111 return not isinstance(self._format, format.__class__)
113 def import_branch(self, source, stop_revision=None):
114 """Create a new branch in this repository, possibly
115 with the specified history, optionally importing revisions.
117 :param source: Source branch
118 :param stop_revision: Tip of new branch
119 :return: Branch object
121 from commit import push_new
122 if stop_revision is None:
123 stop_revision = source.last_revision()
124 target_branch_path = self.branch_path.strip("/")
125 repos = self.find_repository()
128 full_branch_url = urlutils.join(repos.transport.base,
130 if repos.transport.check_path(target_branch_path,
131 repos.get_latest_revnum()) != core.NODE_NONE:
132 raise AlreadyBranchError(full_branch_url)
133 push_new(repos, target_branch_path, source, stop_revision)
136 branch = self.open_branch()
139 branch.pull(source, stop_revision=stop_revision)
144 def create_branch(self):
145 """See BzrDir.create_branch()."""
146 from branch import SvnBranch
147 repos = self.find_repository()
149 if self.branch_path != "":
150 # TODO: Set NULL_REVISION in SVN_PROP_BZR_BRANCHING_SCHEME
151 repos.transport.mkdir(self.branch_path.strip("/"))
152 elif repos.get_latest_revnum() > 0:
153 # Bail out if there are already revisions in this repository
154 raise AlreadyBranchError(self.root_transport.base)
155 branch = SvnBranch(self.root_transport.base, repos, self.branch_path)
159 def open_branch(self, unsupported=True):
160 """See BzrDir.open_branch()."""
161 from branch import SvnBranch
162 repos = self.find_repository()
163 branch = SvnBranch(self.root_transport.base, repos, self.branch_path)
167 def create_repository(self, shared=False, format=None):
168 """See BzrDir.create_repository."""
169 return self.open_repository()