~bzr-pqm/bzr/bzr.dev

5218.2.2 by John Arbash Meinel
Bring in the global chk change, which includes some more bzr.dev code.
1
# Copyright (C) 2006-2010 Canonical Ltd
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
16
17
"""Server-side branch related request implmentations."""
18
19
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
20
from bzrlib import (
21
    bencode,
22
    errors,
6165.4.16 by Jelmer Vernooij
Don't provide Branch.iter_reverse_revision_history.
23
    revision as _mod_revision,
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
24
    )
6207.3.3 by jelmer at samba
Fix tests and the like.
25
from bzrlib.controldir import ControlDir
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
26
from bzrlib.smart.request import (
27
    FailedSmartServerResponse,
28
    SmartServerRequest,
29
    SuccessfulSmartServerResponse,
30
    )
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
31
32
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
33
class SmartServerBranchRequest(SmartServerRequest):
2692.1.10 by Andrew Bennetts
More docstring polish
34
    """Base class for handling common branch request logic.
35
    """
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
36
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
37
    def do(self, path, *args):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
38
        """Execute a request for a branch at path.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
39
2692.1.10 by Andrew Bennetts
More docstring polish
40
        All Branch requests take a path to the branch as their first argument.
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
41
42
        If the branch is a branch reference, NotBranchError is raised.
2692.1.10 by Andrew Bennetts
More docstring polish
43
44
        :param path: The path for the repository as received from the
45
            client.
46
        :return: A SmartServerResponse from self.do_with_branch().
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
47
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
48
        transport = self.transport_from_client_path(path)
6207.3.3 by jelmer at samba
Fix tests and the like.
49
        controldir = ControlDir.open_from_transport(transport)
50
        if controldir.get_branch_reference() is not None:
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
51
            raise errors.NotBranchError(transport.base)
6207.3.3 by jelmer at samba
Fix tests and the like.
52
        branch = controldir.open_branch(ignore_fallbacks=True)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
53
        return self.do_with_branch(branch, *args)
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
54
55
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
56
class SmartServerLockedBranchRequest(SmartServerBranchRequest):
57
    """Base class for handling common branch request logic for requests that
58
    need a write lock.
59
    """
60
61
    def do_with_branch(self, branch, branch_token, repo_token, *args):
62
        """Execute a request for a branch.
63
64
        A write lock will be acquired with the given tokens for the branch and
65
        repository locks.  The lock will be released once the request is
66
        processed.  The physical lock state won't be changed.
67
        """
68
        # XXX: write a test for LockContention
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
69
        branch.repository.lock_write(token=repo_token)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
70
        try:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
71
            branch.lock_write(token=branch_token)
72
            try:
73
                return self.do_with_locked_branch(branch, *args)
74
            finally:
75
                branch.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
76
        finally:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
77
            branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
78
79
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
80
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
81
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
82
    def do_with_branch(self, branch):
3407.2.1 by Martin Pool
Deprecate LockableFiles.get
83
        """Return the content of branch.conf
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
84
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
85
        The body is not utf8 decoded - its the literal bytestream from disk.
86
        """
87
        try:
3407.2.14 by Martin Pool
Remove more cases of getting transport via control_files
88
            content = branch._transport.get_bytes('branch.conf')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
89
        except errors.NoSuchFile:
90
            content = ''
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
91
        return SuccessfulSmartServerResponse( ('ok', ), content)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
92
93
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
94
class SmartServerBranchGetParent(SmartServerBranchRequest):
95
96
    def do_with_branch(self, branch):
97
        """Return the parent of branch."""
98
        parent = branch._get_parent_location() or ''
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
99
        return SuccessfulSmartServerResponse((parent,))
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
100
101
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
102
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
103
104
    def do_with_branch(self, branch):
105
        """Return the _get_tags_bytes for a branch."""
106
        bytes = branch._get_tags_bytes()
107
        return SuccessfulSmartServerResponse((bytes,))
108
109
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
110
class SmartServerBranchSetTagsBytes(SmartServerLockedBranchRequest):
111
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
112
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
113
        SmartServerLockedBranchRequest.__init__(
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
114
            self, backing_transport, root_client_path, jail_root)
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
115
        self.locked = False
116
        
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
117
    def do_with_locked_branch(self, branch):
4556.2.4 by Andrew Bennetts
Add NEWS entry, docstring.
118
        """Call _set_tags_bytes for a branch.
119
120
        New in 1.18.
