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
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
77
82
# path segments to pop-out.
78
83
relpath = repository.bzrdir.root_transport.relpath(
79
bzrdir.root_transport.base)
84
current_transport.base)
81
86
segments = ['..'] * len(relpath.split('/'))
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
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."""
97
branch_ref = self._bzrdir.get_branch_reference()
98
except errors.NotBranchError:
100
if require_stacking == "True":
101
require_stacking = True
103
require_stacking = False
104
control_format = self._bzrdir.cloning_metadir(
105
require_stacking=require_stacking)
106
control_name = control_format.network_name()
107
# XXX: There should be a method that tells us that the format does/does not
109
if isinstance(control_format, BzrDirMetaFormat1):
110
if branch_ref is not None:
111
# If there's a branch reference, the client will have to resolve
112
# the branch reference to figure out the cloning metadir
113
branch_name = ('ref', branch_ref)
115
branch_name = ('branch',
116
control_format.get_branch_format().network_name())
117
repository_name = control_format.repository_format.network_name()
119
# Only MetaDir has delegated formats today.
120
branch_name = ('branch', '')
122
return SuccessfulSmartServerResponse((control_name, repository_name,
126
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
128
def do(self, path, network_name):
129
"""Create a branch in the bzr dir at path.
131
This operates precisely like 'bzrdir.create_branch'.
133
If a bzrdir is not present, an exception is propogated
134
rather than 'no branch' because these are different conditions (and
135
this method should only be called after establishing that a bzr dir
138
This is the initial version of this method introduced to the smart
141
:param path: The path to the bzrdir.
142
:param network_name: The network name of the branch type to create.
143
:return: (ok, network_name)
145
bzrdir = BzrDir.open_from_transport(
146
self.transport_from_client_path(path))
147
format = branch.network_format_registry.get(network_name)
148
bzrdir.branch_format = format
149
result = format.initialize(bzrdir)
150
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
151
result.repository._format)
152
branch_format = result._format.network_name()
153
repo_format = result.repository._format.network_name()
154
repo_path = self._repo_relpath(bzrdir.root_transport,
156
# branch format, repo relpath, rich_root, tree_ref, external_lookup,
158
return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
159
rich_root, tree_ref, external_lookup, repo_format))
162
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
164
def do(self, path, network_name, shared):
165
"""Create a repository in the bzr dir at path.
167
This operates precisely like 'bzrdir.create_repository'.
169
If a bzrdir is not present, an exception is propogated
170
rather than 'no branch' because these are different conditions (and
171
this method should only be called after establishing that a bzr dir
174
This is the initial version of this method introduced to the smart
177
:param path: The path to the bzrdir.
178
:param network_name: The network name of the repository type to create.
179
:param shared: The value to pass create_repository for the shared
181
:return: (ok, rich_root, tree_ref, external_lookup, network_name)
183
bzrdir = BzrDir.open_from_transport(
184
self.transport_from_client_path(path))
185
shared = shared == 'True'
186
format = repository.network_format_registry.get(network_name)
187
bzrdir.repository_format = format
188
result = format.initialize(bzrdir, shared=shared)
189
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
191
return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
192
external_lookup, result._format.network_name()))
195
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
197
def _find(self, path):
198
"""try to find a repository from path upwards
200
This operates precisely like 'bzrdir.find_repository'.
202
:return: (relpath, rich_root, tree_ref, external_lookup, network_name).
203
All are strings, relpath is a / prefixed path, the next three are
204
either 'yes' or 'no', and the last is a repository format network
206
:raises errors.NoRepositoryPresent: When there is no repository
209
bzrdir = BzrDir.open_from_transport(
210
self.transport_from_client_path(path))
211
repository = bzrdir.find_repository()
212
path = self._repo_relpath(bzrdir.root_transport, repository)
213
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
215
network_name = repository._format.network_name()
216
return path, rich_root, tree_ref, external_lookup, network_name
92
219
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
94
221
def do(self, path):
95
222
"""try to find a repository from path upwards
97
224
This operates precisely like 'bzrdir.find_repository'.
99
226
If a bzrdir is not present, an exception is propogated
100
227
rather than 'no branch' because these are different conditions.
126
253
returns information about the supports_external_lookups format
129
:return: norepository or ok, relpath.
256
:return: norepository or ok, relpath, rich_root, tree_ref,
132
path, rich_root, tree_ref, external_lookup = self._find(path)
260
path, rich_root, tree_ref, external_lookup, name = self._find(path)
133
261
return SuccessfulSmartServerResponse(
134
262
('ok', path, rich_root, tree_ref, external_lookup))
135
263
except errors.NoRepositoryPresent:
136
264
return FailedSmartServerResponse(('norepository', ))
267
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
270
"""try to find a repository from path upwards
272
This operates precisely like 'bzrdir.find_repository'.
274
If a bzrdir is not present, an exception is propogated
275
rather than 'no branch' because these are different conditions.
277
This is the third edition of this method introduced in bzr 1.13, which
278
returns information about the network name of the repository format.
280
:return: norepository or ok, relpath, rich_root, tree_ref,
281
external_lookup, network_name.
284
path, rich_root, tree_ref, external_lookup, name = self._find(path)
285
return SuccessfulSmartServerResponse(
286
('ok', path, rich_root, tree_ref, external_lookup, name))
287
except errors.NoRepositoryPresent:
288
return FailedSmartServerResponse(('norepository', ))
139
291
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
141
293
def do(self, path):
149
301
return SuccessfulSmartServerResponse(('ok', ))
152
class SmartServerRequestOpenBranch(SmartServerRequest):
304
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
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))
306
def do_bzrdir_request(self):
307
"""open a branch at path and return the branch reference or branch."""
163
reference_url = bzrdir.get_branch_reference()
309
reference_url = self._bzrdir.get_branch_reference()
164
310
if reference_url is None:
165
311
return SuccessfulSmartServerResponse(('ok', ''))
167
313
return SuccessfulSmartServerResponse(('ok', reference_url))
168
314
except errors.NotBranchError:
169
315
return FailedSmartServerResponse(('nobranch', ))
318
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
320
def do_bzrdir_request(self):
321
"""open a branch at path and return the reference or format."""
323
reference_url = self._bzrdir.get_branch_reference()
324
if reference_url is None:
325
format = self._bzrdir.open_branch()._format.network_name()
326
return SuccessfulSmartServerResponse(('branch', format))
328
return SuccessfulSmartServerResponse(('ref', reference_url))
329
except errors.NotBranchError:
330
return FailedSmartServerResponse(('nobranch', ))