/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bzr/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2018-05-06 11:48:54 UTC
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@jelmer.uk-20180506114854-h4qd9ojaqy8wxjsd
Move .mailmap to root.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
from ..lazy_import import lazy_import
33
33
lazy_import(globals(), """
 
34
import breezy
34
35
from breezy import (
35
36
    branch as _mod_branch,
36
37
    cleanup,
 
38
    fetch,
 
39
    graph,
37
40
    lockable_files,
38
41
    lockdir,
39
42
    osutils,
 
43
    pyutils,
40
44
    repository,
41
45
    revision as _mod_revision,
42
46
    transport as _mod_transport,
46
50
    )
47
51
from breezy.bzr import (
48
52
    branch as _mod_bzrbranch,
49
 
    fetch,
50
53
    remote,
51
54
    vf_search,
52
55
    workingtree_3,
61
64
from breezy.i18n import gettext
62
65
""")
63
66
 
64
 
from ..sixish import viewitems
65
67
from ..trace import (
66
68
    mutter,
67
69
    note,
68
 
    warning,
69
70
    )
70
71
 
71
72
from .. import (
72
73
    config,
73
74
    controldir,
74
75
    errors,
 
76
    registry,
75
77
    )
76
78
 
77
79
 
131
133
 
132
134
    def check_conversion_target(self, target_format):
133
135
        """Check that a bzrdir as a whole can be converted to a new format."""
134
 
        # The only current restriction is that the repository content can be
 
136
        # The only current restriction is that the repository content can be 
135
137
        # fetched compatibly with the target.
136
138
        target_repo_format = target_format.repository_format
137
139
        try:
142
144
            pass
143
145
 
144
146
    def clone_on_transport(self, transport, revision_id=None,
145
 
                           force_new_repo=False, preserve_stacking=False, stacked_on=None,
146
 
                           create_prefix=False, use_existing_dir=True, no_tree=False,
147
 
                           tag_selector=None):
 
147
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
148
        create_prefix=False, use_existing_dir=True, no_tree=False):
148
149
        """Clone this bzrdir and its contents to transport verbatim.
149
150
 
150
151
        :param transport: The transport for the location to produce the clone
174
175
            local_repo = self.find_repository()
175
176
        except errors.NoRepositoryPresent:
176
177
            local_repo = None
177
 
        local_branches = self.get_branches()
178
178
        try:
179
 
            local_active_branch = local_branches['']
180
 
        except KeyError:
181
 
            pass
 
179
            local_branch = self.open_branch()
 
180
        except errors.NotBranchError:
 
181
            local_branch = None
182
182
        else:
183
183
            # enable fallbacks when branch is not a branch reference
184
 
            if local_active_branch.repository.has_same_location(local_repo):
185
 
                local_repo = local_active_branch.repository
 
184
            if local_branch.repository.has_same_location(local_repo):
 
185
                local_repo = local_branch.repository
186
186
            if preserve_stacking:
187
187
                try:
188
 
                    stacked_on = local_active_branch.get_stacked_on_url()
 
188
                    stacked_on = local_branch.get_stacked_on_url()
189
189
                except (_mod_branch.UnstackableBranchFormat,
190
190
                        errors.UnstackableRepositoryFormat,
191
191
                        errors.NotStacked):
194
194
        # we should look up the policy needs first, or just use it as a hint,
195
195
        # or something.
196
196
        if local_repo:
197
 
            make_working_trees = (local_repo.make_working_trees() and
198
 
                                  not no_tree)
 
197
            make_working_trees = local_repo.make_working_trees() and not no_tree
199
198
            want_shared = local_repo.is_shared()
200
199
            repo_format_name = format.repository_format.network_name()
201
200
        else:
204
203
            repo_format_name = None
205
204
 
206
205
        result_repo, result, require_stacking, repository_policy = \
207
 
            format.initialize_on_transport_ex(
208
 
                transport, use_existing_dir=use_existing_dir,
209
 
                create_prefix=create_prefix, force_new_repo=force_new_repo,
210
 
                stacked_on=stacked_on, stack_on_pwd=self.root_transport.base,
211
 
                repo_format_name=repo_format_name,
212
 
                make_working_trees=make_working_trees, shared_repo=want_shared)
 
206
            format.initialize_on_transport_ex(transport,
 
207
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
208
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
209
            stack_on_pwd=self.root_transport.base,
 
210
            repo_format_name=repo_format_name,
 
211
            make_working_trees=make_working_trees, shared_repo=want_shared)
213
212
        if repo_format_name:
214
213
            try:
215
214
                # If the result repository is in the same place as the
219
218
                # revision_id then we can use the pending-ancestry-result which
220
219
                # does not require traversing all of history to describe it.
221
220
                if (result_repo.user_url == result.user_url
222
 
                    and not require_stacking
223
 
                        and revision_id is not None):
 
221
                    and not require_stacking and
 
222
                    revision_id is not None):
224
223
                    fetch_spec = vf_search.PendingAncestryResult(
225
224
                        [revision_id], local_repo)
226
225
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
234
233
        # 1 if there is a branch present
235
234
        #   make sure its content is available in the target repository
236
235
        #   clone it.
237
 
        for name, local_branch in local_branches.items():
238
 
            local_branch.clone(
239
 
                result, revision_id=(None if name != '' else revision_id),
240
 
                repository_policy=repository_policy,
241
 
                name=name, tag_selector=tag_selector)
 
236
        if local_branch is not None:
 
237
            result_branch = local_branch.clone(result, revision_id=revision_id,
 
238
                repository_policy=repository_policy)
242
239
        try:
243
240
            # Cheaper to check if the target is not local, than to try making
244
241
            # the tree and fail.
285
282
            except errors.NoRepositoryPresent:
286
283
                repository = None
287
284
            else:
288
 
                if (found_bzrdir.user_url != self.user_url and
289
 
                        not repository.is_shared()):
 
285
                if (found_bzrdir.user_url != self.user_url 
 
286
                    and not repository.is_shared()):
290
287
                    # Don't look higher, can't use a higher shared repo.
291
288
                    repository = None
292
289
                    stop = True
295
292
            if not stop:
296
293
                return None, False
297
294
            if repository:
298
 
                return UseExistingRepository(
299
 
                    repository, stack_on, stack_on_pwd,
300
 
                    require_stacking=require_stacking), True
 
295
                return UseExistingRepository(repository, stack_on,
 
296
                    stack_on_pwd, require_stacking=require_stacking), True
301
297
            else:
302
 
                return CreateRepository(
303
 
                    self, stack_on, stack_on_pwd,
 
298
                return CreateRepository(self, stack_on, stack_on_pwd,
304
299
                    require_stacking=require_stacking), True
305
300
 
306
301
        if not force_new_repo:
311
306
            else:
312
307
                try:
313
308
                    return UseExistingRepository(
314
 
                        self.open_repository(), stack_on, stack_on_pwd,
315
 
                        require_stacking=require_stacking)
 
309
                            self.open_repository(), stack_on, stack_on_pwd,
 
310
                            require_stacking=require_stacking)
316
311
                except errors.NoRepositoryPresent:
317
312
                    pass
318
313
        return CreateRepository(self, stack_on, stack_on_pwd,
323
318
        policy = self.determine_repository_policy(force_new_repo)
324
319
        return policy.acquire_repository()[0]
325
320
 
326
 
    def _find_source_repo(self, exit_stack, source_branch):
 
321
    def _find_source_repo(self, add_cleanup, source_branch):
327
322
        """Find the source branch and repo for a sprout operation.