121
        """
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
122
        # We need to keep this branch locked until we get a body with the tags
123
        # bytes.
124
        self.branch = branch
125
        self.branch.lock_write()
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
126
        self.locked = True
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
127
128
    def do_body(self, bytes):
129
        self.branch._set_tags_bytes(bytes)
130
        return SuccessfulSmartServerResponse(())
131
132
    def do_end(self):
4556.2.8 by Andrew Bennetts
Add TODO comment.
133
        # TODO: this request shouldn't have to do this housekeeping manually.
134
        # Some of this logic probably belongs in a base class.
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
135
        if not self.locked:
136
            # We never acquired the branch successfully in the first place, so
137
            # there's nothing more to do.
138
            return
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
139
        try:
140
            return SmartServerLockedBranchRequest.do_end(self)
141
        finally:
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
142
            # Only try unlocking if we locked successfully in the first place
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
143
            self.branch.unlock()
144
145
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
146
class SmartServerBranchHeadsToFetch(SmartServerBranchRequest):
147
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
148
    def do_with_branch(self, branch):
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
149
        """Return the heads-to-fetch for a Branch as two bencoded lists.
150
        
151
        See Branch.heads_to_fetch.
152
153
        New in 2.4.
154
        """
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
155
        must_fetch, if_present_fetch = branch.heads_to_fetch()
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
156
        return SuccessfulSmartServerResponse(
157
            (list(must_fetch), list(if_present_fetch)))
158
159
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
160
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
161
162
    def do_with_branch(self, branch):
163
        stacked_on_url = branch.get_stacked_on_url()
164
        return SuccessfulSmartServerResponse(('ok', stacked_on_url))
165
166
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
167
class SmartServerRequestRevisionHistory(SmartServerBranchRequest):
168
169
    def do_with_branch(self, branch):
170
        """Get the revision history for the branch.
171
172
        The revision list is returned as the body content,
173
        with each revision utf8 encoded and \x00 joined.
174
        """
6165.4.23 by Jelmer Vernooij
Fix tests.
175
        branch.lock_read()
176
        try:
177
            graph = branch.repository.get_graph()
178
            stop_revisions = (None, _mod_revision.NULL_REVISION)
179
            history = list(graph.iter_lefthand_ancestry(
180
                branch.last_revision(), stop_revisions))
181
        finally:
182
            branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
183
        return SuccessfulSmartServerResponse(
6165.4.11 by Jelmer Vernooij
More test fixes.
184
            ('ok', ), ('\x00'.join(reversed(history))))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
185
186
187
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
188
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
189
    def do_with_branch(self, branch):
190
        """Return branch.last_revision_info().
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
191
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
192
        The revno is encoded in decimal, the revision_id is encoded as utf8.
193
        """
194
        revno, last_revision = branch.last_revision_info()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
195
        return SuccessfulSmartServerResponse(('ok', str(revno), last_revision))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
196
197
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
198
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
199
    """Base class for handling common branch request logic for requests that
200
    update the branch tip.
201
    """
202
203
    def do_with_locked_branch(self, branch, *args):
204
        try:
205
            return self.do_tip_change_with_locked_branch(branch, *args)
206
        except errors.TipChangeRejected, e:
207
            msg = e.msg
208
            if isinstance(msg, unicode):
209
                msg = msg.encode('utf-8')
210
            return FailedSmartServerResponse(('TipChangeRejected', msg))
211
212
4226.2.1 by Robert Collins
Set branch config options via a smart method.
213
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
214
    """Set an option in the branch configuration."""
215
216
    def do_with_locked_branch(self, branch, value, name, section):
217
        if not section:
218
            section = None
4226.2.2 by Robert Collins
Fix setting config options to support unicode values and don't attempt to reset repositories _fallback_repositories as the simple approach fails to work.
219
        branch._get_config().set_option(value.decode('utf8'), name, section)
4226.2.1 by Robert Collins
Set branch config options via a smart method.
220
        return SuccessfulSmartServerResponse(())
221
222
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
223
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
224
    """Set an option in the branch configuration.
225
    
226
    New in 2.2.
227
    """
228
229
    def do_with_locked_branch(self, branch, value_dict, name, section):
230
        utf8_dict = bencode.bdecode(value_dict)
231
        value_dict = {}
232
        for key, value in utf8_dict.items():
233
            value_dict[key.decode('utf8')] = value.decode('utf8')
234
        if not section:
235
            section = None
236
        branch._get_config().set_option(value_dict, name, section)
237
        return SuccessfulSmartServerResponse(())
238
239
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
240
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
241
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
242
    def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
243
        if new_last_revision_id == 'null:':
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
244
            branch._set_revision_history([])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
245
        else:
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
246
            if not branch.repository.has_revision(new_last_revision_id):
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
247
                return FailedSmartServerResponse(
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
248
                    ('NoSuchRevision', new_last_revision_id))
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
249
            branch._set_revision_history(branch._lefthand_history(
250
                new_last_revision_id, None, None))
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
251
        return SuccessfulSmartServerResponse(('ok',))
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
252
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
253
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
254
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
255
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
256
    def do_tip_change_with_locked_branch(self, branch, new_last_revision_id,
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
257
            allow_divergence, allow_overwrite_descendant):
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
258
        """Set the last revision of the branch.
259
260
        New in 1.6.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
261
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
262
        :param new_last_revision_id: the revision ID to set as the last
263
            revision of the branch.
264
        :param allow_divergence: A flag.  If non-zero, change the revision ID
265
            even if the new_last_revision_id's ancestry has diverged from the
