/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1
# Copyright (C) 2006 Canonical Ltd
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.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
16
17
"""Server-side bzrdir related request implmentations."""
18
19
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
20
from bzrlib import branch, errors, repository
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
21
from bzrlib.bzrdir import (
22
    BzrDir,
23
    BzrDirFormat,
24
    BzrDirMetaFormat1,
25
    network_format_registry,
26
    )
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
27
from bzrlib.smart.request import (
28
    FailedSmartServerResponse,
29
    SmartServerRequest,
30
    SuccessfulSmartServerResponse,
31
    )
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
32
33
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
34
class SmartServerRequestOpenBzrDir(SmartServerRequest):
35
36
    def do(self, path):
37
        from bzrlib.bzrdir import BzrDirFormat
38
        try:
2692.1.11 by Andrew Bennetts
Improve test coverage by making SmartTCPServer_for_testing by default create a server that does not serve the backing transport's root at its own root. This mirrors the way most HTTP smart servers are configured.
39
            t = self.transport_from_client_path(path)
40
        except errors.PathNotChild:
41
            # The client is trying to ask about a path that they have no access
42
            # to.
43
            # Ideally we'd return a FailedSmartServerResponse here rather than
44
            # a "successful" negative, but we want to be compatibile with
45
            # clients that don't anticipate errors from this method.
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
46
            answer = 'no'
47
        else:
2692.1.11 by Andrew Bennetts
Improve test coverage by making SmartTCPServer_for_testing by default create a server that does not serve the backing transport's root at its own root. This mirrors the way most HTTP smart servers are configured.
48
            default_format = BzrDirFormat.get_default_format()
49
            real_bzrdir = default_format.open(t, _found=True)
50
            try:
51
                real_bzrdir._format.probe_transport(t)
52
            except (errors.NotBranchError, errors.UnknownFormatError):
53
                answer = 'no'
54
            else:
55
                answer = 'yes'
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
56
        return SuccessfulSmartServerResponse((answer,))
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
57
58
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
59
class SmartServerRequestBzrDir(SmartServerRequest):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
60
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
61
    def do(self, path, *args):
62
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
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.
63
        try:
64
            self._bzrdir = BzrDir.open_from_transport(
65
                self.transport_from_client_path(path))
66
        except errors.NotBranchError:
67
            return FailedSmartServerResponse(('nobranch', ))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
68
        return self.do_bzrdir_request(*args)
69
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
70
    def _boolean_to_yes_no(self, a_boolean):
71
        if a_boolean:
72
            return 'yes'
73
        else:
74
            return 'no'
75
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
76
    def _format_to_capabilities(self, repo_format):
77
        rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
78
        tree_ref = self._boolean_to_yes_no(
79
            repo_format.supports_tree_reference)
80
        external_lookup = self._boolean_to_yes_no(
81
            repo_format.supports_external_lookups)
82
        return rich_root, tree_ref, external_lookup
83
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
84
    def _repo_relpath(self, current_transport, repository):
85
        """Get the relative path for repository from current_transport."""
86
        # the relpath of the bzrdir in the found repository gives us the
87
        # path segments to pop-out.
88
        relpath = repository.bzrdir.root_transport.relpath(
89
            current_transport.base)
90
        if len(relpath):
91
            segments = ['..'] * len(relpath.split('/'))
92
        else:
93
            segments = []
94
        return '/'.join(segments)
95
96
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
97
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
98
99
    def do_bzrdir_request(self, require_stacking):
4160.2.10 by Andrew Bennetts
Improve documentation of BzrDir.cloning_metadir RPC
100
        """Get the format that should be used when cloning from this dir.
101
102
        New in 1.13.
103
        
104
        :return: on success, a 3-tuple of network names for (control,
105
            repository, branch) directories, where '' signifies "not present".
106
            If this BzrDir contains a branch reference then this will fail with
107
            BranchReference; clients should resolve branch references before
108
            calling this RPC.
109
        """
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
110
        try:
111
            branch_ref = self._bzrdir.get_branch_reference()
112
        except errors.NotBranchError:
113
            branch_ref = None
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
114
        if branch_ref is not None:
115
            # The server shouldn't try to resolve references, and it quite
116
            # possibly can't reach them anyway.  The client needs to resolve
117
            # the branch reference to determine the cloning_metadir.