328
 
 
 
323
        
329
324
        This is helper intended for use by _sprout.
330
325
 
331
326
        :returns: (source_branch, source_repository).  Either or both may be
332
327
            None.  If not None, they will be read-locked (and their unlock(s)
333
 
            scheduled via the exit_stack param).
 
328
            scheduled via the add_cleanup param).
334
329
        """
335
330
        if source_branch is not None:
336
 
            exit_stack.enter_context(source_branch.lock_read())
 
331
            add_cleanup(source_branch.lock_read().unlock)
337
332
            return source_branch, source_branch.repository
338
333
        try:
339
334
            source_branch = self.open_branch()
345
340
            except errors.NoRepositoryPresent:
346
341
                source_repository = None
347
342
            else:
348
 
                exit_stack.enter_context(source_repository.lock_read())
 
343
                add_cleanup(source_repository.lock_read().unlock)
349
344
        else:
350
 
            exit_stack.enter_context(source_branch.lock_read())
 
345
            add_cleanup(source_branch.lock_read().unlock)
351
346
        return source_branch, source_repository
352
347
 
353
348
    def sprout(self, url, revision_id=None, force_new_repo=False,
380
375
            when working locally.
381
376
        :return: The created control directory
382
377
        """
383
 
        with cleanup.ExitStack() as stack:
384
 
            fetch_spec_factory = fetch.FetchSpecFactory()
385
 
            if revision_id is not None:
386
 
                fetch_spec_factory.add_revision_ids([revision_id])
387
 
                fetch_spec_factory.source_branch_stop_revision_id = revision_id
388
 
            if possible_transports is None:
389
 
                possible_transports = []
390
 
            else:
391
 
                possible_transports = list(possible_transports) + [
392
 
                    self.root_transport]
393
 
            target_transport = _mod_transport.get_transport(url,
394
 
                                                            possible_transports)
395
 
            target_transport.ensure_base()
396
 
            cloning_format = self.cloning_metadir(stacked)
397
 
            # Create/update the result branch
 
378
        operation = cleanup.OperationWithCleanups(self._sprout)
 
379
        return operation.run(url, revision_id=revision_id,
 
380
            force_new_repo=force_new_repo, recurse=recurse,
 
381
            possible_transports=possible_transports,
 
382
            accelerator_tree=accelerator_tree, hardlink=hardlink,
 
383
            stacked=stacked, source_branch=source_branch,
 
384
            create_tree_if_local=create_tree_if_local)
 
385
 
 
386
    def _sprout(self, op, url, revision_id=None, force_new_repo=False,
 
387
               recurse='down', possible_transports=None,
 
388
               accelerator_tree=None, hardlink=False, stacked=False,
 
389
               source_branch=None, create_tree_if_local=True, lossy=False):
 
390
        add_cleanup = op.add_cleanup
 
391
        fetch_spec_factory = fetch.FetchSpecFactory()
 
392
        if revision_id is not None:
 
393
            fetch_spec_factory.add_revision_ids([revision_id])
 
394
            fetch_spec_factory.source_branch_stop_revision_id = revision_id
 
395
        if possible_transports is None:
 
396
            possible_transports = []
 
397
        else:
 
398
            possible_transports = list(possible_transports) + [
 
399
                self.root_transport]
 
400
        target_transport = _mod_transport.get_transport(url,
 
401
            possible_transports)
 
402
        target_transport.ensure_base()
 
403
        cloning_format = self.cloning_metadir(stacked)
 
404
        # Create/update the result branch
 
405
        try:
 
406
            result = controldir.ControlDir.open_from_transport(target_transport)
 
407
        except errors.NotBranchError:
 
408
            result = cloning_format.initialize_on_transport(target_transport)
 
409
        source_branch, source_repository = self._find_source_repo(
 
410
            add_cleanup, source_branch)
 
411
        fetch_spec_factory.source_branch = source_branch
 
412
        # if a stacked branch wasn't requested, we don't create one
 
413
        # even if the origin was stacked
 
414
        if stacked and source_branch is not None:
 
415
            stacked_branch_url = self.root_transport.base
 
416
        else:
 
417
            stacked_branch_url = None
 
418
        repository_policy = result.determine_repository_policy(
 
419
            force_new_repo, stacked_branch_url, require_stacking=stacked)
 
420
        result_repo, is_new_repo = repository_policy.acquire_repository(
 
421
            possible_transports=possible_transports)
 
422
        add_cleanup(result_repo.lock_write().unlock)
 
423
        fetch_spec_factory.source_repo = source_repository
 
424
        fetch_spec_factory.target_repo = result_repo
 
425
        if stacked or (len(result_repo._fallback_repositories) != 0):
 
426
            target_repo_kind = fetch.TargetRepoKinds.STACKED
 
427
        elif is_new_repo:
 
428
            target_repo_kind = fetch.TargetRepoKinds.EMPTY
 
429
        else:
 
430
            target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
 
431
        fetch_spec_factory.target_repo_kind = target_repo_kind
 
432
        if source_repository is not None:
 
433
            fetch_spec = fetch_spec_factory.make_fetch_spec()
 
434
            result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
435
 
 
436
        if source_branch is None:
 
437
            # this is for sprouting a controldir without a branch; is that
 
438
            # actually useful?
 
439
            # Not especially, but it's part of the contract.
 
440
            result_branch = result.create_branch()
 
441
        else:
 
442
            result_branch = source_branch.sprout(result,
 
443
                revision_id=revision_id, repository_policy=repository_policy,
 
444
                repository=result_repo)
 
445
        mutter("created new branch %r" % (result_branch,))
 
446
 
 
447
        # Create/update the result working tree
 
448
        if (create_tree_if_local and not result.has_workingtree() and
 
449
            isinstance(target_transport, local.LocalTransport) and
 
450
            (result_repo is None or result_repo.make_working_trees())):
 
451
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
 
452
                hardlink=hardlink, from_branch=result_branch)
 
453
            wt.lock_write()
398
454
            try:
399
 
                result = controldir.ControlDir.open_from_transport(
400
 
                    target_transport)
401
 
            except errors.NotBranchError:
402
 
                result = cloning_format.initialize_on_transport(target_transport)
403
 
            source_branch, source_repository = self._find_source_repo(
404
 
                stack, source_branch)
405
 
            fetch_spec_factory.source_branch = source_branch
406
 
            # if a stacked branch wasn't requested, we don't create one
407
 
            # even if the origin was stacked
408
 
            if stacked and source_branch is not None:
409
 
                stacked_branch_url = self.root_transport.base
410
 
            else:
411
 
                stacked_branch_url = None
412
 
            repository_policy = result.determine_repository_policy(
413
 
                force_new_repo, stacked_branch_url, require_stacking=stacked)
414
 
            result_repo, is_new_repo = repository_policy.acquire_repository(
415
 
                possible_transports=possible_transports)
416
 
            stack.enter_context(result_repo.lock_write())
417
 
            fetch_spec_factory.source_repo = source_repository
418
 
            fetch_spec_factory.target_repo = result_repo
419
 
            if stacked or (len(result_repo._fallback_repositories) != 0):
420
 
                target_repo_kind = fetch.TargetRepoKinds.STACKED
421
 
            elif is_new_repo:
422
 
                target_repo_kind = fetch.TargetRepoKinds.EMPTY
423
 
            else:
424
 
                target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
425
 
            fetch_spec_factory.target_repo_kind = target_repo_kind
426
 
            if source_repository is not None:
427
 
                fetch_spec = fetch_spec_factory.make_fetch_spec()
428
 
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
429
 
 
430
 
            if source_branch is None:
431
 
                # this is for sprouting a controldir without a branch; is that
432
 
                # actually useful?
433
 
                # Not especially, but it's part of the contract.
434
 
                result_branch = result.create_branch()
435
 
            else:
436
 
                result_branch = source_branch.sprout(
437
 
                    result, revision_id=revision_id,
438
 
                    repository_policy=repository_policy, repository=result_repo)
439
 
            mutter("created new branch %r" % (result_branch,))
440
 
 
441
 
            # Create/update the result working tree
442
 
            if (create_tree_if_local and not result.has_workingtree()
443
 
                    and isinstance(target_transport, local.LocalTransport)
444
 
                    and (result_repo is None or result_repo.make_working_trees())
445
 
                    and result.open_branch(
446
 
                        name="",
447
 
                        possible_transports=possible_transports).name == result_branch.name):
448
 
                wt = result.create_workingtree(
449
 
                    accelerator_tree=accelerator_tree, hardlink=hardlink,
450
 
                    from_branch=result_branch)
451
 
                with wt.lock_write():
452
 
                    if not wt.is_versioned(''):
453
 
                        try:
454
 
                            wt.set_root_id(self.open_workingtree.path2id(''))
455
 
                        except errors.NoWorkingTree:
456
 
                            pass
457
 
            else:
458
 
                wt = None
459
 
            if recurse == 'down':
460
 
                tree = None
461
 
                if wt is not None:
462
 
                    tree = wt
463
 
                    basis = tree.basis_tree()
464
 
                    stack.enter_context(basis.lock_read())
465
 
                elif result_branch is not None:
466
 
                    basis = tree = result_branch.basis_tree()
467
 
                elif source_branch is not None:
468
 
                    basis = tree = source_branch.basis_tree()
469
 
                if tree is not None:
470
 
                    stack.enter_context(tree.lock_read())
471
 
                    subtrees = tree.iter_references()
472
 
                else:
473
 
                    subtrees = []
474
 
                for path in subtrees:
475
 
                    target = urlutils.join(url, urlutils.escape(path))
476
 
                    sublocation = tree.reference_parent(
477
 
                        path, branch=result_branch,
478
 
                        possible_transports=possible_transports)
479
 
                    if sublocation is None:
480
 
                        warning(
481
 
                            'Ignoring nested tree %s, parent location unknown.',
482
 
                            path)
483
 
                        continue
484
 
                    sublocation.controldir.sprout(
485
 
                        target, basis.get_reference_revision(path),
486
 
                        force_new_repo=force_new_repo, recurse=recurse,
487
 
                        stacked=stacked)
488
 
            return result
 
455
                if not wt.is_versioned(''):
 
456
                    try:
 
457
                        wt.set_root_id(self.open_workingtree.get_root_id())
 
458
                    except errors.NoWorkingTree:
 
459
                        pass
 
460
            finally:
 
461
                wt.unlock()
 
462
        else:
 
463
            wt = None
 
464
        if recurse == 'down':
 
465
            basis = None
 
466
            if wt is not None:
 
467
                basis = wt.basis_tree()
 
468
            elif result_branch is not None:
 
469
                basis = result_branch.basis_tree()
 
470
            elif source_branch is not None:
 
471
                basis = source_branch.basis_tree()
 
472
            if basis is not None:
 
473
                add_cleanup(basis.lock_read().unlock)
 
474
                subtrees = basis.iter_references()
 
475
            else:
 
476
                subtrees = []
 
477
            for path, file_id in subtrees:
 
478
                target = urlutils.join(url, urlutils.escape(path))
 
479
                sublocation = source_branch.reference_parent(path, file_id)
 
480
                sublocation.controldir.sprout(target,
 
481
                    basis.get_reference_revision(path, file_id),
 
482
                    force_new_repo=force_new_repo, recurse=recurse,
 
483
                    stacked=stacked)
 
484
        return result
489
485
 
490
486
    def _available_backup_name(self, base):
491
487
        """Find a non-existing backup file name based on base.
500
496
        :return: Tuple with old path name and new path name
501
497
        """
502
498
 
503
 
        with ui.ui_factory.nested_progress_bar():
 
499
        with ui.ui_factory.nested_progress_bar() as pb:
504
500
            old_path = self.root_transport.abspath('.bzr')
505
501
            backup_dir = self._available_backup_name('backup.bzr')
506
502
            new_path = self.root_transport.abspath(backup_dir)
507
 
            ui.ui_factory.note(
508
 
                gettext('making backup of {0}\n  to {1}').format(
509
 
                    urlutils.unescape_for_display(old_path, 'utf-8'),
510
 
                    urlutils.unescape_for_display(new_path, 'utf-8')))
 
503
            ui.ui_factory.note(gettext('making backup of {0}\n  to {1}').format(
 
504
                urlutils.unescape_for_display(old_path, 'utf-8'),
 
505
                urlutils.unescape_for_display(new_path, 'utf-8')))
511
506
            self.root_transport.copy_tree('.bzr', backup_dir)
512
507
            return (old_path, new_path)
513
508
 
521
516
        in use.
522
517
        :param limit: number of times to retry
523
518
        """
524
 
        i = 0
 
519
        i  = 0
525
520
        while True:
526
521
            try:
527
522
                to_path = '.bzr.retired.%d' % i
652
647
        :param _transport: the transport this dir is based at.
653
648
        """