266
            current last revision.  If zero, a 'Diverged' error will be
267
            returned if new_last_revision_id is not a descendant of the current
268
            last revision.
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
269
        :param allow_overwrite_descendant:  A flag.  If zero and
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
270
            new_last_revision_id is not a descendant of the current last
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
271
            revision, then the last revision will not be changed.  If non-zero
272
            and there is no divergence, then the last revision is always
273
            changed.
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
274
275
        :returns: on success, a tuple of ('ok', revno, revision_id), where
276
            revno and revision_id are the new values of the current last
277
            revision info.  The revision_id might be different to the
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
278
            new_last_revision_id if allow_overwrite_descendant was not set.
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
279
        """
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
280
        do_not_overwrite_descendant = not allow_overwrite_descendant
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
281
        try:
3441.5.18 by Andrew Bennetts
Fix some test failures.
282
            last_revno, last_rev = branch.last_revision_info()
283
            graph = branch.repository.get_graph()
284
            if not allow_divergence or do_not_overwrite_descendant:
285
                relation = branch._revision_relations(
286
                    last_rev, new_last_revision_id, graph)
287
                if relation == 'diverged' and not allow_divergence:
288
                    return FailedSmartServerResponse(('Diverged',))
289
                if relation == 'a_descends_from_b' and do_not_overwrite_descendant:
290
                    return SuccessfulSmartServerResponse(
291
                        ('ok', last_revno, last_rev))
292
            new_revno = graph.find_distance_to_null(
293
                new_last_revision_id, [(last_rev, last_revno)])
294
            branch.set_last_revision_info(new_revno, new_last_revision_id)
3441.5.23 by Andrew Bennetts
Fix test failures.
295
        except errors.GhostRevisionsHaveNoRevno:
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
296
            return FailedSmartServerResponse(
297
                ('NoSuchRevision', new_last_revision_id))
3441.5.18 by Andrew Bennetts
Fix some test failures.
298
        return SuccessfulSmartServerResponse(
299
            ('ok', new_revno, new_last_revision_id))
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
300
301
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
302
class SmartServerBranchRequestSetLastRevisionInfo(SmartServerSetTipRequest):
3297.4.2 by Andrew Bennetts
Add backwards compatibility for servers older than 1.4.
303
    """Branch.set_last_revision_info.  Sets the revno and the revision ID of
304
    the specified branch.
305
306
    New in bzrlib 1.4.
307
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
308
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
309
    def do_tip_change_with_locked_branch(self, branch, new_revno,
310
            new_last_revision_id):
3297.4.3 by Andrew Bennetts
Add more tests, handle NoSuchRevision in case the remote branch's format can raise it.
311
        try:
312
            branch.set_last_revision_info(int(new_revno), new_last_revision_id)
313
        except errors.NoSuchRevision:
314
            return FailedSmartServerResponse(
315
                ('NoSuchRevision', new_last_revision_id))
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
316
        return SuccessfulSmartServerResponse(('ok',))
317
318
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
319
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
320
    """Set the parent location for a branch.
321
    
322
    Takes a location to set, which must be utf8 encoded.
323
    """
324
325
    def do_with_locked_branch(self, branch, location):
326
        branch._set_parent_location(location)
327
        return SuccessfulSmartServerResponse(())
328
329
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
330
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
331
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
332
    def do_with_branch(self, branch, branch_token='', repo_token=''):
333
        if branch_token == '':
334
            branch_token = None
335
        if repo_token == '':
336
            repo_token = None
337
        try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
338
            repo_token = branch.repository.lock_write(
339
                token=repo_token).repository_token
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
340
            try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
341
                branch_token = branch.lock_write(
342
                    token=branch_token).branch_token
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
343
            finally:
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
344
                # this leaves the repository with 1 lock
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
345
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
346
        except errors.LockContention:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
347
            return FailedSmartServerResponse(('LockContention',))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
348
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
349
            return FailedSmartServerResponse(('TokenMismatch',))
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
350
        except errors.UnlockableTransport:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
351
            return FailedSmartServerResponse(('UnlockableTransport',))
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
352
        except errors.LockFailed, e:
353
            return FailedSmartServerResponse(('LockFailed', str(e.lock), str(e.why)))
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
354
        if repo_token is None:
355
            repo_token = ''
356
        else:
357
            branch.repository.leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
358
        branch.leave_lock_in_place()
359
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
360
        return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
361
362
363
class SmartServerBranchRequestUnlock(SmartServerBranchRequest):
364
365
    def do_with_branch(self, branch, branch_token, repo_token):
366
        try:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
367
            branch.repository.lock_write(token=repo_token)
368
            try:
369
                branch.lock_write(token=branch_token)
370
            finally:
371
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
372
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
373
            return FailedSmartServerResponse(('TokenMismatch',))
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
374
        if repo_token:
375
            branch.repository.dont_leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
376
        branch.dont_leave_lock_in_place()
377
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
378
        return SuccessfulSmartServerResponse(('ok',))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
379