118
            return FailedSmartServerResponse(('BranchReference',))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
119
        if require_stacking == "True":
120
            require_stacking = True
121
        else:
122
            require_stacking = False
123
        control_format = self._bzrdir.cloning_metadir(
124
            require_stacking=require_stacking)
125
        control_name = control_format.network_name()
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
126
        # XXX: There should be a method that tells us that the format does/does
127
        # not have subformats.
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
128
        if isinstance(control_format, BzrDirMetaFormat1):
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
129
            branch_name = ('branch',
130
                control_format.get_branch_format().network_name())
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
131
            repository_name = control_format.repository_format.network_name()
132
        else:
133
            # Only MetaDir has delegated formats today.
4084.2.2 by Robert Collins
Review feedback.
134
            branch_name = ('branch', '')
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
135
            repository_name = ''
136
        return SuccessfulSmartServerResponse((control_name, repository_name,
137
            branch_name))
138
139
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
140
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
141
142
    def do(self, path, network_name):
143
        """Create a branch in the bzr dir at path.
144
145
        This operates precisely like 'bzrdir.create_branch'.
146
147
        If a bzrdir is not present, an exception is propogated
148
        rather than 'no branch' because these are different conditions (and
149
        this method should only be called after establishing that a bzr dir
150
        exists anyway).
151
152
        This is the initial version of this method introduced to the smart
153
        server for 1.13.
154
155
        :param path: The path to the bzrdir.
156
        :param network_name: The network name of the branch type to create.
157
        :return: (ok, network_name)
158
        """
159
        bzrdir = BzrDir.open_from_transport(
160
            self.transport_from_client_path(path))
161
        format = branch.network_format_registry.get(network_name)
162
        bzrdir.branch_format = format
163
        result = format.initialize(bzrdir)
164
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
165
            result.repository._format)
166
        branch_format = result._format.network_name()
167
        repo_format = result.repository._format.network_name()
168
        repo_path = self._repo_relpath(bzrdir.root_transport,
169
            result.repository)
170
        # branch format, repo relpath, rich_root, tree_ref, external_lookup,
171
        # repo_network_name
172
        return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
173
            rich_root, tree_ref, external_lookup, repo_format))
174
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
175
176
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
177
178
    def do(self, path, network_name, shared):
179
        """Create a repository in the bzr dir at path.
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
180
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
181
        This operates precisely like 'bzrdir.create_repository'.
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
182
4031.3.1 by Frank Aspell
Fixing various typos
183
        If a bzrdir is not present, an exception is propagated
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
184
        rather than 'no branch' because these are different conditions (and
185
        this method should only be called after establishing that a bzr dir
186
        exists anyway).
187
188
        This is the initial version of this method introduced to the smart
189
        server for 1.13.
190
191
        :param path: The path to the bzrdir.
192
        :param network_name: The network name of the repository type to create.
193
        :param shared: The value to pass create_repository for the shared
194
            parameter.
195
        :return: (ok, rich_root, tree_ref, external_lookup, network_name)
196
        """
197
        bzrdir = BzrDir.open_from_transport(
198
            self.transport_from_client_path(path))
199
        shared = shared == 'True'
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
200
        format = repository.network_format_registry.get(network_name)
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
201
        bzrdir.repository_format = format
202
        result = format.initialize(bzrdir, shared=shared)
203
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
204
            result._format)
205
        return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
206
            external_lookup, result._format.network_name()))
207
208
209
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
210
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
211
    def _find(self, path):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
212
        """try to find a repository from path upwards
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
213
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
214
        This operates precisely like 'bzrdir.find_repository'.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
215
4053.1.2 by Robert Collins
Actually make this branch work.
216
        :return: (relpath, rich_root, tree_ref, external_lookup, network_name).
217
            All are strings, relpath is a / prefixed path, the next three are
218
            either 'yes' or 'no', and the last is a repository format network
219
            name.
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
220
        :raises errors.NoRepositoryPresent: When there is no repository
221
            present.
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
222
        """
2692.1.6 by Andrew Bennetts
Fix some >80 columns violations.
223
        bzrdir = BzrDir.open_from_transport(
224
            self.transport_from_client_path(path))
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
225
        repository = bzrdir.find_repository()
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
226
        path = self._repo_relpath(bzrdir.root_transport, repository)
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
227
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
228
            repository._format)
