~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,
23
    )
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
24
from bzrlib.bzrdir import BzrDir
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
25
from bzrlib.smart.request import (
26
    FailedSmartServerResponse,
27
    SmartServerRequest,
28
    SuccessfulSmartServerResponse,
29
    )
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
30
31
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
32
class SmartServerBranchRequest(SmartServerRequest):
2692.1.10 by Andrew Bennetts
More docstring polish
33
    """Base class for handling common branch request logic.
34
    """
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
35
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
36
    def do(self, path, *args):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
37
        """Execute a request for a branch at path.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
38
2692.1.10 by Andrew Bennetts
More docstring polish
39
        All Branch requests take a path to the branch as their first argument.
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
40
41
        If the branch is a branch reference, NotBranchError is raised.
2692.1.10 by Andrew Bennetts
More docstring polish
42
43
        :param path: The path for the repository as received from the
44
            client.
45
        :return: A SmartServerResponse from self.do_with_branch().
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
46
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
47
        transport = self.transport_from_client_path(path)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
48
        bzrdir = BzrDir.open_from_transport(transport)
49
        if bzrdir.get_branch_reference() is not None:
50
            raise errors.NotBranchError(transport.base)
4160.2.6 by Andrew Bennetts
Add ignore_fallbacks flag.
51
        branch = bzrdir.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.
52
        return self.do_with_branch(branch, *args)
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
53
54
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
55
class SmartServerLockedBranchRequest(SmartServerBranchRequest):
56
    """Base class for handling common branch request logic for requests that
57
    need a write lock.
58
    """
59
60
    def do_with_branch(self, branch, branch_token, repo_token, *args):
61
        """Execute a request for a branch.
62
63
        A write lock will be acquired with the given tokens for the branch and
64
        repository locks.  The lock will be released once the request is
65
        processed.  The physical lock state won't be changed.
66
        """
67
        # 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).
68
        branch.repository.lock_write(token=repo_token)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
69
        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).
70
            branch.lock_write(token=branch_token)
71
            try:
72
                return self.do_with_locked_branch(branch, *args)
73
            finally:
74
                branch.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
75
        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).
76
            branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
77
78
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
79
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
80
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
81
    def do_with_branch(self, branch):
3407.2.1 by Martin Pool
Deprecate LockableFiles.get
82
        """Return the content of branch.conf
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
83
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
84
        The body is not utf8 decoded - its the literal bytestream from disk.
85
        """
86
        try:
3407.2.14 by Martin Pool
Remove more cases of getting transport via control_files
87
            content = branch._transport.get_bytes('branch.conf')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
88
        except errors.NoSuchFile:
89
            content = ''
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
90
        return SuccessfulSmartServerResponse( ('ok', ), content)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
91
92
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
93
class SmartServerBranchGetParent(SmartServerBranchRequest):
94
95
    def do_with_branch(self, branch):
96
        """Return the parent of branch."""
97
        parent = branch._get_parent_location() or ''
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
98
        return SuccessfulSmartServerResponse((parent,))
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
99
100
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.
101
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
102
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,))
107
108
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.
109
class SmartServerBranchSetTagsBytes(SmartServerLockedBranchRequest):
110
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).
111
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
112
        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).
113
            self, backing_transport, root_client_path, jail_root)
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
114
        self.locked = False
115
        
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.
116
    def do_with_locked_branch(self, branch):
4556.2.4 by Andrew Bennetts
Add NEWS entry, docstring.
117
        """Call _set_tags_bytes for a branch.
118
119
        New in 1.18.
120
        """
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.
121
        # We need to keep this branch locked until we get a body with the tags
122
        # bytes.
123
        self.branch = branch
124
        self.branch.lock_write()
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
125
        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.
126
127
    def do_body(self, bytes):
128
        self.branch._set_tags_bytes(bytes)
129
        return SuccessfulSmartServerResponse(())
130
131
    def do_end(self):
4556.2.8 by Andrew Bennetts
Add TODO comment.
132
        # TODO: this request shouldn't have to do this housekeeping manually.
133
        # Some of this logic probably belongs in a base class.
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
134
        if not self.locked:
135
            # We never acquired the branch successfully in the first place, so
136
            # there's nothing more to do.
137
            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.
138
        try:
139
            return SmartServerLockedBranchRequest.do_end(self)
140
        finally:
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
141
            # 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.
142
            self.branch.unlock()
143
144
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).
145
class SmartServerBranchHeadsToFetch(SmartServerBranchRequest):
146
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
147
    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).
148
        """Return the heads-to-fetch for a Branch as two bencoded lists.
