17
17
"""Server-side bzrdir related request implmentations."""
19
from __future__ import absolute_import
20
from bzrlib import branch, errors, repository, urlutils
28
21
from bzrlib.bzrdir import (
33
from bzrlib.controldir import (
34
25
network_format_registry,
36
27
from bzrlib.smart.request import (
53
44
# clients that don't anticipate errors from this method.
56
bzr_prober = BzrProber()
47
default_format = BzrDirFormat.get_default_format()
48
real_bzrdir = default_format.open(t, _found=True)
58
bzr_prober.probe_transport(t)
50
real_bzrdir._format.probe_transport(t)
59
51
except (errors.NotBranchError, errors.UnknownFormatError):
92
84
class SmartServerRequestBzrDir(SmartServerRequest):
94
86
def do(self, path, *args):
95
"""Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
87
"""Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
97
89
self._bzrdir = BzrDir.open_from_transport(
98
90
self.transport_from_client_path(path))
118
110
"""Get the relative path for repository from current_transport."""
119
111
# the relpath of the bzrdir in the found repository gives us the
120
112
# path segments to pop-out.
121
relpath = repository.user_transport.relpath(
113
relpath = repository.bzrdir.root_transport.relpath(
122
114
current_transport.base)
124
116
segments = ['..'] * len(relpath.split('/'))
127
119
return '/'.join(segments)
130
class SmartServerBzrDirRequestDestroyBranch(SmartServerRequestBzrDir):
132
def do_bzrdir_request(self, name=None):
133
"""Destroy the branch with the specified name.
136
:return: On success, 'ok'.
139
self._bzrdir.destroy_branch(name)
140
except errors.NotBranchError, e:
141
return FailedSmartServerResponse(('nobranch',))
142
return SuccessfulSmartServerResponse(('ok',))
145
class SmartServerBzrDirRequestHasWorkingTree(SmartServerRequestBzrDir):
147
def do_bzrdir_request(self, name=None):
148
"""Check whether there is a working tree present.
152
:return: If there is a working tree present, 'yes'.
155
if self._bzrdir.has_workingtree():
156
return SuccessfulSmartServerResponse(('yes', ))
158
return SuccessfulSmartServerResponse(('no', ))
161
class SmartServerBzrDirRequestDestroyRepository(SmartServerRequestBzrDir):
163
def do_bzrdir_request(self, name=None):
164
"""Destroy the repository.
168
:return: On success, 'ok'.
171
self._bzrdir.destroy_repository()
172
except errors.NoRepositoryPresent, e:
173
return FailedSmartServerResponse(('norepository',))
174
return SuccessfulSmartServerResponse(('ok',))
177
122
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
179
124
def do_bzrdir_request(self, require_stacking):
203
148
control_format = self._bzrdir.cloning_metadir(
204
149
require_stacking=require_stacking)
205
150
control_name = control_format.network_name()
206
if not control_format.fixed_components:
151
# XXX: There should be a method that tells us that the format does/does
152
# not have subformats.
153
if isinstance(control_format, BzrDirMetaFormat1):
207
154
branch_name = ('branch',
208
155
control_format.get_branch_format().network_name())
209
156
repository_name = control_format.repository_format.network_name()
218
class SmartServerBzrDirRequestCheckoutMetaDir(SmartServerRequestBzrDir):
219
"""Get the format to use for checkouts.
223
:return: on success, a 3-tuple of network names for (control,
224
repository, branch) directories, where '' signifies "not present".
225
If this BzrDir contains a branch reference then this will fail with
226
BranchReference; clients should resolve branch references before
227
calling this RPC (they should not try to create a checkout of a
231
def do_bzrdir_request(self):
233
branch_ref = self._bzrdir.get_branch_reference()
234
except errors.NotBranchError:
236
if branch_ref is not None:
237
# The server shouldn't try to resolve references, and it quite
238
# possibly can't reach them anyway. The client needs to resolve
239
# the branch reference to determine the cloning_metadir.
240
return FailedSmartServerResponse(('BranchReference',))
241
control_format = self._bzrdir.checkout_metadir()
242
control_name = control_format.network_name()
243
if not control_format.fixed_components:
244
branch_name = control_format.get_branch_format().network_name()
245
repo_name = control_format.repository_format.network_name()
249
return SuccessfulSmartServerResponse(
250
(control_name, repo_name, branch_name))
253
165
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
255
167
def do(self, path, network_name):
268
180
:param path: The path to the bzrdir.
269
181
:param network_name: The network name of the branch type to create.
270
:return: ('ok', branch_format, repo_path, rich_root, tree_ref,
271
external_lookup, repo_format)
182
:return: (ok, network_name)
273
184
bzrdir = BzrDir.open_from_transport(
274
185
self.transport_from_client_path(path))
275
186
format = branch.network_format_registry.get(network_name)
276
187
bzrdir.branch_format = format
277
result = format.initialize(bzrdir, name="")
188
result = format.initialize(bzrdir)
278
189
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
279
190
result.repository._format)
280
191
branch_format = result._format.network_name()
431
342
return SuccessfulSmartServerResponse((), content)
434
class SmartServerBzrDirRequestGetBranches(SmartServerRequestBzrDir):
436
def do_bzrdir_request(self):
437
"""Get the branches in a control directory.
439
The body is a bencoded dictionary, with values similar to the return
440
value of the open branch request.
442
branches = self._bzrdir.get_branches()
444
for name, b in branches.iteritems():
447
ret[name] = ("branch", b._format.network_name())
448
return SuccessfulSmartServerResponse(
449
("success", ), bencode.bencode(ret))
452
345
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
454
347
def do(self, path):
536
429
# It is returned locked, but we need to do the lock to get the lock
539
repo_lock_token = repo.lock_write().repository_token or ''
432
repo_lock_token = repo.lock_write() or ''
540
433
if repo_lock_token:
541
434
repo.leave_lock_in_place()