/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 bzrlib/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2011-04-19 14:19:50 UTC
  • mfrom: (5804 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5808.
  • Revision ID: jelmer@samba.org-20110419141950-b5no329iig0ludz9
merge bzr.dev/.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
objects returned.
26
26
"""
27
27
 
28
 
# TODO: Move old formats into a plugin to make this file smaller.
29
 
 
30
28
import sys
31
29
 
32
30
from bzrlib.lazy_import import lazy_import
33
31
lazy_import(globals(), """
34
 
from stat import S_ISDIR
35
 
 
36
32
import bzrlib
37
33
from bzrlib import (
 
34
    branch as _mod_branch,
 
35
    cleanup,
38
36
    config,
39
37
    controldir,
40
38
    errors,
 
39
    fetch,
41
40
    graph,
42
41
    lockable_files,
43
42
    lockdir,
49
48
    transport as _mod_transport,
50
49
    ui,
51
50
    urlutils,
52
 
    versionedfile,
53
51
    win32utils,
54
52
    workingtree,
55
53
    workingtree_4,
56
54
    )
57
 
from bzrlib.repofmt import pack_repo
 
55
from bzrlib.repofmt import knitpack_repo
58
56
from bzrlib.transport import (
59
57
    do_catching_redirections,
60
58
    local,
61
59
    )
62
 
from bzrlib.weave import (
63
 
    WeaveFile,
64
 
    Weave,
65
 
    )
66
60
""")
67
61
 
68
62
from bzrlib.trace import (
 
63
    mutter,
69
64
    note,
70
65
    )
71
66
 
128
123
            # No repo, no problem.
129
124
            pass
130
125
 
131
 
    @staticmethod
132
 
    def _check_supported(format, allow_unsupported,
133
 
        recommend_upgrade=True,
134
 
        basedir=None):
135
 
        """Give an error or warning on old formats.
136
 
 
137
 
        :param format: may be any kind of format - workingtree, branch,
138
 
        or repository.
139
 
 
140
 
        :param allow_unsupported: If true, allow opening
141
 
        formats that are strongly deprecated, and which may
142
 
        have limited functionality.
143
 
 
144
 
        :param recommend_upgrade: If true (default), warn
145
 
        the user through the ui object that they may wish
146
 
        to upgrade the object.
147
 
        """
148
 
        # TODO: perhaps move this into a base Format class; it's not BzrDir
149
 
        # specific. mbp 20070323
150
 
        if not allow_unsupported and not format.is_supported():
151
 
            # see open_downlevel to open legacy branches.
152
 
            raise errors.UnsupportedFormatError(format=format)
153
 
        if recommend_upgrade \
154
 
            and getattr(format, 'upgrade_recommended', False):
155
 
            ui.ui_factory.recommend_upgrade(
156
 
                format.get_format_description(),
157
 
                basedir)
158
 
 
159
126
    def clone_on_transport(self, transport, revision_id=None,
160
127
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
161
128
        create_prefix=False, use_existing_dir=True, no_tree=False):
421
388
        policy = self.determine_repository_policy(force_new_repo)
422
389
        return policy.acquire_repository()[0]
423
390
 
 
391
    def _find_source_repo(self, add_cleanup, source_branch):
 
392
        """Find the source branch and repo for a sprout operation.
 
393
        
 
394
        This is helper intended for use by _sprout.
 
395
 
 
396
        :returns: (source_branch, source_repository).  Either or both may be
 
397
            None.  If not None, they will be read-locked (and their unlock(s)
 
398
            scheduled via the add_cleanup param).
 
399
        """
 
400
        if source_branch is not None:
 
401
            add_cleanup(source_branch.lock_read().unlock)
 
402
            return source_branch, source_branch.repository
 
403
        try:
 
404
            source_branch = self.open_branch()
 
405
            source_repository = source_branch.repository
 
406
        except errors.NotBranchError:
 
407
            source_branch = None
 
408
            try:
 
409
                source_repository = self.open_repository()
 
410
            except errors.NoRepositoryPresent:
 
411
                source_repository = None
 
412
            else:
 
413
                add_cleanup(source_repository.lock_read().unlock)
 
414
        else:
 
415
            add_cleanup(source_branch.lock_read().unlock)
 
416
        return source_branch, source_repository
 
417
 
 
418
    def sprout(self, url, revision_id=None, force_new_repo=False,
 
419
               recurse='down', possible_transports=None,
 
420
               accelerator_tree=None, hardlink=False, stacked=False,
 
421
               source_branch=None, create_tree_if_local=True):
 
422
        """Create a copy of this controldir prepared for use as a new line of
 
423
        development.
 
424
 
 
425
        If url's last component does not exist, it will be created.
 
426
 
 
427
        Attributes related to the identity of the source branch like
 
428
        branch nickname will be cleaned, a working tree is created
 
429
        whether one existed before or not; and a local branch is always
 
430
        created.
 
431
 
 
432
        if revision_id is not None, then the clone operation may tune
 
433
            itself to download less data.
 
434
        :param accelerator_tree: A tree which can be used for retrieving file
 
435
            contents more quickly than the revision tree, i.e. a workingtree.
 
436
            The revision tree will be used for cases where accelerator_tree's
 
437
            content is different.
 
438
        :param hardlink: If true, hard-link files from accelerator_tree,
 
439
            where possible.
 
440
        :param stacked: If true, create a stacked branch referring to the
 
441
            location of this control directory.
 
442
        :param create_tree_if_local: If true, a working-tree will be created
 
443
            when working locally.
 
444
        """
 
445
        operation = cleanup.OperationWithCleanups(self._sprout)
 
446
        return operation.run(url, revision_id=revision_id,
 
447
            force_new_repo=force_new_repo, recurse=recurse,
 
448
            possible_transports=possible_transports,
 
449
            accelerator_tree=accelerator_tree, hardlink=hardlink,
 
450
            stacked=stacked, source_branch=source_branch,
 
451
            create_tree_if_local=create_tree_if_local)
 
452
 
 
453
    def _sprout(self, op, url, revision_id=None, force_new_repo=False,
 
454
               recurse='down', possible_transports=None,
 
455
               accelerator_tree=None, hardlink=False, stacked=False,
 
456
               source_branch=None, create_tree_if_local=True):
 
457
        add_cleanup = op.add_cleanup
 
458
        fetch_spec_factory = fetch.FetchSpecFactory()
 
459
        if revision_id is not None:
 
460
            fetch_spec_factory.add_revision_ids([revision_id])
 
461
            fetch_spec_factory.source_branch_stop_revision_id = revision_id
 
462
        target_transport = _mod_transport.get_transport(url,
 
463
            possible_transports)
 
464
        target_transport.ensure_base()
 
465
        cloning_format = self.cloning_metadir(stacked)
 
466
        # Create/update the result branch
 
467
        result = cloning_format.initialize_on_transport(target_transport)
 
468
        source_branch, source_repository = self._find_source_repo(
 
469
            add_cleanup, source_branch)
 
470
        fetch_spec_factory.source_branch = source_branch
 
471
        # if a stacked branch wasn't requested, we don't create one
 
472
        # even if the origin was stacked
 
473
        if stacked and source_branch is not None:
 
474
            stacked_branch_url = self.root_transport.base
 
475
        else:
 
476
            stacked_branch_url = None
 
477
        repository_policy = result.determine_repository_policy(
 
478
            force_new_repo, stacked_branch_url, require_stacking=stacked)
 
479
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
480
        add_cleanup(result_repo.lock_write().unlock)
 
481
        fetch_spec_factory.source_repo = source_repository
 
482
        fetch_spec_factory.target_repo = result_repo
 
483
        if stacked or (len(result_repo._fallback_repositories) != 0):
 
484
            target_repo_kind = fetch.TargetRepoKinds.STACKED
 
485
        elif is_new_repo:
 
486
            target_repo_kind = fetch.TargetRepoKinds.EMPTY
 
487
        else:
 
488
            target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
 
489
        fetch_spec_factory.target_repo_kind = target_repo_kind
 
490
        if source_repository is not None:
 
491
            fetch_spec = fetch_spec_factory.make_fetch_spec()
 
492
            result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
493
 
 
494
        if source_branch is None:
 
495
            # this is for sprouting a controldir without a branch; is that
 
496
            # actually useful?
 
497
            # Not especially, but it's part of the contract.
 
498
            result_branch = result.create_branch()
 
499
        else:
 
500
            result_branch = source_branch.sprout(result,
 
501
                revision_id=revision_id, repository_policy=repository_policy,
 
502
                repository=result_repo)
 
503
        mutter("created new branch %r" % (result_branch,))
 
504
 
 
505
        # Create/update the result working tree
 
506
        if (create_tree_if_local and
 
507
            isinstance(target_transport, local.LocalTransport) and
 
508
            (result_repo is None or result_repo.make_working_trees())):
 
509
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
 
510
                hardlink=hardlink, from_branch=result_branch)
 
511
            wt.lock_write()
 
512
            try:
 
513
                if wt.path2id('') is None:
 
514
                    try:
 
515
                        wt.set_root_id(self.open_workingtree.get_root_id())
 
516
                    except errors.NoWorkingTree:
 
517
                        pass
 
518
            finally:
 
519
                wt.unlock()
 
520
        else:
 
521
            wt = None
 
522
        if recurse == 'down':
 
523
            basis = None
 
524
            if wt is not None:
 
525
                basis = wt.basis_tree()
 
526
            elif result_branch is not None:
 
527
                basis = result_branch.basis_tree()
 
528
            elif source_branch is not None:
 
529
                basis = source_branch.basis_tree()
 
530
            if basis is not None:
 
531
                add_cleanup(basis.lock_read().unlock)
 
532
                subtrees = basis.iter_references()
 
533
            else:
 
534
                subtrees = []
 
535
            for path, file_id in subtrees:
 
536
                target = urlutils.join(url, urlutils.escape(path))
 
537
                sublocation = source_branch.reference_parent(file_id, path)
 
538
                sublocation.bzrdir.sprout(target,
 
539
                    basis.get_reference_revision(file_id, path),
 
540
                    force_new_repo=force_new_repo, recurse=recurse,
 
541
                    stacked=stacked)
 
542
        return result
 
543
 
 
544
 
 
545
 
424
546
    @staticmethod
425
547
    def create_branch_convenience(base, force_new_repo=False,
426
548
                                  force_new_tree=None, format=None,
735
857
        except errors.TooManyRedirections:
736
858
            raise errors.NotBranchError(base)
737
859
 
738
 
        BzrDir._check_supported(format, _unsupported)
 
860
        format.check_support_status(_unsupported)
739
861
        return format.open(transport, _found=True)
740
862
 
741
863
    @staticmethod
958
1080
 
959
1081
    def __init__(self):
960
1082
        """Create the default hooks."""
961
 
        hooks.Hooks.__init__(self)
962
 
        self.create_hook(hooks.HookPoint('pre_open',
 
1083
        hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
 
1084
        self.add_hook('pre_open',
963
1085
            "Invoked before attempting to open a BzrDir with the transport "
964
 
            "that the open will use.", (1, 14), None))
965
 
        self.create_hook(hooks.HookPoint('post_repo_init',
 
1086
            "that the open will use.", (1, 14))
 
1087
        self.add_hook('post_repo_init',
966
1088
            "Invoked after a repository has been initialized. "
967
1089
            "post_repo_init is called with a "
968
1090
            "bzrlib.bzrdir.RepoInitHookParams.",
969
 
            (2, 2), None))
 
1091
            (2, 2))
970
1092
 
971
1093
# install the default hooks
972
1094
BzrDir.hooks = BzrDirHooks()
1175
1297
                    ignore_fallbacks=False):
1176
1298
        """See BzrDir.open_branch."""
1177
1299
        format = self.find_branch_format(name=name)
1178
 
        self._check_supported(format, unsupported)
 
1300
        format.check_support_status(unsupported)
1179
1301
        return format.open(self, name=name,
1180
1302
            _found=True, ignore_fallbacks=ignore_fallbacks)
1181
1303
 
1183
1305
        """See BzrDir.open_repository."""
1184
1306
        from bzrlib.repository import RepositoryFormat
1185
1307
        format = RepositoryFormat.find_format(self)
1186
 
        self._check_supported(format, unsupported)
 
1308
        format.check_support_status(unsupported)
1187
1309
        return format.open(self, _found=True)
1188
1310
 
1189
1311
    def open_workingtree(self, unsupported=False,
1191
1313
        """See BzrDir.open_workingtree."""
1192
1314
        from bzrlib.workingtree import WorkingTreeFormat
1193
1315
        format = WorkingTreeFormat.find_format(self)
1194
 
        self._check_supported(format, unsupported,
1195
 
            recommend_upgrade,
 
1316
        format.check_support_status(unsupported, recommend_upgrade,
1196
1317
            basedir=self.root_transport.base)
1197
1318
        return format.open(self, _found=True)
1198
1319
 
1585
1706
                    # stack_on is inaccessible, JFDI.
1586
1707
                    # TODO: bad monkey, hard-coded formats...
1587
1708
                    if self.repository_format.rich_root_data:
1588
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
 
1709
                        new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1589
1710
                    else:
1590
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
 
1711
                        new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1591
1712
            else:
1592
1713
                # If the target already supports stacking, then we know the
1593
1714
                # project is already able to use stacking, so auto-upgrade
1737
1858
            # TODO: conversions of Branch and Tree should be done by
1738
1859
            # InterXFormat lookups/some sort of registry.
1739
1860
            # Avoid circular imports
1740
 
            from bzrlib import branch as _mod_branch
1741
1861
            old = branch._format.__class__
1742
1862
            new = self.target_format.get_branch_format().__class__
1743
1863
            while old != new:
2034
2154
    hidden=True,
2035
2155
    )
2036
2156
register_metadir(controldir.format_registry, 'pack-0.92',
2037
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
 
2157
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2038
2158
    help='New in 0.92: Pack-based format with data compatible with '
2039
2159
        'dirstate-tags format repositories. Interoperates with '
2040
2160
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2043
2163
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2044
2164
    )
2045
2165
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2046
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
 
2166
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2047
2167
    help='New in 0.92: Pack-based format with data compatible with '
2048
2168
        'dirstate-with-subtree format repositories. Interoperates with '
2049
2169
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2054
2174
    experimental=True,
2055
2175
    )
2056
2176
register_metadir(controldir.format_registry, 'rich-root-pack',
2057
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
 
2177
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2058
2178
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2059
2179
         '(needed for bzr-svn and bzr-git).',
2060
2180
    branch_format='bzrlib.branch.BzrBranchFormat6',
2062
2182
    hidden=True,
2063
2183
    )
2064
2184
register_metadir(controldir.format_registry, '1.6',
2065
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
 
2185
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2066
2186
    help='A format that allows a branch to indicate that there is another '
2067
2187
         '(stacked) repository that should be used to access data that is '
2068
2188
         'not present locally.',
2071
2191
    hidden=True,
2072
2192
    )
2073
2193
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2074
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
 
2194
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2075
2195
    help='A variant of 1.6 that supports rich-root data '
2076
2196
         '(needed for bzr-svn and bzr-git).',
2077
2197
    branch_format='bzrlib.branch.BzrBranchFormat7',
2079
2199
    hidden=True,
2080
2200
    )
2081
2201
register_metadir(controldir.format_registry, '1.9',
2082
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
 
2202
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2083
2203
    help='A repository format using B+tree indexes. These indexes '
2084
2204
         'are smaller in size, have smarter caching and provide faster '
2085
2205
         'performance for most operations.',
2088
2208
    hidden=True,
2089
2209
    )
2090
2210
register_metadir(controldir.format_registry, '1.9-rich-root',
2091
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
 
2211
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2092
2212
    help='A variant of 1.9 that supports rich-root data '
2093
2213
         '(needed for bzr-svn and bzr-git).',
2094
2214
    branch_format='bzrlib.branch.BzrBranchFormat7',
2096
2216
    hidden=True,
2097
2217
    )
2098
2218
register_metadir(controldir.format_registry, '1.14',
2099
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
 
2219
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2100
2220
    help='A working-tree format that supports content filtering.',
2101
2221
    branch_format='bzrlib.branch.BzrBranchFormat7',
2102
2222
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2103
2223
    )
2104
2224
register_metadir(controldir.format_registry, '1.14-rich-root',
2105
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
 
2225
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2106
2226
    help='A variant of 1.14 that supports rich-root data '
2107
2227
         '(needed for bzr-svn and bzr-git).',
2108
2228
    branch_format='bzrlib.branch.BzrBranchFormat7',
2126
2246
                 # chk based subtree format.
2127
2247
    )
2128
2248
register_metadir(controldir.format_registry, 'development5-subtree',
2129
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
2249
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2130
2250
    help='Development format, subtree variant. Can convert data to and '
2131
2251
        'from pack-0.92-subtree (and anything compatible with '
2132
2252
        'pack-0.92-subtree) format repositories. Repositories and branches in '