149
        
150
        See Branch.heads_to_fetch.
151
152
        New in 2.4.
153
        """
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
154
        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).
155
        return SuccessfulSmartServerResponse(
156
            (list(must_fetch), list(if_present_fetch)))
157
158
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
159
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
160
161
    def do_with_branch(self, branch):
162
        stacked_on_url = branch.get_stacked_on_url()
163
        return SuccessfulSmartServerResponse(('ok', stacked_on_url))
164
165
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
166
class SmartServerRequestRevisionHistory(SmartServerBranchRequest):
167
168
    def do_with_branch(self, branch):
169
        """Get the revision history for the branch.
170
171
        The revision list is returned as the body content,
172
        with each revision utf8 encoded and \x00 joined.
173
        """
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
174
        return SuccessfulSmartServerResponse(
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
175
            ('ok', ), ('\x00'.join(branch.revision_history())))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
176
177
178
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
179
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
180
    def do_with_branch(self, branch):
181
        """Return branch.last_revision_info().
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
182
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
183
        The revno is encoded in decimal, the revision_id is encoded as utf8.
184
        """
185
        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.
186
        return SuccessfulSmartServerResponse(('ok', str(revno), last_revision))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
187
188
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
189
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
190
    """Base class for handling common branch request logic for requests that
191
    update the branch tip.
192
    """
193
194
    def do_with_locked_branch(self, branch, *args):
195
        try:
196
            return self.do_tip_change_with_locked_branch(branch, *args)
197
        except errors.TipChangeRejected, e:
198
            msg = e.msg
199
            if isinstance(msg, unicode):
200
                msg = msg.encode('utf-8')
201
            return FailedSmartServerResponse(('TipChangeRejected', msg))
202
203
4226.2.1 by Robert Collins
Set branch config options via a smart method.
204
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
205
    """Set an option in the branch configuration."""
206
207
    def do_with_locked_branch(self, branch, value, name, section):
208
        if not section:
209
            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.
210
        branch._get_config().set_option(value.decode('utf8'), name, section)
4226.2.1 by Robert Collins
Set branch config options via a smart method.
211
        return SuccessfulSmartServerResponse(())
212
213
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
214
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
215
    """Set an option in the branch configuration.
216
    
217
    New in 2.2.
218
    """
219
220
    def do_with_locked_branch(self, branch, value_dict, name, section):
221
        utf8_dict = bencode.bdecode(value_dict)
222
        value_dict = {}
223
        for key, value in utf8_dict.items():
224
            value_dict[key.decode('utf8')] = value.decode('utf8')
225
        if not section:
226
            section = None
227
        branch._get_config().set_option(value_dict, name, section)
228
        return SuccessfulSmartServerResponse(())
229
230
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
231
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
232
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
233
    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.
234
        if new_last_revision_id == 'null:':
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
235
            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.
236
        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.
237
            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.
238
                return FailedSmartServerResponse(
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
239
                    ('NoSuchRevision', new_last_revision_id))
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
240
            branch._set_revision_history(branch._lefthand_history(
241
                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.
242
        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.
243
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
244
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
245
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
246
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
247
    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.
248
            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.
249
        """Set the last revision of the branch.
250
251
        New in 1.6.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
252
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.
253
        :param new_last_revision_id: the revision ID to set as the last
254
            revision of the branch.
255
        :param allow_divergence: A flag.  If non-zero, change the revision ID
256
            even if the new_last_revision_id's ancestry has diverged from the
257
            current last revision.  If zero, a 'Diverged' error will be
258
            returned if new_last_revision_id is not a descendant of the current
259
            last revision.
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
260
        :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.
261
            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.
262
            revision, then the last revision will not be changed.  If non-zero
