/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/smart/branch.py

  • Committer: Robert Collins
  • Date: 2010-05-05 00:05:29 UTC
  • mto: This revision was merged to the branch mainline in revision 5206.
  • Revision ID: robertc@robertcollins.net-20100505000529-ltmllyms5watqj5u
Make 'pydoc bzrlib.tests.build_tree_shape' useful.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
#
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
16
16
 
17
17
"""Server-side branch related request implmentations."""
18
18
 
19
 
from __future__ import absolute_import
20
19
 
21
 
from ... import (
22
 
    bencode,
23
 
    errors,
24
 
    revision as _mod_revision,
25
 
    )
26
 
from ...controldir import ControlDir
27
 
from ...sixish import text_type
28
 
from .request import (
 
20
from bzrlib import errors
 
21
from bzrlib.bzrdir import BzrDir
 
22
from bzrlib.smart.request import (
29
23
    FailedSmartServerResponse,
30
24
    SmartServerRequest,
31
25
    SuccessfulSmartServerResponse,
48
42
        :return: A SmartServerResponse from self.do_with_branch().
49
43
        """
50
44
        transport = self.transport_from_client_path(path)
51
 
        controldir = ControlDir.open_from_transport(transport)
52
 
        if controldir.get_branch_reference() is not None:
 
45
        bzrdir = BzrDir.open_from_transport(transport)
 
46
        if bzrdir.get_branch_reference() is not None:
53
47
            raise errors.NotBranchError(transport.base)
54
 
        branch = controldir.open_branch(ignore_fallbacks=True)
 
48
        branch = bzrdir.open_branch(ignore_fallbacks=True)
55
49
        return self.do_with_branch(branch, *args)
56
50
 
57
51
 
68
62
        processed.  The physical lock state won't be changed.
69
63
        """
70
64
        # XXX: write a test for LockContention
71
 
        with branch.repository.lock_write(token=repo_token), \
72
 
                branch.lock_write(token=branch_token):
73
 
            return self.do_with_locked_branch(branch, *args)
74
 
 
75
 
 
76
 
class SmartServerBranchBreakLock(SmartServerBranchRequest):
77
 
 
78
 
    def do_with_branch(self, branch):
79
 
        """Break a branch lock.
80
 
        """
81
 
        branch.break_lock()
82
 
        return SuccessfulSmartServerResponse((b'ok', ), )
 
65
        branch.repository.lock_write(token=repo_token)
 
66
        try:
 
67
            branch.lock_write(token=branch_token)
 
68
            try:
 
69
                return self.do_with_locked_branch(branch, *args)
 
70
            finally:
 
71
                branch.unlock()
 
72
        finally:
 
73
            branch.repository.unlock()
83
74
 
84
75
 
85
76
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
90
81
        The body is not utf8 decoded - its the literal bytestream from disk.
91
82
        """
92
83
        try:
93
 
            content = branch.control_transport.get_bytes('branch.conf')
 
84
            content = branch._transport.get_bytes('branch.conf')
94
85
        except errors.NoSuchFile:
95
 
            content = b''
96
 
        return SuccessfulSmartServerResponse((b'ok', ), content)
97
 
 
98
 
 
99
 
class SmartServerBranchPutConfigFile(SmartServerBranchRequest):
100
 
    """Set the configuration data for a branch.
101
 
 
102
 
    New in 2.5.
103
 
    """
104
 
 
105
 
    def do_with_branch(self, branch, branch_token, repo_token):
106
 
        """Set the content of branch.conf.
107
 
 
108
 
        The body is not utf8 decoded - its the literal bytestream for disk.
109
 
        """
110
 
        self._branch = branch
111
 
        self._branch_token = branch_token
112
 
        self._repo_token = repo_token
113
 
        # Signal we want a body
114
 
        return None
115
 
 
116
 
    def do_body(self, body_bytes):
117
 
        with self._branch.repository.lock_write(token=self._repo_token), \
118
 
                self._branch.lock_write(token=self._branch_token):
119
 
            self._branch.control_transport.put_bytes(
120
 
                'branch.conf', body_bytes)
121
 
        return SuccessfulSmartServerResponse((b'ok', ))
 
86
            content = ''
 
87
        return SuccessfulSmartServerResponse( ('ok', ), content)
122
88
 
123
89
 
124
90
class SmartServerBranchGetParent(SmartServerBranchRequest):
126
92
    def do_with_branch(self, branch):
127
93
        """Return the parent of branch."""
128
94
        parent = branch._get_parent_location() or ''
129
 
        return SuccessfulSmartServerResponse((parent.encode('utf-8'),))
 
95
        return SuccessfulSmartServerResponse((parent,))
130
96
 
131
97
 
132
98
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
143
109
        SmartServerLockedBranchRequest.__init__(
144
110
            self, backing_transport, root_client_path, jail_root)
145
111
        self.locked = False
146
 
 
 
112
        
147
113
    def do_with_locked_branch(self, branch):
148
114
        """Call _set_tags_bytes for a branch.
149
115
 
173
139
            self.branch.unlock()
174
140
 
175
141
 
176
 
class SmartServerBranchHeadsToFetch(SmartServerBranchRequest):
177
 
 
178
 
    def do_with_branch(self, branch):
179
 
        """Return the heads-to-fetch for a Branch as two bencoded lists.
180
 
 
181
 
        See Branch.heads_to_fetch.
182
 
 
183
 
        New in 2.4.
184
 
        """
185
 
        must_fetch, if_present_fetch = branch.heads_to_fetch()
186
 
        return SuccessfulSmartServerResponse(
187
 
            (list(must_fetch), list(if_present_fetch)))
188
 
 
189
 
 
190
142
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
191
143
 
192
144
    def do_with_branch(self, branch):
193
145
        stacked_on_url = branch.get_stacked_on_url()
194
 
        return SuccessfulSmartServerResponse((b'ok', stacked_on_url.encode('ascii')))
 
146
        return SuccessfulSmartServerResponse(('ok', stacked_on_url))
195
147
 
196
148
 
197
149
class SmartServerRequestRevisionHistory(SmartServerBranchRequest):
202
154
        The revision list is returned as the body content,
203
155
        with each revision utf8 encoded and \x00 joined.
204
156
        """
205
 
        with branch.lock_read():
206
 
            graph = branch.repository.get_graph()
207
 
            stop_revisions = (None, _mod_revision.NULL_REVISION)
208
 
            history = list(graph.iter_lefthand_ancestry(
209
 
                branch.last_revision(), stop_revisions))
210
157
        return SuccessfulSmartServerResponse(
211
 
            (b'ok', ), (b'\x00'.join(reversed(history))))
 
158
            ('ok', ), ('\x00'.join(branch.revision_history())))
212
159
 
213
160
 
214
161
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
219
166
        The revno is encoded in decimal, the revision_id is encoded as utf8.
220
167
        """
221
168
        revno, last_revision = branch.last_revision_info()
222
 
        return SuccessfulSmartServerResponse(
223
 
            (b'ok', str(revno).encode('ascii'), last_revision))
224
 
 
225
 
 
226
 
class SmartServerBranchRequestRevisionIdToRevno(SmartServerBranchRequest):
227
 
 
228
 
    def do_with_branch(self, branch, revid):
229
 
        """Return branch.revision_id_to_revno().
230
 
 
231
 
        New in 2.5.
232
 
 
233
 
        The revno is encoded in decimal, the revision_id is encoded as utf8.
234
 
        """
235
 
        try:
236
 
            dotted_revno = branch.revision_id_to_dotted_revno(revid)
237
 
        except errors.NoSuchRevision:
238
 
            return FailedSmartServerResponse((b'NoSuchRevision', revid))
239
 
        except errors.GhostRevisionsHaveNoRevno as e:
240
 
            return FailedSmartServerResponse(
241
 
                (b'GhostRevisionsHaveNoRevno', e.revision_id,
242
 
                    e.ghost_revision_id))
243
 
        return SuccessfulSmartServerResponse(
244
 
            (b'ok', ) + tuple([b'%d' % x for x in dotted_revno]))
 
169
        return SuccessfulSmartServerResponse(('ok', str(revno), last_revision))
245
170
 
246
171
 
247
172
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
252
177
    def do_with_locked_branch(self, branch, *args):
253
178
        try:
254
179
            return self.do_tip_change_with_locked_branch(branch, *args)
255
 
        except errors.TipChangeRejected as e:
 
180
        except errors.TipChangeRejected, e:
256
181
            msg = e.msg
257
 
            if isinstance(msg, text_type):
 
182
            if isinstance(msg, unicode):
258
183
                msg = msg.encode('utf-8')
259
 
            return FailedSmartServerResponse((b'TipChangeRejected', msg))
 
184
            return FailedSmartServerResponse(('TipChangeRejected', msg))
260
185
 
261
186
 
262
187
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
265
190
    def do_with_locked_branch(self, branch, value, name, section):
266
191
        if not section:
267
192
            section = None
268
 
        branch._get_config().set_option(
269
 
            value.decode('utf-8'), name.decode('utf-8'),
270
 
            section.decode('utf-8') if section is not None else None)
271
 
        return SuccessfulSmartServerResponse(())
272
 
 
273
 
 
274
 
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
275
 
    """Set an option in the branch configuration.
276
 
 
277
 
    New in 2.2.
278
 
    """
279
 
 
280
 
    def do_with_locked_branch(self, branch, value_dict, name, section):
281
 
        utf8_dict = bencode.bdecode(value_dict)
282
 
        value_dict = {}
283
 
        for key, value in utf8_dict.items():
284
 
            value_dict[key.decode('utf8')] = value.decode('utf8')
285
 
        if not section:
286
 
            section = None
287
 
        else:
288
 
            section = section.decode('utf-8')
289
 
        branch._get_config().set_option(value_dict, name.decode('utf-8'), section)
 
193
        branch._get_config().set_option(value.decode('utf8'), name, section)
290
194
        return SuccessfulSmartServerResponse(())
291
195
 
292
196
 
293
197
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
294
198
 
295
199
    def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):
296
 
        if new_last_revision_id == b'null:':
297
 
            branch.set_last_revision_info(0, new_last_revision_id)
 
200
        if new_last_revision_id == 'null:':
 
201
            branch.set_revision_history([])
298
202
        else:
299
203
            if not branch.repository.has_revision(new_last_revision_id):
300
204
                return FailedSmartServerResponse(
301
 
                    (b'NoSuchRevision', new_last_revision_id))
302
 
            branch.generate_revision_history(new_last_revision_id, None, None)
303
 
        return SuccessfulSmartServerResponse((b'ok',))
 
205
                    ('NoSuchRevision', new_last_revision_id))
 
