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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Server-side branch related request implmentations."""
19
from __future__ import absolute_import
20
from bzrlib import errors
21
from bzrlib.bzrdir import BzrDir
24
revision as _mod_revision,
26
from bzrlib.controldir import ControlDir
22
27
from bzrlib.smart.request import (
23
28
FailedSmartServerResponse,
24
29
SmartServerRequest,
73
78
branch.repository.unlock()
81
class SmartServerBranchBreakLock(SmartServerBranchRequest):
83
def do_with_branch(self, branch):
84
"""Break a branch lock.
87
return SuccessfulSmartServerResponse(('ok', ), )
76
90
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
78
92
def do_with_branch(self, branch):
79
93
"""Return the content of branch.conf
81
95
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
89
content = branch._transport.get_bytes('branch.conf')
98
content = branch.control_transport.get_bytes('branch.conf')
90
99
except errors.NoSuchFile:
92
101
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
class SmartServerBranchGetParent(SmartServerBranchRequest):
137
def do_with_branch(self, branch):
138
"""Return the parent of branch."""
139
parent = branch._get_parent_location() or ''
140
return SuccessfulSmartServerResponse((parent,))
143
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
145
def do_with_branch(self, branch):
146
"""Return the _get_tags_bytes for a branch."""
147
bytes = branch._get_tags_bytes()
148
return SuccessfulSmartServerResponse((bytes,))
151
class SmartServerBranchSetTagsBytes(SmartServerLockedBranchRequest):
153
def __init__(self, backing_transport, root_client_path='/', jail_root=None):
154
SmartServerLockedBranchRequest.__init__(
155
self, backing_transport, root_client_path, jail_root)
158
def do_with_locked_branch(self, branch):
159
"""Call _set_tags_bytes for a branch.
163
# We need to keep this branch locked until we get a body with the tags
166
self.branch.lock_write()
169
def do_body(self, bytes):
170
self.branch._set_tags_bytes(bytes)
171
return SuccessfulSmartServerResponse(())
174
# TODO: this request shouldn't have to do this housekeeping manually.
175
# Some of this logic probably belongs in a base class.
177
# We never acquired the branch successfully in the first place, so
178
# there's nothing more to do.
181
return SmartServerLockedBranchRequest.do_end(self)
183
# Only try unlocking if we locked successfully in the first place
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)))
95
201
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
97
203
def do_with_branch(self, branch):
107
213
The revision list is returned as the body content,
108
214
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))
110
224
return SuccessfulSmartServerResponse(
111
('ok', ), ('\x00'.join(branch.revision_history())))
225
('ok', ), ('\x00'.join(reversed(history))))
114
228
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
116
230
def do_with_branch(self, branch):
117
231
"""Return branch.last_revision_info().
119
233
The revno is encoded in decimal, the revision_id is encoded as utf8.
121
235
revno, last_revision = branch.last_revision_info()
122
236
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)))
125
256
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
126
257
"""Base class for handling common branch request logic for requests that
127
258
update the branch tip.
137
268
return FailedSmartServerResponse(('TipChangeRejected', msg))
271
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
272
"""Set an option in the branch configuration."""
274
def do_with_locked_branch(self, branch, value, name, section):
277
branch._get_config().set_option(value.decode('utf8'), name, section)
278
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(())
140
298
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
142
300
def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):
143
301
if new_last_revision_id == 'null:':
144
branch.set_revision_history([])
302
branch.set_last_revision_info(0, new_last_revision_id)
146
304
if not branch.repository.has_revision(new_last_revision_id):
147
305
return FailedSmartServerResponse(
148
306
('NoSuchRevision', new_last_revision_id))
149
branch.generate_revision_history(new_last_revision_id)
307
branch.generate_revision_history(new_last_revision_id, None, None)
150
308
return SuccessfulSmartServerResponse(('ok',))
153
311
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
155
313
def do_tip_change_with_locked_branch(self, branch, new_last_revision_id,
156
314
allow_divergence, allow_overwrite_descendant):
157
315
"""Set the last revision of the branch.
161
319
:param new_last_revision_id: the revision ID to set as the last
162
320
revision of the branch.
163
321
:param allow_divergence: A flag. If non-zero, change the revision ID
215
373
return SuccessfulSmartServerResponse(('ok',))
376
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
377
"""Set the parent location for a branch.
379
Takes a location to set, which must be utf8 encoded.
382
def do_with_locked_branch(self, branch, location):
383
branch._set_parent_location(location)
384
return SuccessfulSmartServerResponse(())
218
387
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
220
389
def do_with_branch(self, branch, branch_token='', repo_token=''):
221
390
if branch_token == '':
222
391
branch_token = None
223
392
if repo_token == '':
224
393
repo_token = None
226
repo_token = branch.repository.lock_write(token=repo_token)
395
repo_token = branch.repository.lock_write(
396
token=repo_token).repository_token
228
branch_token = branch.lock_write(token=branch_token)
398
branch_token = branch.lock_write(
399
token=branch_token).branch_token
230
401
# this leaves the repository with 1 lock
231
402
branch.repository.unlock()