263
            and there is no divergence, then the last revision is always
264
            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.
265
266
        :returns: on success, a tuple of ('ok', revno, revision_id), where
267
            revno and revision_id are the new values of the current last
268
            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.
269
            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.
270
        """
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
271
        do_not_overwrite_descendant = not allow_overwrite_descendant
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
272
        try:
3441.5.18 by Andrew Bennetts
Fix some test failures.
273
            last_revno, last_rev = branch.last_revision_info()
274
            graph = branch.repository.get_graph()
275
            if not allow_divergence or do_not_overwrite_descendant:
276
                relation = branch._revision_relations(
277
                    last_rev, new_last_revision_id, graph)
278
                if relation == 'diverged' and not allow_divergence:
279
                    return FailedSmartServerResponse(('Diverged',))
280
                if relation == 'a_descends_from_b' and do_not_overwrite_descendant:
281
                    return SuccessfulSmartServerResponse(
282
                        ('ok', last_revno, last_rev))
283
            new_revno = graph.find_distance_to_null(
284
                new_last_revision_id, [(last_rev, last_revno)])
285
            branch.set_last_revision_info(new_revno, new_last_revision_id)
3441.5.23 by Andrew Bennetts
Fix test failures.
286
        except errors.GhostRevisionsHaveNoRevno:
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
287
            return FailedSmartServerResponse(
288
                ('NoSuchRevision', new_last_revision_id))
3441.5.18 by Andrew Bennetts
Fix some test failures.
289
        return SuccessfulSmartServerResponse(
290
            ('ok', new_revno, new_last_revision_id))
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
291
292
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
293
class SmartServerBranchRequestSetLastRevisionInfo(SmartServerSetTipRequest):
3297.4.2 by Andrew Bennetts
Add backwards compatibility for servers older than 1.4.
294
    """Branch.set_last_revision_info.  Sets the revno and the revision ID of
295
    the specified branch.
296
297
    New in bzrlib 1.4.
298
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
299
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
300
    def do_tip_change_with_locked_branch(self, branch, new_revno,
301
            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.
302
        try:
303
            branch.set_last_revision_info(int(new_revno), new_last_revision_id)
304
        except errors.NoSuchRevision:
305
            return FailedSmartServerResponse(
306
                ('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.
307
        return SuccessfulSmartServerResponse(('ok',))
308
309
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
310
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
311
    """Set the parent location for a branch.
312
    
313
    Takes a location to set, which must be utf8 encoded.
314
    """
315
316
    def do_with_locked_branch(self, branch, location):
317
        branch._set_parent_location(location)
318
        return SuccessfulSmartServerResponse(())
319
320
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
321
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
322
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
323
    def do_with_branch(self, branch, branch_token='', repo_token=''):
324
        if branch_token == '':
325
            branch_token = None
326
        if repo_token == '':
327
            repo_token = None
328
        try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
329
            repo_token = branch.repository.lock_write(
330
                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).
331
            try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
332
                branch_token = branch.lock_write(
333
                    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).
334
            finally:
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
335
                # 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).
336
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
337
        except errors.LockContention:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
338
            return FailedSmartServerResponse(('LockContention',))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
339
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
340
            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.
341
        except errors.UnlockableTransport:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
342
            return FailedSmartServerResponse(('UnlockableTransport',))
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
343
        except errors.LockFailed, e:
344
            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.
345
        if repo_token is None:
346
            repo_token = ''
347
        else:
348
            branch.repository.leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
349
        branch.leave_lock_in_place()
350
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
351
        return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
352
353
354
class SmartServerBranchRequestUnlock(SmartServerBranchRequest):
355
356
    def do_with_branch(self, branch, branch_token, repo_token):
357
        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).
358
            branch.repository.lock_write(token=repo_token)
359
            try:
360
                branch.lock_write(token=branch_token)
361
            finally:
362
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
363
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
364
            return FailedSmartServerResponse(('TokenMismatch',))
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
365
        if repo_token:
366
            branch.repository.dont_leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
367
        branch.dont_leave_lock_in_place()
368
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
369
        return SuccessfulSmartServerResponse(('ok',))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
370