654
649
        self._format = _format
655
 
        # these are also under the more standard names of
 
650
        # these are also under the more standard names of 
656
651
        # control_transport and user_transport
657
652
        self.transport = _transport.clone('.bzr')
658
653
        self.root_transport = _transport
659
654
        self._mode_check_done = False
660
655
 
661
 
    @property
 
656
    @property 
662
657
    def user_transport(self):
663
658
        return self.root_transport
664
659
 
666
661
    def control_transport(self):
667
662
        return self.transport
668
663
 
 
664
    def is_control_filename(self, filename):
 
665
        """True if filename is the name of a path which is reserved for bzrdir's.
 
666
 
 
667
        :param filename: A filename within the root transport of this bzrdir.
 
668
 
 
669
        This is true IF and ONLY IF the filename is part of the namespace reserved
 
670
        for bzr control dirs. Currently this is the '.bzr' directory in the root
 
671
        of the root_transport. 
 
672
        """
 
673
        # this might be better on the BzrDirFormat class because it refers to
 
674
        # all the possible bzrdir disk formats.
 
675
        # This method is tested via the workingtree is_control_filename tests-
 
676
        # it was extracted from WorkingTree.is_control_filename. If the method's
 
677
        # contract is extended beyond the current trivial implementation, please
 
678
        # add new tests for it to the appropriate place.
 
679
        return filename == '.bzr' or filename.startswith('.bzr/')
 
680
 
669
681
    def _cloning_metadir(self):
670
682
        """Produce a metadir suitable for cloning with.
671
683
 
678
690
                source_repository = branch.repository
679
691
                result_format._branch_format = branch._format
680
692
            except errors.NotBranchError:
 
693
                source_branch = None
681
694
                source_repository = self.open_repository()
682
695
        except errors.NoRepositoryPresent:
683
696
            source_repository = None
722
735
                return format
723
736
            # We have a repository, so set a working tree? (Why? This seems to
724
737
            # contradict the stated return value in the docstring).
725
 
            tree_format = (
726
 
                repository._format._matchingcontroldir.workingtree_format)
 
738
            tree_format = repository._format._matchingcontroldir.workingtree_format
727
739
            format.workingtree_format = tree_format.__class__()
728
740
        if require_stacking:
729
741
            format.require_stacking()
779
791
        """
780
792
        if cls is not BzrDir:
781
793
            raise AssertionError("BzrDir.create always creates the "
782
 
                                 "default format, not one of %r" % cls)
783
 
        return controldir.ControlDir.create(
784
 
            base, format=format, possible_transports=possible_transports)
 
794
                "default format, not one of %r" % cls)
 
795
        return controldir.ControlDir.create(base, format=format,
 
796
                possible_transports=possible_transports)
785
797
 
786
798
    def __repr__(self):
787
799
        return "<%s at %r>" % (self.__class__.__name__, self.user_url)
821
833
        """
822
834
        if name == "":
823
835
            return 'branch'
824
 
        return urlutils.join('branches', urlutils.escape(name))
 
836
        return urlutils.join('branches', name.encode("utf-8"))
825
837
 
826
838
    def _read_branch_list(self):
827
839
        """Read the branch list.
828
840
 
829
 
        :return: List of branch names.
 
841
        :return: List of utf-8 encoded branch names.
830
842
        """
831
843
        try:
832
844
            f = self.control_transport.get('branch-list')
836
848
        ret = []
837
849
        try:
838
850
            for name in f:
839
 
                ret.append(name.rstrip(b"\n").decode('utf-8'))
 
851
                ret.append(name.rstrip(b"\n"))
840
852
        finally:
841
853
            f.close()
842
854
        return ret
846
858
 
847
859
        :param branches: List of utf-8 branch names to write
848
860
        """
849
 
        self.transport.put_bytes(
850
 
            'branch-list',
851
 
            b"".join([name.encode('utf-8') + b"\n" for name in branches]))
 
861
        self.transport.put_bytes('branch-list',
 
862
            "".join([name+"\n" for name in branches]))
852
863
 
853
864
    def __init__(self, _transport, _format):
854
865
        super(BzrDirMeta1, self).__init__(_transport, _format)
861
872
        return True
862
873
 
863
874
    def create_branch(self, name=None, repository=None,
864
 
                      append_revisions_only=None):
 
875
            append_revisions_only=None):
865
876
        """See ControlDir.create_branch."""
866
877
        if name is None:
867
878
            name = self._get_selected_branch()
868
 
        return self._format.get_branch_format().initialize(
869
 
            self, name=name, repository=repository,
870
 
            append_revisions_only=append_revisions_only)
 
879
        return self._format.get_branch_format().initialize(self, name=name,
 
880
                repository=repository,
 
881
                append_revisions_only=append_revisions_only)
871
882
 
872
883
    def destroy_branch(self, name=None):
873
884
        """See ControlDir.destroy_branch."""
874
885
        if name is None:
875
886
            name = self._get_selected_branch()
876
887
        path = self._get_branch_path(name)
877
 
        if name != u"":
 
888
        if name != "":
878
889
            self.control_files.lock_write()
879
890
            try:
880
891
                branches = self._read_branch_list()
881
892
                try:
882
 
                    branches.remove(name)
 
893
                    branches.remove(name.encode("utf-8"))
883
894
                except ValueError:
884
895
                    raise errors.NotBranchError(name)
885
896
                self._write_branch_list(branches)
888
899
        try:
889
900
            self.transport.delete_tree(path)
890
901
        except errors.NoSuchFile:
891
 
            raise errors.NotBranchError(
892
 
                path=urlutils.join(self.transport.base, path), controldir=self)
 
902
            raise errors.NotBranchError(path=urlutils.join(self.transport.base,
 
903
                path), controldir=self)
893
904
 
894
905
    def create_repository(self, shared=False):
895
906
        """See BzrDir.create_repository."""
917
928
        # We ignore the conflicts returned by wt.revert since we're about to
918
929
        # delete the wt metadata anyway, all that should be left here are
919
930
        # detritus. But see bug #634470 about subtree .bzr dirs.
920
 
        wt.revert(old_tree=empty)
 
931
        conflicts = wt.revert(old_tree=empty)
921
932
        self.destroy_workingtree_metadata()
922
933
 
923
934
    def destroy_workingtree_metadata(self):
933
944
 
934
945
    def _get_mkdir_mode(self):
935
946
        """Figure out the mode to use when creating a bzrdir subdir."""
936
 
        temp_control = lockable_files.LockableFiles(
937
 
            self.transport, '', lockable_files.TransportLock)
 
947
        temp_control = lockable_files.LockableFiles(self.transport, '',
 
948
                                     lockable_files.TransportLock)
938
949
        return temp_control._dir_mode
939
950
 
940
951
    def get_branch_reference(self, name=None):
945
956
 
