1 # Copyright (C) 2005-2006 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 2 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
17 from bzrlib.branch import Branch, BranchFormat, BranchCheckResult, BzrBranch
18 from bzrlib.delta import compare_trees
19 from bzrlib.errors import (NotBranchError, NoWorkingTree, NoSuchRevision,
21 from bzrlib.inventory import (Inventory, InventoryFile, InventoryDirectory,
23 from bzrlib.revision import Revision, NULL_REVISION
24 from bzrlib.tree import Tree, EmptyTree
25 from bzrlib.trace import mutter, note
26 from bzrlib.workingtree import WorkingTree
30 import svn.core, svn.ra
31 from svn.core import SubversionException
35 class FakeControlFiles(object):
36 def get_utf8(self, name):
37 raise NoSuchFile(name)
40 class SvnBranch(Branch):
41 """Maps to a Branch in a Subversion repository """
42 def __init__(self, repos, branch_path):
43 """Instantiate a new SvnBranch.
45 :param repos: SvnRepository this branch is part of.
46 :param branch_path: Relative path inside the repository this
49 self.repository = repos
50 self.branch_path = branch_path
51 self.control_files = FakeControlFiles()
52 self._generate_revision_history()
53 self.base = "%s/%s" % (repos.url, branch_path)
54 self._format = SvnBranchFormat()
55 mutter("Connected to branch at %s" % branch_path)
60 Doesn't do anything for Subversion repositories at the moment (yet).
62 return BranchCheckResult(self)
64 def _generate_revision_history(self):
66 return self.repository.generate_revision_id(rev, self.branch_path)
67 self._revision_history = map(rcvr,
68 self.repository._log.follow_history(self.branch_path, self.repository.latest_revnum))
70 def set_root_id(self, file_id):
71 raise NotImplementedError(self.set_root_id)
73 def get_root_id(self):
74 inv = self.repository.get_inventory(self.last_revision())
75 return inv.root.file_id
78 return self.branch_path
80 nick = property(_get_nick)
82 def abspath(self, name):
83 return self.base+"/"+name
85 def push_stores(self, branch_to):
86 raise NotImplementedError(self.push_stores)
88 def get_revision_inventory(self, revision_id):
89 raise NotImplementedError(self.get_revision_inventory)
91 def sign_revision(self, revision_id, gpg_strategy):
92 raise NotImplementedError(self.sign_revision)
94 def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
95 raise NotImplementedError(self.store_revision_signature)
97 def set_revision_history(self, rev_history):
98 raise NotImplementedError(self.set_revision_history)
100 def set_push_location(self, location):
101 raise NotImplementedError(self.set_push_location)
103 def get_push_location(self):
104 # get_push_location not supported on Subversion
107 def revision_history(self):
108 return self._revision_history
110 def pull(self, source, overwrite=False):
111 raise NotImplementedError(self.pull)
113 def update_revisions(self, other, stop_revision=None):
114 raise NotImplementedError(self.update_revisions)
116 def pullable_revisions(self, other, stop_revision):
117 raise NotImplementedError(self.pullable_revisions)
119 # The remote server handles all this for us
120 def lock_write(self):
129 def get_parent(self):
132 def set_parent(self, url):
133 raise NotImplementedError(self.set_parent,
134 'can not change parent of SVN branch')
136 def get_transaction(self):
137 raise NotImplementedError(self.get_transaction)
139 def append_revision(self, *revision_ids):
140 # FIXME: raise NotImplementedError(self.append_revision)
143 def get_physical_lock_status(self):
146 def sprout(self, to_bzrdir, revision_id=None):
147 result = BranchFormat.get_default_format().initialize(to_bzrdir)
148 self.copy_content_into(result, revision_id=revision_id)
149 result.set_parent(self.bzrdir.root_transport.base)
152 def copy_content_into(self, destination, revision_id=None):
153 new_history = self.revision_history()
154 if revision_id is not None:
156 new_history = new_history[:new_history.index(revision_id) + 1]
158 rev = self.repository.get_revision(revision_id)
159 new_history = rev.get_history(self.repository)[1:]
160 destination.set_revision_history(new_history)
161 parent = self.get_parent()
163 destination.set_parent(parent)
166 class SvnBranchFormat(BranchFormat):
167 """ Branch format for Subversion Branches."""
169 BranchFormat.__init__(self)
171 def get_format_description(self):
172 """See Branch.get_format_description."""
173 return 'Subversion Smart Server'
175 def get_format_string(self):
176 return 'Subversion Smart Server'
178 def initialize(self, to_bzrdir):
179 raise NotImplementedError(self.initialize)