/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
6280.4.4 by Jelmer Vernooij
Add Branch.break_lock.
80
class SmartServerBranchBreakLock(SmartServerBranchRequest):
81
82
    def do_with_branch(self, branch):
83
        """Break a branch lock.
84
        """
85
        branch.break_lock()
86
        return SuccessfulSmartServerResponse(('ok', ), )
87
88
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
89
class SmartServerBranchGetConfigFile(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
90
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
91
    def do_with_branch(self, branch):
3407.2.1 by Martin Pool
Deprecate LockableFiles.get
92
        """Return the content of branch.conf
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
93
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
94
        The body is not utf8 decoded - its the literal bytestream from disk.
95
        """
96
        try:
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
97
            content = branch.control_transport.get_bytes('branch.conf')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
98
        except errors.NoSuchFile:
99
            content = ''
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
100
        return SuccessfulSmartServerResponse( ('ok', ), content)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
101
102
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
103
class SmartServerBranchPutConfigFile(SmartServerBranchRequest):
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
104
    """Set the configuration data for a branch.
105
106
    New in 2.5.
107
    """
108
109
    def do_with_branch(self, branch, branch_token, repo_token):
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
110
        """Set the content of branch.conf.
111
112
        The body is not utf8 decoded - its the literal bytestream for disk.
113
        """
114
        self._branch = branch
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
115
        self._branch_token = branch_token
116
        self._repo_token = repo_token
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
117
        # Signal we want a body
118
        return None
119
120
    def do_body(self, body_bytes):
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
121
        self._branch.repository.lock_write(token=self._repo_token)
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
122
        try:
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
123
            self._branch.lock_write(token=self._branch_token)
124
            try:
125
                self._branch.control_transport.put_bytes(
126
                    'branch.conf', body_bytes)
127
            finally:
128
                self._branch.unlock()
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
129
        finally:
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
130
            self._branch.repository.unlock()
131
        return SuccessfulSmartServerResponse(('ok', ))
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
132
133
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
134
class SmartServerBranchGetParent(SmartServerBranchRequest):
135
136
    def do_with_branch(self, branch):
137
        """Return the parent of branch."""
138
        parent = branch._get_parent_location() or ''
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
139
        return SuccessfulSmartServerResponse((parent,))
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
140
141
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.
142
class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
143
144
    def do_with_branch(self, branch):
145
        """Return the _get_tags_bytes for a branch."""
146
        bytes = branch._get_tags_bytes()
147
        return SuccessfulSmartServerResponse((bytes,))
148
149
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.
150
class SmartServerBranchSetTagsBytes(SmartServerLockedBranchRequest):
151
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).
152
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
153
        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).
154
            self, backing_transport, root_client_path, jail_root)
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
155
        self.locked = False
156
        
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.
157
    def do_with_locked_branch(self, branch):
4556.2.4 by Andrew Bennetts
Add NEWS entry, docstring.
158
        """Call _set_tags_bytes for a branch.
159
160
        New in 1.18.
161
        """
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.
162
        # We need to keep this branch locked until we get a body with the tags
163
        # bytes.
164
        self.branch = branch
165
        self.branch.lock_write()
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
166
        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.
167
168
    def do_body(self, bytes):
169
        self.branch._set_tags_bytes(bytes)
170
        return SuccessfulSmartServerResponse(())
171
172
    def do_end(self):
4556.2.8 by Andrew Bennetts
Add TODO comment.
173
        # TODO: this request shouldn't have to do this housekeeping manually.
174
        # Some of this logic probably belongs in a base class.
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
175
        if not self.locked:
176
            # We never acquired the branch successfully in the first place, so
177
            # there's nothing more to do.
178
            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.
179
        try:
180
            return SmartServerLockedBranchRequest.do_end(self)
181
        finally:
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
182
            # 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.
183
            self.branch.unlock()
184
185
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).
186
class SmartServerBranchHeadsToFetch(SmartServerBranchRequest):
187
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
188
    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).
189
        """Return the heads-to-fetch for a Branch as two bencoded lists.
190
        
191
        See Branch.heads_to_fetch.
192
193
        New in 2.4.
194
        """
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
195
        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).
196
        return SuccessfulSmartServerResponse(
197
            (list(must_fetch), list(if_present_fetch)))
198
199
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
200
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
201
202
    def do_with_branch(self, branch):
203
        stacked_on_url = branch.get_stacked_on_url()
204
        return SuccessfulSmartServerResponse(('ok', stacked_on_url))
205
206
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
207
class SmartServerRequestRevisionHistory(SmartServerBranchRequest):
208
209
    def do_with_branch(self, branch):
210
        """Get the revision history for the branch.
211
212
        The revision list is returned as the body content,
213
        with each revision utf8 encoded and \x00 joined.
214
        """