946
957
    def set_branch_reference(self, target_branch, name=None):
947
958
        format = _mod_bzrbranch.BranchReferenceFormat()
948
 
        if (self.control_url == target_branch.controldir.control_url
949
 
                and name == target_branch.name):
 
959
        if (self.control_url == target_branch.controldir.control_url and
 
960
            name == target_branch.name):
950
961
            raise controldir.BranchReferenceLoop(target_branch)
951
962
        return format.initialize(self, target_branch=target_branch, name=name)
952
963
 
965
976
            raise errors.IncompatibleFormat(branch_format, self._format)
966
977
        if name != "":
967
978
            branches = self._read_branch_list()
968
 
            if name not in branches:
 
979
            utf8_name = name.encode("utf-8")
 
980
            if not utf8_name in branches:
969
981
                self.control_files.lock_write()
970
982
                try:
971
983
                    branches = self._read_branch_list()
972
 
                    dirname = urlutils.dirname(name)
973
 
                    if dirname != u"" and dirname in branches:
 
984
                    dirname = urlutils.dirname(utf8_name)
 
985
                    if dirname != "" and dirname in branches:
974
986
                        raise errors.ParentBranchExists(name)
975
987
                    child_branches = [
976
 
                        b.startswith(name + u"/") for b in branches]
 
988
                        b.startswith(utf8_name+"/") for b in branches]
977
989
                    if any(child_branches):
978
990
                        raise errors.AlreadyBranchError(name)
979
 
                    branches.append(name)
 
991
                    branches.append(utf8_name)
980
992
                    self._write_branch_list(branches)
981
993
                finally:
982
994
                    self.control_files.unlock()
1017
1029
            pass
1018
1030
        return self.transport.clone('checkout')
1019
1031
 
1020
 
    def branch_names(self):
1021
 
        """See ControlDir.branch_names."""
1022
 
        ret = []
1023
 
        try:
1024
 
            self.get_branch_reference()
1025
 
        except errors.NotBranchError:
1026
 
            pass
1027
 
        else:
1028
 
            ret.append("")
1029
 
        ret.extend(self._read_branch_list())
1030
 
        return ret
1031
 
 
1032
1032
    def get_branches(self):
1033
1033
        """See ControlDir.get_branches."""
1034
1034
        ret = {}
1038
1038
            pass
1039
1039
 
1040
1040
        for name in self._read_branch_list():
1041
 
            ret[name] = self.open_branch(name=name)
 
1041
            ret[name] = self.open_branch(name=name.decode('utf-8'))
1042
1042
 
1043
1043
        return ret
1044
1044
 
1057
1057
 
1058
1058
    def needs_format_conversion(self, format):
1059
1059
        """See BzrDir.needs_format_conversion()."""
1060
 
        if (not isinstance(self._format, format.__class__)
1061
 
                or self._format.get_format_string() != format.get_format_string()):
 
1060
        if (not isinstance(self._format, format.__class__) or
 
1061
            self._format.get_format_string() != format.get_format_string()):
1062
1062
            # it is not a meta dir format, conversion is needed.
1063
1063
            return True
1064
1064
        # we might want to push this down to the repository?
1091
1091
            name = self._get_selected_branch()
1092
1092
        format = self.find_branch_format(name=name)
1093
1093
        format.check_support_status(unsupported)
1094
 
        if possible_transports is None:
1095
 
            possible_transports = []
1096
 
        else:
1097
 
            possible_transports = list(possible_transports)
1098
 
        possible_transports.append(self.root_transport)
1099
1094
        return format.open(self, name=name,
1100
 
                           _found=True, ignore_fallbacks=ignore_fallbacks,
1101
 
                           possible_transports=possible_transports)
 
1095
            _found=True, ignore_fallbacks=ignore_fallbacks,
 
1096
            possible_transports=possible_transports)
1102
1097
 
1103
1098
    def open_repository(self, unsupported=False):
1104
1099
        """See BzrDir.open_repository."""
1108
1103
        return format.open(self, _found=True)
1109
1104
 
1110
1105
    def open_workingtree(self, unsupported=False,
1111
 
                         recommend_upgrade=True):
 
1106
            recommend_upgrade=True):
1112
1107
        """See BzrDir.open_workingtree."""
1113
1108
        from .workingtree import WorkingTreeFormatMetaDir
1114
1109
        format = WorkingTreeFormatMetaDir.find_format(self)
1115
1110
        format.check_support_status(unsupported, recommend_upgrade,
1116
 
                                    basedir=self.root_transport.base)
 
1111
            basedir=self.root_transport.base)
1117
1112
        return format.open(self, _found=True)
1118
1113
 
1119
1114
    def _get_config(self):
1165
1160
        cls._present_features.remove(name)
1166
1161
 
1167
1162
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1168
 
                             basedir=None):
1169
 
        for name, necessity in viewitems(self.features):
 
1163
            basedir=None):
 
1164
        for name, necessity in self.features.items():
1170
1165
            if name in self._present_features:
1171
1166
                continue
1172
1167
            if necessity == b"optional":
1188
1183
    def from_string(cls, text):
1189
1184
        format_string = cls.get_format_string()
1190
1185
        if not text.startswith(format_string):
1191
 
            raise AssertionError(
1192
 
                "Invalid format header %r for %r" % (text, cls))
 
1186
            raise AssertionError("Invalid format header %r for %r" % (text, cls))
1193
1187
        lines = text[len(format_string):].splitlines()
1194
1188
        ret = cls()
1195
1189
        for lineno, line in enumerate(lines):
1196
1190
            try:
1197
1191
                (necessity, feature) = line.split(b" ", 1)
1198
1192
            except ValueError:
1199
 
                raise errors.ParseFormatError(format=cls, lineno=lineno + 2,
1200
 
                                              line=line, text=text)
 
1193
                raise errors.ParseFormatError(format=cls, lineno=lineno+2,
 
1194
                    line=line, text=text)
1201
1195
            ret.features[feature] = necessity
1202
1196
        return ret
1203
1197
 
1206
1200
        """
1207
1201
        lines = [self.get_format_string()]
1208
1202
        lines.extend([(item[1] + b" " + item[0] + b"\n")
1209
 
                      for item in sorted(viewitems(self.features))])
 
1203
                      for item in self.features.items()])
1210
1204
        return b"".join(lines)
1211
1205
 
1212
1206
    @classmethod
1213
1207
    def _find_format(klass, registry, kind, format_string):
1214
1208
        try:
1215
 
            first_line = format_string[:format_string.index(b"\n") + 1]
 
1209
            first_line = format_string[:format_string.index(b"\n")+1]
1216
1210
        except ValueError:
1217
1211
            first_line = format_string
1218
1212
        try:
1229
1223
        return self.as_string()
1230
1224
 
1231
1225
    def __eq__(self, other):
1232
 
        return (self.__class__ is other.__class__
1233
 
                and self.features == other.features)
 
1226
        return (self.__class__ is other.__class__ and
 
1227
                self.features == other.features)
1234
1228
 
1235
1229
    def _update_feature_flags(self, updated_flags):
1236
1230
        """Update the feature flags in this format.
