71
def _format_to_capabilities(self, repo_format):
72
rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
73
tree_ref = self._boolean_to_yes_no(
74
repo_format.supports_tree_reference)
75
external_lookup = self._boolean_to_yes_no(
76
repo_format.supports_external_lookups)
77
return rich_root, tree_ref, external_lookup
79
def _repo_relpath(self, current_transport, repository):
80
"""Get the relative path for repository from current_transport."""
81
# the relpath of the bzrdir in the found repository gives us the
62
def _find(self, path):
63
"""try to find a repository from path upwards
65
This operates precisely like 'bzrdir.find_repository'.
67
:return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
68
strings, relpath is a / prefixed path, and the other three are
70
:raises errors.NoRepositoryPresent: When there is no repository
73
bzrdir = BzrDir.open_from_transport(
74
self.transport_from_client_path(path))
75
repository = bzrdir.find_repository()
76
# the relpath of the bzrdir in the found repository gives us the
82
77
# path segments to pop-out.
83
78
relpath = repository.bzrdir.root_transport.relpath(
84
current_transport.base)
79
bzrdir.root_transport.base)
86
81
segments = ['..'] * len(relpath.split('/'))
89
return '/'.join(segments)
92
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
94
def do_bzrdir_request(self, require_stacking):
95
"""Get the format that should be used when cloning from this dir.
99
:return: on success, a 3-tuple of network names for (control,
100
repository, branch) directories, where '' signifies "not present".
101
If this BzrDir contains a branch reference then this will fail with
102
BranchReference; clients should resolve branch references before
106
branch_ref = self._bzrdir.get_branch_reference()
107
except errors.NotBranchError:
109
if branch_ref is not None:
110
# The server shouldn't try to resolve references, and it quite
111
# possibly can't reach them anyway. The client needs to resolve
112
# the branch reference to determine the cloning_metadir.
113
return FailedSmartServerResponse(('BranchReference',))
114
if require_stacking == "True":
115
require_stacking = True
117
require_stacking = False
118
control_format = self._bzrdir.cloning_metadir(
119
require_stacking=require_stacking)
120
control_name = control_format.network_name()
121
# XXX: There should be a method that tells us that the format does/does
122
# not have subformats.
123
if isinstance(control_format, BzrDirMetaFormat1):
124
branch_name = ('branch',
125
control_format.get_branch_format().network_name())
126
repository_name = control_format.repository_format.network_name()
128
# Only MetaDir has delegated formats today.
129
branch_name = ('branch', '')
131
return SuccessfulSmartServerResponse((control_name, repository_name,
135
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
137
def do(self, path, network_name):
138
"""Create a branch in the bzr dir at path.
140
This operates precisely like 'bzrdir.create_branch'.
142
If a bzrdir is not present, an exception is propogated
143
rather than 'no branch' because these are different conditions (and
144
this method should only be called after establishing that a bzr dir
147
This is the initial version of this method introduced to the smart
150
:param path: The path to the bzrdir.
151
:param network_name: The network name of the branch type to create.
152
:return: (ok, network_name)
154
bzrdir = BzrDir.open_from_transport(
155
self.transport_from_client_path(path))
156
format = branch.network_format_registry.get(network_name)
157
bzrdir.branch_format = format
158
result = format.initialize(bzrdir)
159
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
160
result.repository._format)
161
branch_format = result._format.network_name()
162
repo_format = result.repository._format.network_name()
163
repo_path = self._repo_relpath(bzrdir.root_transport,
165
# branch format, repo relpath, rich_root, tree_ref, external_lookup,
167
return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
168
rich_root, tree_ref, external_lookup, repo_format))
171
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
173
def do(self, path, network_name, shared):
174
"""Create a repository in the bzr dir at path.
176
This operates precisely like 'bzrdir.create_repository'.
178
If a bzrdir is not present, an exception is propogated
179
rather than 'no branch' because these are different conditions (and
180
this method should only be called after establishing that a bzr dir
183
This is the initial version of this method introduced to the smart
186
:param path: The path to the bzrdir.
187
:param network_name: The network name of the repository type to create.
188
:param shared: The value to pass create_repository for the shared
190
:return: (ok, rich_root, tree_ref, external_lookup, network_name)
192
bzrdir = BzrDir.open_from_transport(
193
self.transport_from_client_path(path))
194
shared = shared == 'True'
195
format = repository.network_format_registry.get(network_name)
196
bzrdir.repository_format = format
197
result = format.initialize(bzrdir, shared=shared)
198
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
200
return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
201
external_lookup, result._format.network_name()))
204
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
206
def _find(self, path):
207
"""try to find a repository from path upwards
209
This operates precisely like 'bzrdir.find_repository'.
211
:return: (relpath, rich_root, tree_ref, external_lookup, network_name).
212
All are strings, relpath is a / prefixed path, the next three are
213
either 'yes' or 'no', and the last is a repository format network
215
:raises errors.NoRepositoryPresent: When there is no repository
218
bzrdir = BzrDir.open_from_transport(
219
self.transport_from_client_path(path))
220
repository = bzrdir.find_repository()
221
path = self._repo_relpath(bzrdir.root_transport, repository)
222
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
224
network_name = repository._format.network_name()
225
return path, rich_root, tree_ref, external_lookup, network_name
84
rich_root = self._boolean_to_yes_no(repository.supports_rich_root())
85
tree_ref = self._boolean_to_yes_no(
86
repository._format.supports_tree_reference)
87
external_lookup = self._boolean_to_yes_no(
88
repository._format.supports_external_lookups)
89
return '/'.join(segments), rich_root, tree_ref, external_lookup
228
92
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
230
94
def do(self, path):
231
95
"""try to find a repository from path upwards
233
97
This operates precisely like 'bzrdir.find_repository'.
235
99
If a bzrdir is not present, an exception is propogated
236
100
rather than 'no branch' because these are different conditions.
262
126
returns information about the supports_external_lookups format
265
:return: norepository or ok, relpath, rich_root, tree_ref,
129
:return: norepository or ok, relpath.
269
path, rich_root, tree_ref, external_lookup, name = self._find(path)
132
path, rich_root, tree_ref, external_lookup = self._find(path)
270
133
return SuccessfulSmartServerResponse(
271
134
('ok', path, rich_root, tree_ref, external_lookup))
272
135
except errors.NoRepositoryPresent:
273
136
return FailedSmartServerResponse(('norepository', ))
276
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
279
"""try to find a repository from path upwards
281
This operates precisely like 'bzrdir.find_repository'.
283
If a bzrdir is not present, an exception is propogated
284
rather than 'no branch' because these are different conditions.
286
This is the third edition of this method introduced in bzr 1.13, which
287
returns information about the network name of the repository format.
289
:return: norepository or ok, relpath, rich_root, tree_ref,
290
external_lookup, network_name.
293
path, rich_root, tree_ref, external_lookup, name = self._find(path)
294
return SuccessfulSmartServerResponse(
295
('ok', path, rich_root, tree_ref, external_lookup, name))
296
except errors.NoRepositoryPresent:
297
return FailedSmartServerResponse(('norepository', ))
300
139
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
302
141
def do(self, path):
310
149
return SuccessfulSmartServerResponse(('ok', ))
313
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
152
class SmartServerRequestOpenBranch(SmartServerRequest):
315
def do_bzrdir_request(self):
316
"""open a branch at path and return the branch reference or branch."""
155
"""try to open a branch at path and return ok/nobranch.
157
If a bzrdir is not present, an exception is propogated
158
rather than 'no branch' because these are different conditions.
160
bzrdir = BzrDir.open_from_transport(
161
self.transport_from_client_path(path))
318
reference_url = self._bzrdir.get_branch_reference()
163
reference_url = bzrdir.get_branch_reference()
319
164
if reference_url is None:
320
165
return SuccessfulSmartServerResponse(('ok', ''))
322
167
return SuccessfulSmartServerResponse(('ok', reference_url))
323
168
except errors.NotBranchError:
324
169
return FailedSmartServerResponse(('nobranch', ))
327
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
329
def do_bzrdir_request(self):
330
"""open a branch at path and return the reference or format."""
332
reference_url = self._bzrdir.get_branch_reference()
333
if reference_url is None:
334
br = self._bzrdir.open_branch(ignore_fallbacks=True)
335
format = br._format.network_name()
336
return SuccessfulSmartServerResponse(('branch', format))
338
return SuccessfulSmartServerResponse(('ref', reference_url))
339
except errors.NotBranchError:
340
return FailedSmartServerResponse(('nobranch', ))