/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-06 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

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
295
            repo_token = branch.repository.lock_write(
391
296
                token=repo_token).repository_token
392
297
            try:
393
298
                branch_token = branch.lock_write(
394
 
                    token=branch_token).token
 
299
                    token=branch_token).branch_token
395
300
            finally:
396
301
                # this leaves the repository with 1 lock
397
302
                branch.repository.unlock()
398
303
        except errors.LockContention:
399
 
            return FailedSmartServerResponse((b'LockContention',))
 
304
            return FailedSmartServerResponse(('LockContention',))
400
305
        except errors.TokenMismatch:
401
 
            return FailedSmartServerResponse((b'TokenMismatch',))
 
306
            return FailedSmartServerResponse(('TokenMismatch',))
402
307
        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')))
 
308
            return FailedSmartServerResponse(('UnlockableTransport',))
 
309
        except errors.LockFailed, e:
 
310
            return FailedSmartServerResponse(('LockFailed', str(e.lock), str(e.why)))
407
311
        if repo_token is None:
408
 
            repo_token = b''
 
312
            repo_token = ''
409
313
        else:
410
314
            branch.repository.leave_lock_in_place()
411
315
        branch.leave_lock_in_place()
412
316
        branch.unlock()
413
 
        return SuccessfulSmartServerResponse((b'ok', branch_token, repo_token))
 
317
        return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
414
318
 
415
319
 
416
320
class SmartServerBranchRequestUnlock(SmartServerBranchRequest):
417
321
 
418
322
    def do_with_branch(self, branch, branch_token, repo_token):
419
323
        try:
420
 
            with branch.repository.lock_write(token=repo_token):
 
324
            branch.repository.lock_write(token=repo_token)
 
325
            try:
421
326
                branch.lock_write(token=branch_token)
 
327
            finally:
 
328
                branch.repository.unlock()
422
329
        except errors.TokenMismatch:
423
 
            return FailedSmartServerResponse((b'TokenMismatch',))
 
330
            return FailedSmartServerResponse(('TokenMismatch',))
424
331
        if repo_token:
425
332
            branch.repository.dont_leave_lock_in_place()
426
333
        branch.dont_leave_lock_in_place()
427
334
        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)
 
335
        return SuccessfulSmartServerResponse(('ok',))
 
336