1284
1278
            return remote_format.initialize_on_transport(transport)
1285
1279
 
1286
1280
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1287
 
                                   create_prefix=False, force_new_repo=False, stacked_on=None,
1288
 
                                   stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1289
 
                                   shared_repo=False, vfs_only=False):
 
1281
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
1282
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
1283
        shared_repo=False, vfs_only=False):
1290
1284
        """Create this format on transport.
1291
1285
 
1292
1286
        The directory to initialize will be created.
1316
1310
            parameter and any stacking policy found for the target.
1317
1311
        """
1318
1312
        if not vfs_only:
1319
 
            # Try to hand off to a smart server
 
1313
            # Try to hand off to a smart server 
1320
1314
            try:
1321
1315
                client_medium = transport.get_smart_medium()
1322
1316
            except errors.NoSmartMedium:
1327
1321
                remote_dir_format = RemoteBzrDirFormat()
1328
1322
                remote_dir_format._network_name = self.network_name()
1329
1323
                self._supply_sub_formats_to(remote_dir_format)
1330
 
                return remote_dir_format.initialize_on_transport_ex(
1331
 
                    transport, use_existing_dir=use_existing_dir,
1332
 
                    create_prefix=create_prefix, force_new_repo=force_new_repo,
1333
 
                    stacked_on=stacked_on, stack_on_pwd=stack_on_pwd,
1334
 
                    repo_format_name=repo_format_name,
1335
 
                    make_working_trees=make_working_trees,
1336
 
                    shared_repo=shared_repo)
 
1324
                return remote_dir_format.initialize_on_transport_ex(transport,
 
1325
                    use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
1326
                    force_new_repo=force_new_repo, stacked_on=stacked_on,
 
1327
                    stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
1328
                    make_working_trees=make_working_trees, shared_repo=shared_repo)
1337
1329
        # XXX: Refactor the create_prefix/no_create_prefix code into a
1338
1330
        #      common helper function
1339
1331
        # The destination may not exist - if so make it according to policy.
1340
 
 
1341
1332
        def make_directory(transport):
1342
1333
            transport.mkdir('.')
1343
1334
            return transport
1344
 
 
1345
1335
        def redirected(transport, e, redirection_notice):
1346
1336
            note(redirection_notice)
1347
1337
            return transport._redirected_to(e.source, e.target)
1348
1338
        try:
1349
1339
            transport = do_catching_redirections(make_directory, transport,
1350
 
                                                 redirected)
 
1340
                redirected)
1351
1341
        except errors.FileExists:
1352
1342
            if not use_existing_dir:
1353
1343
                raise
1394
1384
        # Since we are creating a .bzr directory, inherit the
1395
1385
        # mode from the root directory
1396
1386
        temp_control = lockable_files.LockableFiles(transport,
1397
 
                                                    '', lockable_files.TransportLock)
 
1387
                            '', lockable_files.TransportLock)
1398
1388
        try:
1399
1389
            temp_control._transport.mkdir('.bzr',
1400
 
                                          # FIXME: RBC 20060121 don't peek under
1401
 
                                          # the covers
1402
 
                                          mode=temp_control._dir_mode)
 
1390
                # FIXME: RBC 20060121 don't peek under
 
1391
                # the covers
 
1392
                mode=temp_control._dir_mode)
1403
1393
        except errors.FileExists:
1404
1394
            raise errors.AlreadyControlDirError(transport.base)
1405
1395
        if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1415
1405
                      ]
1416
1406
        # NB: no need to escape relative paths that are url safe.
1417
1407
        control_files = lockable_files.LockableFiles(bzrdir_transport,
1418
 
                                                     self._lock_file_name, self._lock_class)
 
1408
            self._lock_file_name, self._lock_class)
1419
1409
        control_files.create_lock()
1420
1410
        control_files.lock_write()
1421
1411
        try:
1422
1412
            for (filename, content) in utf8_files:
1423
1413
                bzrdir_transport.put_bytes(filename, content,
1424
 
                                           mode=file_mode)
 
1414
                    mode=file_mode)
1425
1415
        finally:
1426
1416
            control_files.unlock()
1427
1417
        return self.open(transport, _found=True)
1435
1425
            found_format = controldir.ControlDirFormat.find_format(transport)
1436
1426
            if not isinstance(found_format, self.__class__):
1437
1427
                raise AssertionError("%s was asked to open %s, but it seems to need "
1438
 
                                     "format %s"
1439
 
                                     % (self, transport, found_format))
 
1428
                        "format %s"
 
1429
                        % (self, transport, found_format))
1440
1430
            # Allow subclasses - use the found format.
1441
1431
            self._supply_sub_formats_to(found_format)
1442
1432
            return found_format._open(transport)
1468
1458
        return True
1469
1459
 
1470
1460
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1471
 
                             basedir=None):
 
1461
            basedir=None):
1472
1462
        controldir.ControlDirFormat.check_support_status(self,
1473
 
                                                         allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1474
 
                                                         basedir=basedir)
 
1463
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
 
1464
            basedir=basedir)
1475
1465
        BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1476
 
                                       recommend_upgrade=recommend_upgrade, basedir=basedir)
1477
 
 
1478
 
    @classmethod
1479
 
    def is_control_filename(klass, filename):
1480
 
        """True if filename is the name of a path which is reserved for bzrdir's.
1481
 
 
1482
 
        :param filename: A filename within the root transport of this bzrdir.
1483
 
 
1484
 
        This is true IF and ONLY IF the filename is part of the namespace
1485
 
        reserved for bzr control dirs. Currently this is the '.bzr' directory
1486
 
        in the root of the root_transport.
1487
 
        """
1488
 
        # this might be better on the BzrDirFormat class because it refers to
1489
 
        # all the possible bzrdir disk formats.
1490
 
        # This method is tested via the workingtree is_control_filename tests-
1491
 
        # it was extracted from WorkingTree.is_control_filename. If the
1492
 
        # method's contract is extended beyond the current trivial
1493
 
        # implementation, please add new tests for it to the appropriate place.
1494
 
        return filename == '.bzr' or filename.startswith('.bzr/')
 
1466
            recommend_upgrade=recommend_upgrade, basedir=basedir)
1495
1467
 
1496
1468
 
1497
1469
class BzrDirMetaFormat1(BzrDirFormat):
1543
1515
        self._branch_format = format
1544
1516
 
1545
1517
    def require_stacking(self, stack_on=None, possible_transports=None,
1546
 
                         _skip_repo=False):
 
1518
            _skip_repo=False):