206
            branch.set_revision_history(branch._lefthand_history(
 
207
                new_last_revision_id, None, None))
 
208
        return SuccessfulSmartServerResponse(('ok',))
304
209
 
305
210
 
306
211
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
307
212
 
308
213
    def do_tip_change_with_locked_branch(self, branch, new_last_revision_id,
309
 
                                         allow_divergence, allow_overwrite_descendant):
 
214
            allow_divergence, allow_overwrite_descendant):
310
215
        """Set the last revision of the branch.
311
216
 
312
217
        New in 1.6.
337
242
                relation = branch._revision_relations(
338
243
                    last_rev, new_last_revision_id, graph)
339
244
                if relation == 'diverged' and not allow_divergence:
340
 
                    return FailedSmartServerResponse((b'Diverged',))
 
245
                    return FailedSmartServerResponse(('Diverged',))
341
246
                if relation == 'a_descends_from_b' and do_not_overwrite_descendant:
342
247
                    return SuccessfulSmartServerResponse(
343
 
                        (b'ok', last_revno, last_rev))
 
248
                        ('ok', last_revno, last_rev))
344
249
            new_revno = graph.find_distance_to_null(
345
250
                new_last_revision_id, [(last_rev, last_revno)])
346
251
            branch.set_last_revision_info(new_revno, new_last_revision_id)
347
252
        except errors.GhostRevisionsHaveNoRevno:
348
253
            return FailedSmartServerResponse(
349
 
                (b'NoSuchRevision', new_last_revision_id))
 
254
                ('NoSuchRevision', new_last_revision_id))
350
255
        return SuccessfulSmartServerResponse(
351
 
            (b'ok', new_revno, new_last_revision_id))
 
256
            ('ok', new_revno, new_last_revision_id))
352
257
 
353
258
 
354
259
class SmartServerBranchRequestSetLastRevisionInfo(SmartServerSetTipRequest):
355
260
    """Branch.set_last_revision_info.  Sets the revno and the revision ID of
