1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Server-side branch related request implmentations."""
19
from __future__ import absolute_import
24
revision as _mod_revision,
26
from bzrlib.controldir import ControlDir
20
from bzrlib import errors
21
from bzrlib.bzrdir import BzrDir
27
22
from bzrlib.smart.request import (
28
23
FailedSmartServerResponse,
29
24
SmartServerRequest,
47
42
:return: A SmartServerResponse from self.do_with_branch().
49
44
transport = self.transport_from_client_path(path)
50
controldir = ControlDir.open_from_transport(transport)
51
if controldir.get_branch_reference() is not None:
45
bzrdir = BzrDir.open_from_transport(transport)
46
if bzrdir.get_branch_reference() is not None:
52
47
raise errors.NotBranchError(transport.base)
53
branch = controldir.open_branch(ignore_fallbacks=True)
48
branch = bzrdir.open_branch(ignore_fallbacks=True)
54
49
return self.do_with_branch(branch, *args)
78
73
branch.repository.unlock()
81
class SmartServerBranchBreakLock(SmartServerBranchRequest):
83
def do_with_branch(self, branch):
84
"""Break a branch lock.
87
return SuccessfulSmartServerResponse(('ok', ), )
90
76
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
92
78
def do_with_branch(self, branch):
95
81
The body is not utf8 decoded - its the literal bytestream from disk.
98
content = branch.control_transport.get_bytes('branch.conf')
84
content = branch._transport.get_bytes('branch.conf')
99
85
except errors.NoSuchFile:
101
87
return SuccessfulSmartServerResponse( ('ok', ), content)
104
class SmartServerBranchPutConfigFile(SmartServerBranchRequest):
105
"""Set the configuration data for a branch.
110
def do_with_branch(self, branch, branch_token, repo_token):
111
"""Set the content of branch.conf.
113
The body is not utf8 decoded - its the literal bytestream for disk.
115
self._branch = branch
116
self._branch_token = branch_token
117
self._repo_token = repo_token
118
# Signal we want a body
121
def do_body(self, body_bytes):
122
self._branch.repository.lock_write(token=self._repo_token)
124
self._branch.lock_write(token=self._branch_token)
126
self._branch.control_transport.put_bytes(
127
'branch.conf', body_bytes)
129
self._branch.unlock()
131
self._branch.repository.unlock()
132
return SuccessfulSmartServerResponse(('ok', ))
135
90
class SmartServerBranchGetParent(SmartServerBranchRequest):
137
92
def do_with_branch(self, branch):
184
139
self.branch.unlock()
187
class SmartServerBranchHeadsToFetch(SmartServerBranchRequest):
189
def do_with_branch(self, branch):
190
"""Return the heads-to-fetch for a Branch as two bencoded lists.
192
See Branch.heads_to_fetch.
196
must_fetch, if_present_fetch = branch.heads_to_fetch()
197
return SuccessfulSmartServerResponse(
198
(list(must_fetch), list(if_present_fetch)))
201
142
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
203
144
def do_with_branch(self, branch):
213
154
The revision list is returned as the body content,
214
155
with each revision utf8 encoded and \x00 joined.
218
graph = branch.repository.get_graph()
219
stop_revisions = (None, _mod_revision.NULL_REVISION)
220
history = list(graph.iter_lefthand_ancestry(
221
branch.last_revision(), stop_revisions))
224
157
return SuccessfulSmartServerResponse(
225
('ok', ), ('\x00'.join(reversed(history))))
158
('ok', ), ('\x00'.join(branch.revision_history())))
228
161
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
236
169
return SuccessfulSmartServerResponse(('ok', str(revno), last_revision))
239
class SmartServerBranchRequestRevisionIdToRevno(SmartServerBranchRequest):
241
def do_with_branch(self, branch, revid):
242
"""Return branch.revision_id_to_revno().
246
The revno is encoded in decimal, the revision_id is encoded as utf8.
249
dotted_revno = branch.revision_id_to_dotted_revno(revid)
250
except errors.NoSuchRevision:
251
return FailedSmartServerResponse(('NoSuchRevision', revid))
252
return SuccessfulSmartServerResponse(
253
('ok', ) + tuple(map(str, dotted_revno)))
256
172
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
257
173
"""Base class for handling common branch request logic for requests that
258
174
update the branch tip.
278
194
return SuccessfulSmartServerResponse(())
281
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
282
"""Set an option in the branch configuration.
287
def do_with_locked_branch(self, branch, value_dict, name, section):
288
utf8_dict = bencode.bdecode(value_dict)
290
for key, value in utf8_dict.items():
291
value_dict[key.decode('utf8')] = value.decode('utf8')
294
branch._get_config().set_option(value_dict, name, section)
295
return SuccessfulSmartServerResponse(())
298
197
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
300
199
def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):
301
200
if new_last_revision_id == 'null:':
302
branch._set_revision_history([])
201
branch.set_revision_history([])
304
203
if not branch.repository.has_revision(new_last_revision_id):
305
204
return FailedSmartServerResponse(
306
205
('NoSuchRevision', new_last_revision_id))
307
branch._set_revision_history(branch._lefthand_history(
206
branch.set_revision_history(branch._lefthand_history(
308
207
new_last_revision_id, None, None))
309
208
return SuccessfulSmartServerResponse(('ok',))
393
292
if repo_token == '':
394
293
repo_token = None
396
repo_token = branch.repository.lock_write(
397
token=repo_token).repository_token
295
repo_token = branch.repository.lock_write(token=repo_token)
399
branch_token = branch.lock_write(
400
token=branch_token).branch_token
297
branch_token = branch.lock_write(token=branch_token)
402
299
# this leaves the repository with 1 lock
403
300
branch.repository.unlock()
436
333
return SuccessfulSmartServerResponse(('ok',))
439
class SmartServerBranchRequestGetPhysicalLockStatus(SmartServerBranchRequest):
440
"""Get the physical lock status for a branch.
445
def do_with_branch(self, branch):
446
if branch.get_physical_lock_status():
447
return SuccessfulSmartServerResponse(('yes',))
449
return SuccessfulSmartServerResponse(('no',))