1547
1519
        """We have a request to stack, try to ensure the formats support it.
1548
1520
 
1549
1521
        :param stack_on: If supplied, it is the URL to a branch that we want to
1558
1530
 
1559
1531
        # a bit of state for get_target_branch so that we don't try to open it
1560
1532
        # 2 times, for both repo *and* branch
1561
 
        target = [None, False, None]  # target_branch, checked, upgrade anyway
1562
 
 
 
1533
        target = [None, False, None] # target_branch, checked, upgrade anyway
1563
1534
        def get_target_branch():
1564
1535
            if target[1]:
1565
1536
                # We've checked, don't check again
1570
1541
                return target
1571
1542
            try:
1572
1543
                target_dir = BzrDir.open(stack_on,
1573
 
                                         possible_transports=possible_transports)
 
1544
                    possible_transports=possible_transports)
1574
1545
            except errors.NotBranchError:
1575
1546
                # Nothing there, don't change formats
1576
1547
                target[:] = [None, True, False]
1588
1559
            target[:] = [target_branch, True, False]
1589
1560
            return target
1590
1561
 
1591
 
        if (not _skip_repo
1592
 
                and not self.repository_format.supports_external_lookups):
 
1562
        if (not _skip_repo and
 
1563
                 not self.repository_format.supports_external_lookups):
1593
1564
            # We need to upgrade the Repository.
1594
1565
            target_branch, _, do_upgrade = get_target_branch()
1595
1566
            if target_branch is None:
1613
1584
            if new_repo_format is not None:
1614
1585
                self.repository_format = new_repo_format
1615
1586
                note(gettext('Source repository format does not support stacking,'
1616
 
                             ' using format:\n  %s'),
 
1587
                     ' using format:\n  %s'),
1617
1588
                     new_repo_format.get_format_description())
1618
1589
 
1619
1590
        if not self.get_branch_format().supports_stacking():
1633
1604
                # Does support stacking, use its format.
1634
1605
                self.set_branch_format(new_branch_format)
1635
1606
                note(gettext('Source branch format does not support stacking,'
1636
 
                             ' using format:\n  %s'),
 
1607
                     ' using format:\n  %s'),
1637
1608
                     new_branch_format.get_format_description())
1638
1609
 
1639
1610
    def get_converter(self, format=None):
1640
1611
        """See BzrDirFormat.get_converter()."""
1641
1612
        if format is None:
1642
1613
            format = BzrDirFormat.get_default_format()
1643
 
        if (isinstance(self, BzrDirMetaFormat1)
1644
 
                and isinstance(format, BzrDirMetaFormat1Colo)):
 
1614
        if (isinstance(self, BzrDirMetaFormat1) and
 
1615
            isinstance(format, BzrDirMetaFormat1Colo)):
1645
1616
            return ConvertMetaToColo(format)
1646
 
        if (isinstance(self, BzrDirMetaFormat1Colo)
1647
 
                and isinstance(format, BzrDirMetaFormat1)):
 
1617
        if (isinstance(self, BzrDirMetaFormat1Colo) and
 
1618
            isinstance(format, BzrDirMetaFormat1)):
1648
1619
            return ConvertMetaToColo(format)
1649
1620
        if not isinstance(self, format.__class__):
1650
1621
            # converting away from metadir is not implemented
1681
1652
        self._repository_format = value
1682
1653
 
1683
1654
    repository_format = property(__return_repository_format,
1684
 
                                 _set_repository_format)
 
1655
        _set_repository_format)
1685
1656
 
1686
1657
    def _supply_sub_formats_to(self, other_format):
1687
1658
        """Give other_format the same values for sub formats as this has.
1757
1728
    def convert(self, to_convert, pb):
1758
1729
        """See Converter.convert()."""
1759
1730
        self.controldir = to_convert
1760
 
        with ui.ui_factory.nested_progress_bar() as self.pb:
1761
 
            self.count = 0
1762
 
            self.total = 1
1763
 
            self.step('checking repository format')
1764
 
            try:
1765
 
                repo = self.controldir.open_repository()
1766
 
            except errors.NoRepositoryPresent:
1767
 
                pass
1768
 
            else:
1769
 
                repo_fmt = self.target_format.repository_format
1770
 
                if not isinstance(repo._format, repo_fmt.__class__):
1771
 
                    from ..repository import CopyConverter
1772
 
                    ui.ui_factory.note(gettext('starting repository conversion'))
1773
 
                    if not repo_fmt.supports_overriding_transport:
1774
 
                        raise AssertionError(
 
1731
        self.pb = ui.ui_factory.nested_progress_bar()
 
1732
        self.count = 0
 
1733
        self.total = 1
 
1734
        self.step('checking repository format')
 
1735
        try:
 
1736
            repo = self.controldir.open_repository()
 
1737
        except errors.NoRepositoryPresent:
 
1738
            pass
 
1739
        else:
 
1740
            repo_fmt = self.target_format.repository_format
 
1741
            if not isinstance(repo._format, repo_fmt.__class__):
 
1742
                from ..repository import CopyConverter
 
1743
                ui.ui_factory.note(gettext('starting repository conversion'))
 
1744
                if not repo_fmt.supports_overriding_transport:
 
1745
                    raise AssertionError(
1775
1746
                            "Repository in metadir does not support "
1776
1747
                            "overriding transport")
1777
 
                    converter = CopyConverter(self.target_format.repository_format)
1778
 
                    converter.convert(repo, pb)
1779
 
            for branch in self.controldir.list_branches():
1780
 
                # TODO: conversions of Branch and Tree should be done by
1781
 
                # InterXFormat lookups/some sort of registry.
1782
 
                # Avoid circular imports
 
1748
                converter = CopyConverter(self.target_format.repository_format)
 
1749
                converter.convert(repo, pb)
 
1750
        for branch in self.controldir.list_branches():
 
1751
            # TODO: conversions of Branch and Tree should be done by
 
1752
            # InterXFormat lookups/some sort of registry.
 
1753
            # Avoid circular imports
 
1754
            old = branch._format.__class__
 
1755
            new = self.target_format.get_branch_format().__class__
 
1756
            while old != new:
 
1757
                if (old == fullhistorybranch.BzrBranchFormat5 and
 
1758
                    new in (_mod_bzrbranch.BzrBranchFormat6,
 
1759
                        _mod_bzrbranch.BzrBranchFormat7,
 
1760
                        _mod_bzrbranch.BzrBranchFormat8)):
 
1761
                    branch_converter = _mod_bzrbranch.Converter5to6()
 
1762
                elif (old == _mod_bzrbranch.BzrBranchFormat6 and
 
1763
                    new in (_mod_bzrbranch.BzrBranchFormat7,
 
1764
                            _mod_bzrbranch.BzrBranchFormat8)):
 
1765
                    branch_converter = _mod_bzrbranch.Converter6to7()
 
1766
                elif (old == _mod_bzrbranch.BzrBranchFormat7 and
 
1767
                      new is _mod_bzrbranch.BzrBranchFormat8):
 
1768
                    branch_converter = _mod_bzrbranch.Converter7to8()
 
1769
                else:
 
1770
                    raise errors.BadConversionTarget("No converter", new,
 
1771
                        branch._format)
 
1772
                branch_converter.convert(branch)
 
1773
                branch = self.controldir.open_branch()
1783
1774
                old = branch._format.__class__
1784
 
                new = self.target_format.get_branch_format().__class__
1785
 
                while old != new:
1786
 
                    if (old == fullhistorybranch.BzrBranchFormat5
1787
 
                        and new in (_mod_bzrbranch.BzrBranchFormat6,
1788
 
                                    _mod_bzrbranch.BzrBranchFormat7,
1789
 
                                    _mod_bzrbranch.BzrBranchFormat8)):
1790
 
                        branch_converter = _mod_bzrbranch.Converter5to6()
1791
 
                    elif (old == _mod_bzrbranch.BzrBranchFormat6
1792
 
                          and new in (_mod_bzrbranch.BzrBranchFormat7,
1793
 
                                      _mod_bzrbranch.BzrBranchFormat8)):
1794
 
                        branch_converter = _mod_bzrbranch.Converter6to7()
1795
 
                    elif (old == _mod_bzrbranch.BzrBranchFormat7
1796
 
                          and new is _mod_bzrbranch.BzrBranchFormat8):
1797
 
                        branch_converter = _mod_bzrbranch.Converter7to8()
1798
 
                    else:
1799
 
                        raise errors.BadConversionTarget("No converter", new,
1800
 
                                                         branch._format)
1801
 
                    branch_converter.convert(branch)
1802
 
                    branch = self.controldir.open_branch()
1803
 
                    old = branch._format.__class__
1804
 
            try:
1805
 
                tree = self.controldir.open_workingtree(recommend_upgrade=False)
1806
 
            except (errors.NoWorkingTree, errors.NotLocalUrl):
1807
 
                pass
1808
 
            else:
1809
 
                # TODO: conversions of Branch and Tree should be done by
1810
 
                # InterXFormat lookups
1811
 
                if (isinstance(tree, workingtree_3.WorkingTree3)
1812
 
                    and not isinstance(tree, workingtree_4.DirStateWorkingTree)
1813
 
                    and isinstance(self.target_format.workingtree_format,
1814
 
                                   workingtree_4.DirStateWorkingTreeFormat)):
1815
 
                    workingtree_4.Converter3to4().convert(tree)
1816
 
                if (isinstance(tree, workingtree_4.DirStateWorkingTree)
1817
 
                    and not isinstance(tree, workingtree_4.WorkingTree5)
1818
 
                    and isinstance(self.target_format.workingtree_format,
1819
 
                                   workingtree_4.WorkingTreeFormat5)):
1820
 
                    workingtree_4.Converter4to5().convert(tree)
1821
 
                if (isinstance(tree, workingtree_4.DirStateWorkingTree)
1822
 
                    and not isinstance(tree, workingtree_4.WorkingTree6)
1823
 
                    and isinstance(self.target_format.workingtree_format,
1824
 
                                   workingtree_4.WorkingTreeFormat6)):
1825
 
                    workingtree_4.Converter4or5to6().convert(tree)
 
1775
        try:
 
1776
            tree = self.controldir.open_workingtree(recommend_upgrade=False)
 
1777
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
1778
            pass
 
1779
        else:
 
1780
            # TODO: conversions of Branch and Tree should be done by
 
1781
            # InterXFormat lookups
 
1782
            if (isinstance(tree, workingtree_3.WorkingTree3) and
 
1783
                not isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
1784
                isinstance(self.target_format.workingtree_format,
 
1785
                    workingtree_4.DirStateWorkingTreeFormat)):
 
1786
                workingtree_4.Converter3to4().convert(tree)
 
1787
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
1788
                not isinstance(tree, workingtree_4.WorkingTree5) and
 
1789
                isinstance(self.target_format.workingtree_format,
 
1790
                    workingtree_4.WorkingTreeFormat5)):
 
1791
                workingtree_4.Converter4to5().convert(tree)
 
1792
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
1793
                not isinstance(tree, workingtree_4.WorkingTree6) and
 
1794
                isinstance(self.target_format.workingtree_format,
 
1795
                    workingtree_4.WorkingTreeFormat6)):
 
1796
                workingtree_4.Converter4or5to6().convert(tree)
 
1797
        self.pb.finished()
1826
1798
        return to_convert
1827
1799
 
1828
1800
 
1839
1811
    def convert(self, to_convert, pb):
1840
1812
        """See Converter.convert()."""
1841
1813
        to_convert.transport.put_bytes('branch-format',
1842
 
                                       self.target_format.as_string())
 
1814
            self.target_format.as_string())
1843
1815
        return BzrDir.open_from_transport(to_convert.root_transport)
1844
1816
 
1845
1817
 
1857
1829
    def convert(self, to_convert, pb):
1858
1830
        """See Converter.convert()."""
1859
1831
        to_convert.transport.put_bytes('branch-format',
1860
 
                                       self.target_format.as_string())
 
1832
            self.target_format.as_string())
1861
1833
        return BzrDir.open_from_transport(to_convert.root_transport)
1862
1834
 
1863
1835
 
1874
1846
            relative to.
1875
1847
        """
1876
1848
        super(CreateRepository, self).__init__(
1877
 
            stack_on, stack_on_pwd, require_stacking)
 
1849
                stack_on, stack_on_pwd, require_stacking)
1878
1850
        self._controldir = controldir
1879
1851
 
1880
1852
    def acquire_repository(self, make_working_trees=None, shared=False,
1881
 
                           possible_transports=None):
 
1853
            possible_transports=None):
1882
1854
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
1883
1855
 
1884
1856
        Creates the desired repository in the controldir we already have.
1918
1890
            relative to.
1919
1891
        """
1920
1892
        super(UseExistingRepository, self).__init__(
1921
 
            stack_on, stack_on_pwd, require_stacking)
 
1893
                stack_on, stack_on_pwd, require_stacking)
1922
1894
        self._repository = repository
1923
1895
 
1924
1896
    def acquire_repository(self, make_working_trees=None, shared=False,
1925
 
                           possible_transports=None):
 
1897
            possible_transports=None):
1926
1898
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
1927
1899
 
1928
1900
        Returns an existing repository to use.
1933
1905
            possible_transports = list(possible_transports)
1934
1906
        possible_transports.append(self._repository.controldir.transport)
1935
1907
        self._add_fallback(self._repository,
1936
 
                           possible_transports=possible_transports)
 
1908
                       possible_transports=possible_transports)
1937
1909
        return self._repository, False
1938
1910
 
1939
1911