6165.4.23 by Jelmer Vernooij
Fix tests.
215
        branch.lock_read()
216
        try:
217
            graph = branch.repository.get_graph()
218
            stop_revisions = (None, _mod_revision.NULL_REVISION)
219
            history = list(graph.iter_lefthand_ancestry(
220
                branch.last_revision(), stop_revisions))
221
        finally:
222
            branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
223
        return SuccessfulSmartServerResponse(
6165.4.11 by Jelmer Vernooij
More test fixes.
224
            ('ok', ), ('\x00'.join(reversed(history))))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
225
226
227
class SmartServerBranchRequestLastRevisionInfo(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
228
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
229
    def do_with_branch(self, branch):
230
        """Return branch.last_revision_info().
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
231
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
232
        The revno is encoded in decimal, the revision_id is encoded as utf8.
233
        """
234
        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.
235
        return SuccessfulSmartServerResponse(('ok', str(revno), last_revision))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
236
237
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
238
class SmartServerBranchRequestRevisionIdToRevno(SmartServerBranchRequest):
239
240
    def do_with_branch(self, branch, revid):
241
        """Return branch.revision_id_to_revno().
242
6263.1.4 by Jelmer Vernooij
Mention version in which Branch.revision_id_to_revno was introduced.
243
        New in 2.5.
244
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
245
        The revno is encoded in decimal, the revision_id is encoded as utf8.
246
        """
247
        try:
248
            dotted_revno = branch.revision_id_to_dotted_revno(revid)
249
        except errors.NoSuchRevision:
250
            return FailedSmartServerResponse(('NoSuchRevision', revid))
251
        return SuccessfulSmartServerResponse(
252
            ('ok', ) + tuple(map(str, dotted_revno)))
253
254
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
255
class SmartServerSetTipRequest(SmartServerLockedBranchRequest):
256
    """Base class for handling common branch request logic for requests that
257
    update the branch tip.
258
    """
259
260
    def do_with_locked_branch(self, branch, *args):
261
        try:
262
            return self.do_tip_change_with_locked_branch(branch, *args)
263
        except errors.TipChangeRejected, e:
264
            msg = e.msg
265
            if isinstance(msg, unicode):
266
                msg = msg.encode('utf-8')
267
            return FailedSmartServerResponse(('TipChangeRejected', msg))
268
269
4226.2.1 by Robert Collins
Set branch config options via a smart method.
270
class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
271
    """Set an option in the branch configuration."""
272
273
    def do_with_locked_branch(self, branch, value, name, section):
274
        if not section:
275
            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.
276
        branch._get_config().set_option(value.decode('utf8'), name, section)
4226.2.1 by Robert Collins
Set branch config options via a smart method.
277
        return SuccessfulSmartServerResponse(())
278
279
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
280
class SmartServerBranchRequestSetConfigOptionDict(SmartServerLockedBranchRequest):
281
    """Set an option in the branch configuration.
282
    
283
    New in 2.2.
284
    """
285
286
    def do_with_locked_branch(self, branch, value_dict, name, section):
287
        utf8_dict = bencode.bdecode(value_dict)
288
        value_dict = {}
289
        for key, value in utf8_dict.items():
290
            value_dict[key.decode('utf8')] = value.decode('utf8')
291
        if not section:
292
            section = None
293
        branch._get_config().set_option(value_dict, name, section)
294
        return SuccessfulSmartServerResponse(())
295
296
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
297
class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
298
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
299
    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.
300
        if new_last_revision_id == 'null:':
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
301
            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.
302
        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.
303
            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.
304
                return FailedSmartServerResponse(
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
305
                    ('NoSuchRevision', new_last_revision_id))
5718.8.18 by Jelmer Vernooij
Translate local set_rh calls to remote set_rh calls.
306
            branch._set_revision_history(branch._lefthand_history(
307
                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.
308
        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.
309
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
310
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
311
class SmartServerBranchRequestSetLastRevisionEx(SmartServerSetTipRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
312
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
313
    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.
314
            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.
315
        """Set the last revision of the branch.
316
317
        New in 1.6.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
318
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.
319
        :param new_last_revision_id: the revision ID to set as the last
320
            revision of the branch.
321
        :param allow_divergence: A flag.  If non-zero, change the revision ID
322
            even if the new_last_revision_id's ancestry has diverged from the
323
            current last revision.  If zero, a 'Diverged' error will be
324
            returned if new_last_revision_id is not a descendant of the current
325
            last revision.
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
326
        :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.
327
            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.
328
            revision, then the last revision will not be changed.  If non-zero
329
            and there is no divergence, then the last revision is always
330
            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.
331
332
        :returns: on success, a tuple of ('ok', revno, revision_id), where
333
            revno and revision_id are the new values of the current last
334
            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.
335
            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.
336
        """
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
337
        do_not_overwrite_descendant = not allow_overwrite_descendant
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
338
        try:
3441.5.18 by Andrew Bennetts
Fix some test failures.
339
            last_revno, last_rev = branch.last_revision_info()
340
            graph = branch.repository.get_graph()
341
            if not allow_divergence or do_not_overwrite_descendant:
342
                relation = branch._revision_relations(
343
                    last_rev, new_last_revision_id, graph)
344
                if relation == 'diverged' and not allow_divergence:
345
                    return FailedSmartServerResponse(('Diverged',))
346
                if relation == 'a_descends_from_b' and do_not_overwrite_descendant:
347
                    return SuccessfulSmartServerResponse(
348
                        ('ok', last_revno, last_rev))
349
            new_revno = graph.find_distance_to_null(
350
                new_last_revision_id, [(last_rev, last_revno)])
351
            branch.set_last_revision_info(new_revno, new_last_revision_id)
3441.5.23 by Andrew Bennetts
Fix test failures.
352
        except errors.GhostRevisionsHaveNoRevno:
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
353
            return FailedSmartServerResponse(
354
                ('NoSuchRevision', new_last_revision_id))
3441.5.18 by Andrew Bennetts
Fix some test failures.
355
        return SuccessfulSmartServerResponse(
356
            ('ok', new_revno, new_last_revision_id))
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
357
358
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
359
class SmartServerBranchRequestSetLastRevisionInfo(SmartServerSetTipRequest):
3297.4.2 by Andrew Bennetts
Add backwards compatibility for servers older than 1.4.
360
    """Branch.set_last_revision_info.  Sets the revno and the revision ID of
361
    the specified branch.
362
363
    New in bzrlib 1.4.
364
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
365
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
366
    def do_tip_change_with_locked_branch(self, branch, new_revno,
367
            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.
368
        try:
369
            branch.set_last_revision_info(int(new_revno), new_last_revision_id)
370
        except errors.NoSuchRevision:
371
            return FailedSmartServerResponse(
372
                ('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.
373
        return SuccessfulSmartServerResponse(('ok',))
374
375
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
376
class SmartServerBranchRequestSetParentLocation(SmartServerLockedBranchRequest):
377
    """Set the parent location for a branch.
378
    
379
    Takes a location to set, which must be utf8 encoded.
380
    """
381
382
    def do_with_locked_branch(self, branch, location):
383
        branch._set_parent_location(location)
384
        return SuccessfulSmartServerResponse(())
385
386
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
387
class SmartServerBranchRequestLockWrite(SmartServerBranchRequest):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
388
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
389
    def do_with_branch(self, branch, branch_token='', repo_token=''):
390
        if branch_token == '':
391
            branch_token = None
392
        if repo_token == '':
393
            repo_token = None
394
        try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
395
            repo_token = branch.repository.lock_write(
396
                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).
397
            try:
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
398
                branch_token = branch.lock_write(
399
                    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).
400
            finally:
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
401
                # 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).
402
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
403
        except errors.LockContention:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
404
            return FailedSmartServerResponse(('LockContention',))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
405
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
406
            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.
407
        except errors.UnlockableTransport:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
408
            return FailedSmartServerResponse(('UnlockableTransport',))
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
409
        except errors.LockFailed, e:
410
            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.
411
        if repo_token is None:
412
            repo_token = ''
413
        else:
414
            branch.repository.leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
415
        branch.leave_lock_in_place()
416
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
417
        return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
418
419
420
class SmartServerBranchRequestUnlock(SmartServerBranchRequest):
421
422
    def do_with_branch(self, branch, branch_token, repo_token):
423
        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).
424
            branch.repository.lock_write(token=repo_token)
425
            try:
426
                branch.lock_write(token=branch_token)
427
            finally:
428
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
429
        except errors.TokenMismatch:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
430
            return FailedSmartServerResponse(('TokenMismatch',))
3015.2.6 by Robert Collins
In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
431
        if repo_token:
432
            branch.repository.dont_leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
433
        branch.dont_leave_lock_in_place()
434
        branch.unlock()
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
435
        return SuccessfulSmartServerResponse(('ok',))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
436
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
437
438
class SmartServerBranchRequestGetPhysicalLockStatus(SmartServerBranchRequest):
439
    """Get the physical lock status for a branch.
440
441
    New in 2.5.
442
    """
443
444
    def do_with_branch(self, branch):
445
        if branch.get_physical_lock_status():
446
            return SuccessfulSmartServerResponse(('yes',))
447
        else:
448
            return SuccessfulSmartServerResponse(('no',))