4053.1.2 by Robert Collins
Actually make this branch work.
229
        network_name = repository._format.network_name()
230
        return path, rich_root, tree_ref, external_lookup, network_name
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
231
232
233
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
234
235
    def do(self, path):
236
        """try to find a repository from path upwards
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
237
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
238
        This operates precisely like 'bzrdir.find_repository'.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
239
4031.3.1 by Frank Aspell
Fixing various typos
240
        If a bzrdir is not present, an exception is propagated
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
241
        rather than 'no branch' because these are different conditions.
242
243
        This is the initial version of this method introduced with the smart
244
        server. Modern clients will try the V2 method that adds support for the
245
        supports_external_lookups attribute.
246
247
        :return: norepository or ok, relpath.
248
        """
249
        try:
4053.1.2 by Robert Collins
Actually make this branch work.
250
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
251
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
252
        except errors.NoRepositoryPresent:
253
            return FailedSmartServerResponse(('norepository', ))
254
255
256
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
257
258
    def do(self, path):
259
        """try to find a repository from path upwards
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
260
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
261
        This operates precisely like 'bzrdir.find_repository'.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
262
4031.3.1 by Frank Aspell
Fixing various typos
263
        If a bzrdir is not present, an exception is propagated
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
264
        rather than 'no branch' because these are different conditions.
265
3221.3.3 by Robert Collins
* Hook up the new remote method ``RemoteBzrDir.find_repositoryV2`` so
266
        This is the second edition of this method introduced in bzr 1.3, which
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
267
        returns information about the supports_external_lookups format
268
        attribute too.
269
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
270
        :return: norepository or ok, relpath, rich_root, tree_ref,
271
            external_lookup.
272
        """
273
        try:
4053.1.2 by Robert Collins
Actually make this branch work.
274
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
275
            return SuccessfulSmartServerResponse(
276
                ('ok', path, rich_root, tree_ref, external_lookup))
277
        except errors.NoRepositoryPresent:
278
            return FailedSmartServerResponse(('norepository', ))
279
280
281
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
282
283
    def do(self, path):
284
        """try to find a repository from path upwards
285
286
        This operates precisely like 'bzrdir.find_repository'.
287
288
        If a bzrdir is not present, an exception is propogated
289
        rather than 'no branch' because these are different conditions.
290
291
        This is the third edition of this method introduced in bzr 1.13, which
292
        returns information about the network name of the repository format.
293
294
        :return: norepository or ok, relpath, rich_root, tree_ref,
295
            external_lookup, network_name.
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
296
        """
297
        try:
4053.1.2 by Robert Collins
Actually make this branch work.
298
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
299
            return SuccessfulSmartServerResponse(
4053.1.2 by Robert Collins
Actually make this branch work.
300
                ('ok', path, rich_root, tree_ref, external_lookup, name))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
301
        except errors.NoRepositoryPresent:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
302
            return FailedSmartServerResponse(('norepository', ))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
303
304
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
305
class SmartServerBzrDirRequestConfigFile(SmartServerRequestBzrDir):
306
307
    def do_bzrdir_request(self):
308
        """Get the configuration bytes for a config file in bzrdir.
309
        
310
        The body is not utf8 decoded - it is the literal bytestream from disk.
311
        """
312
        config = self._bzrdir._get_config()
313
        if config is None:
314
            content = ''
315
        else:
316
            content = config._get_config_file().read()
317
        return SuccessfulSmartServerResponse((), content)
318
319
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
320
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
321
322
    def do(self, path):
323
        """Initialize a bzrdir at path.
324
325
        The default format of the server is used.
326
        :return: SmartServerResponse(('ok', ))
327
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
328
        target_transport = self.transport_from_client_path(path)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
329
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
330
        return SuccessfulSmartServerResponse(('ok', ))
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
331
332
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
333
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
334
335
    def parse_NoneTrueFalse(self, arg):
336
        if not arg:
337
            return None
338
        if arg == 'False':
339
            return False
340
        if arg == 'True':
341
            return True
342
        raise AssertionError("invalid arg %r" % arg)
343
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
344
    def parse_NoneString(self, arg):
345
        return arg or None
346
347
    def _serialize_NoneTrueFalse(self, arg):
348
        if arg is False:
349
            return 'False'
350
        if not arg:
351
            return ''
352
        return 'True'
353
354
    def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
355
        force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
356
        make_working_trees, shared_repo):
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
357
        """Initialize a bzrdir at path as per BzrDirFormat.initialize_ex
