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
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Server-side branch related request implmentations."""
20
from bzrlib import errors
24
21
from bzrlib.bzrdir import BzrDir
25
22
from bzrlib.smart.request import (
26
23
FailedSmartServerResponse,
36
33
def do(self, path, *args):
37
34
"""Execute a request for a branch at path.
39
36
All Branch requests take a path to the branch as their first argument.
41
38
If the branch is a branch reference, NotBranchError is raised.
48
45
bzrdir = BzrDir.open_from_transport(transport)
49
46
if bzrdir.get_branch_reference() is not None:
50
47
raise errors.NotBranchError(transport.base)
51
branch = bzrdir.open_branch(ignore_fallbacks=True)
48
branch = bzrdir.open_branch()
52
49
return self.do_with_branch(branch, *args)
79
76
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
81
78
def do_with_branch(self, branch):
82
79
"""Return the content of branch.conf
84
81
The body is not utf8 decoded - its the literal bytestream from disk.
83
# This was at one time called by RemoteBranchLockableFiles
84
# intercepting access to this file; as of 1.5 it is not called by the
85
# client but retained for compatibility. It may be called again to
86
# allow the client to get the configuration without needing vfs
87
89
content = branch._transport.get_bytes('branch.conf')
88
90
except errors.NoSuchFile:
90
92
return SuccessfulSmartServerResponse( ('ok', ), content)
93
class SmartServerBranchGetParent(SmartServerBranchRequest):
95
def do_with_branch(self, branch):
96
"""Return the parent of branch."""
97
parent = branch._get_parent_location() or ''
98
return SuccessfulSmartServerResponse((parent,))
101
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
103
def do_with_branch(self, branch):
104
"""Return the _get_tags_bytes for a branch."""
105
bytes = branch._get_tags_bytes()
106
return SuccessfulSmartServerResponse((bytes,))
109
class SmartServerBranchSetTagsBytes(SmartServerLockedBranchRequest):
111
def __init__(self, backing_transport, root_client_path='/', jail_root=None):
112
SmartServerLockedBranchRequest.__init__(
113
self, backing_transport, root_client_path, jail_root)
116
def do_with_locked_branch(self, branch):
117
"""Call _set_tags_bytes for a branch.
121
# We need to keep this branch locked until we get a body with the tags
124
self.branch.lock_write()
127
def do_body(self, bytes):
128
self.branch._set_tags_bytes(bytes)
129
return SuccessfulSmartServerResponse(())
132
# TODO: this request shouldn't have to do this housekeeping manually.
133
# Some of this logic probably belongs in a base class.
135
# We never acquired the branch successfully in the first place, so
136
# there's nothing more to do.
139
return SmartServerLockedBranchRequest.do_end(self)
141
# Only try unlocking if we locked successfully in the first place
145
95
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
147
97
def do_with_branch(self, branch):
164
114
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
166
116
def do_with_branch(self, branch):
167
117
"""Return branch.last_revision_info().
169
119
The revno is encoded in decimal, the revision_id is encoded as utf8.
171
121
revno, last_revision = branch.last_revision_info()
187
137
return FailedSmartServerResponse(('TipChangeRejected', msg))
190
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
191
"""Set an option in the branch configuration."""
193
def do_with_locked_branch(self, branch, value, name, section):
196
branch._get_config().set_option(value.decode('utf8'), name, section)
197
return SuccessfulSmartServerResponse(())
200
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
201
"""Set an option in the branch configuration.
206
def do_with_locked_branch(self, branch, value_dict, name, section):
207
utf8_dict = bencode.bdecode(value_dict)
209
for key, value in utf8_dict.items():
210
value_dict[key.decode('utf8')] = value.decode('utf8')
213
branch._get_config().set_option(value_dict, name, section)
214
return SuccessfulSmartServerResponse(())
217
140
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
219
142
def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):
220
143
if new_last_revision_id == 'null:':
221
144
branch.set_revision_history([])
223
146
if not branch.repository.has_revision(new_last_revision_id):
224
147
return FailedSmartServerResponse(
225
148
('NoSuchRevision', new_last_revision_id))
226
branch.set_revision_history(branch._lefthand_history(
227
new_last_revision_id, None, None))
149
branch.generate_revision_history(new_last_revision_id)
228
150
return SuccessfulSmartServerResponse(('ok',))
231
153
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
233
155
def do_tip_change_with_locked_branch(self, branch, new_last_revision_id,
234
156
allow_divergence, allow_overwrite_descendant):
235
157
"""Set the last revision of the branch.
239
161
:param new_last_revision_id: the revision ID to set as the last
240
162
revision of the branch.
241
163
:param allow_divergence: A flag. If non-zero, change the revision ID
293
215
return SuccessfulSmartServerResponse(('ok',))
296
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
297
"""Set the parent location for a branch.
299
Takes a location to set, which must be utf8 encoded.
302
def do_with_locked_branch(self, branch, location):
303
branch._set_parent_location(location)
304
return SuccessfulSmartServerResponse(())
307
218
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
309
220
def do_with_branch(self, branch, branch_token='', repo_token=''):
310
221
if branch_token == '':
311
222
branch_token = None
312
223
if repo_token == '':
313
224
repo_token = None
315
repo_token = branch.repository.lock_write(
316
token=repo_token).repository_token
226
repo_token = branch.repository.lock_write(token=repo_token)
318
branch_token = branch.lock_write(
319
token=branch_token).branch_token
228
branch_token = branch.lock_write(token=branch_token)
321
230
# this leaves the repository with 1 lock
322
231
branch.repository.unlock()