356
261
    the specified branch.
357
262
 
358
 
    New in breezy 1.4.
 
263
    New in bzrlib 1.4.
359
264
    """
360
265
 
361
266
    def do_tip_change_with_locked_branch(self, branch, new_revno,
362
 
                                         new_last_revision_id):
 
267
            new_last_revision_id):
363
268
        try:
364
269
            branch.set_last_revision_info(int(new_revno), new_last_revision_id)
365
270
        except errors.NoSuchRevision:
366
271
            return FailedSmartServerResponse(
367
 
                (b'NoSuchRevision', new_last_revision_id))
368
 
        return SuccessfulSmartServerResponse((b'ok',))
 
272
                ('NoSuchRevision', new_last_revision_id))
 
273
        return SuccessfulSmartServerResponse(('ok',))
369
274
 
370
275
 
371
276
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
372
277
    """Set the parent location for a branch.
373
 
 
 
278
    
374
279
    Takes a location to set, which must be utf8 encoded.
375
280
    """
376
281
 
377
282
    def do_with_locked_branch(self, branch, location):
378
 
        branch._set_parent_location(location.decode('utf-8'))
 
283
        branch._set_parent_location(location)
379
284
        return SuccessfulSmartServerResponse(())
380
285
 
381
286
 
382
287
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
383
288
 
384
 
    def do_with_branch(self, branch, branch_token=b'', repo_token=b''):
385
 
        if branch_token == b'':
 
289
    def do_with_branch(self, branch, branch_token='', repo_token=''):
 
290
        if branch_token == '':
386
291
            branch_token = None
387
 
        if repo_token == b'':
 
292
        if repo_token == '':
388
293
            repo_token = None
389
294
        try:
390
 
            repo_token = branch.repository.lock_write(
391
 
                token=repo_token).repository_token
 
295
            repo_token = branch.repository.lock_write(token=repo_token)
392
296
            try:
393
 
                branch_token = branch.lock_write(
394
 
                    token=branch_token).token
 
297
                branch_token = branch.lock_write(token=branch_token)
395
298
            finally:
396
299
                # this leaves the repository with 1 lock
397
300
                branch.repository.unlock()
398
301
        except errors.LockContention:
399
 
            return FailedSmartServerResponse((b'LockContention',))
 
302
            return FailedSmartServerResponse(('LockContention',))
400
303
        except errors.TokenMismatch:
401
 
            return FailedSmartServerResponse((b'TokenMismatch',))
 
304
            return FailedSmartServerResponse(('TokenMismatch',))
402
305
        except errors.UnlockableTransport:
403
 
            return FailedSmartServerResponse((b'UnlockableTransport',))
404
 
        except errors.LockFailed as e:
405
 
            return FailedSmartServerResponse((b'LockFailed',
406
 
                                              str(e.lock).encode('utf-8'), str(e.why).encode('utf-8')))
 
306
            return FailedSmartServerResponse(('UnlockableTransport',))
 
307
        except errors.LockFailed, e:
 
308
            return FailedSmartServerResponse(('LockFailed', str(e.lock), str(e.why)))
407
309
        if repo_token is None:
408
 
            repo_token = b''
 
310
            repo_token = ''
409
311
        else:
410
312
            branch.repository.leave_lock_in_place()
411
313
        branch.leave_lock_in_place()
412
314
        branch.unlock()
413
 
        return SuccessfulSmartServerResponse((b'ok', branch_token, repo_token))
 
315
        return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
414
316
 
415
317
 
416
318
class SmartServerBranchRequestUnlock(SmartServerBranchRequest):
417
319
 
418
320
    def do_with_branch(self, branch, branch_token, repo_token):
419
321
        try:
420
 
            with branch.repository.lock_write(token=repo_token):
 
322
            branch.repository.lock_write(token=repo_token)
 
323
            try:
421
324
                branch.lock_write(token=branch_token)
 
325
            finally:
 
326
                branch.repository.unlock()
422
327
        except errors.TokenMismatch:
423
 
            return FailedSmartServerResponse((b'TokenMismatch',))
 
328
            return FailedSmartServerResponse(('TokenMismatch',))
424
329
        if repo_token:
425
330
            branch.repository.dont_leave_lock_in_place()
426
331
        branch.dont_leave_lock_in_place()
427
332
        branch.unlock()
428
 
        return SuccessfulSmartServerResponse((b'ok',))
429
 
 
430
 
 
431
 
class SmartServerBranchRequestGetPhysicalLockStatus(SmartServerBranchRequest):
432
 
    """Get the physical lock status for a branch.
433
 
 
434
 
    New in 2.5.
435
 
    """
436
 
 
437
 
    def do_with_branch(self, branch):
438
 
        if branch.get_physical_lock_status():
439
 
            return SuccessfulSmartServerResponse((b'yes',))
440
 
        else:
441
 
            return SuccessfulSmartServerResponse((b'no',))
442
 
 
443
 
 
444
 
class SmartServerBranchRequestGetAllReferenceInfo(SmartServerBranchRequest):
445
 
    """Get the reference information.
446
 
 
447
 
    New in 3.1.
448
 
    """
449
 
 
450
 
    def do_with_branch(self, branch):
451
 
        all_reference_info = branch._get_all_reference_info()
452
 
        content = bencode.bencode([
453
 
            (key, value[0].encode('utf-8'), value[1].encode('utf-8') if value[1] else b'')
454
 
            for (key, value) in all_reference_info.items()])
455
 
        return SuccessfulSmartServerResponse((b'ok', ), content)
 
333
        return SuccessfulSmartServerResponse(('ok',))
 
334