358
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
359
        :return: return SuccessfulSmartServerResponse((repo_path, rich_root,
360
            tree_ref, external_lookup, repo_network_name,
361
            repo_bzrdir_network_name, bzrdir_format_network_name,
362
            NoneTrueFalse(stacking), final_stack, final_stack_pwd,
363
            repo_lock_token))
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
364
        """
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
365
        target_transport = self.transport_from_client_path(path)
366
        format = network_format_registry.get(bzrdir_network_name)
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
367
        use_existing_dir = self.parse_NoneTrueFalse(use_existing_dir)
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
368
        create_prefix = self.parse_NoneTrueFalse(create_prefix)
369
        force_new_repo = self.parse_NoneTrueFalse(force_new_repo)
370
        stacked_on = self.parse_NoneString(stacked_on)
371
        stack_on_pwd = self.parse_NoneString(stack_on_pwd)
372
        make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
373
        shared_repo = self.parse_NoneTrueFalse(shared_repo)
374
        if stack_on_pwd == '.':
375
            stack_on_pwd = target_transport.base
376
        repo_format_name = self.parse_NoneString(repo_format_name)
377
        repo, bzrdir, stacking, repository_policy = \
378
            format.initialize_on_transport_ex(target_transport,
379
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
380
            force_new_repo=force_new_repo, stacked_on=stacked_on,
381
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
382
            make_working_trees=make_working_trees, shared_repo=shared_repo)
383
        if repo is None:
384
            repo_path = ''
385
            repo_name = ''
386
            rich_root = tree_ref = external_lookup = ''
387
            repo_bzrdir_name = ''
388
            final_stack = None
389
            final_stack_pwd = None
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
390
            repo_lock_token = ''
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
391
        else:
392
            repo_path = self._repo_relpath(bzrdir.root_transport, repo)
393
            if repo_path == '':
394
                repo_path = '.'
395
            rich_root, tree_ref, external_lookup = self._format_to_capabilities(
396
                repo._format)
397
            repo_name = repo._format.network_name()
398
            repo_bzrdir_name = repo.bzrdir._format.network_name()
399
            final_stack = repository_policy._stack_on
400
            final_stack_pwd = repository_policy._stack_on_pwd
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
401
            # It is returned locked, but we need to do the lock to get the lock
402
            # token.
403
            repo.unlock()
404
            repo_lock_token = repo.lock_write() or ''
405
            if repo_lock_token:
406
                repo.leave_lock_in_place()
407
            repo.unlock()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
408
        final_stack = final_stack or ''
409
        final_stack_pwd = final_stack_pwd or ''
410
        return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
411
            external_lookup, repo_name, repo_bzrdir_name,
412
            bzrdir._format.network_name(),
413
            self._serialize_NoneTrueFalse(stacking), final_stack,
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
414
            final_stack_pwd, repo_lock_token))
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
415
416
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.
417
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
418
419
    def do_bzrdir_request(self):
420
        """open a branch at path and return the branch reference or branch."""
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
421
        try:
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.
422
            reference_url = self._bzrdir.get_branch_reference()
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
423
            if reference_url is None:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
424
                return SuccessfulSmartServerResponse(('ok', ''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
425
            else:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
426
                return SuccessfulSmartServerResponse(('ok', reference_url))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
427
        except errors.NotBranchError:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
428
            return FailedSmartServerResponse(('nobranch', ))
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.
429
430
431
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
432
433
    def do_bzrdir_request(self):
434
        """open a branch at path and return the reference or format."""
435
        try:
436
            reference_url = self._bzrdir.get_branch_reference()
437
            if reference_url is None:
4160.2.6 by Andrew Bennetts
Add ignore_fallbacks flag.
438
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
439
                format = br._format.network_name()
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.
440
                return SuccessfulSmartServerResponse(('branch', format))
441
            else:
442
                return SuccessfulSmartServerResponse(('ref', reference_url))
443
        except errors.NotBranchError:
444
            return FailedSmartServerResponse(('nobranch', ))