~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-06 06:48:25 UTC
  • mfrom: (4070.8.6 debug-config)
  • Revision ID: pqm@pqm.ubuntu.com-20090306064825-kbpwggw21dygeix6
(mbp) debug_flags configuration option

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""BzrDir logic. The BzrDir is the basic control directory used by bzr.
18
18
 
57
57
from bzrlib.osutils import (
58
58
    sha_string,
59
59
    )
60
 
from bzrlib.push import (
61
 
    PushResult,
62
 
    )
63
60
from bzrlib.smart.client import _SmartClient
64
61
from bzrlib.store.versioned import WeaveStore
65
62
from bzrlib.transactions import WriteTransaction
78
75
    )
79
76
 
80
77
from bzrlib import (
81
 
    hooks,
82
78
    registry,
83
79
    symbol_versioning,
84
80
    )
97
93
        (i.e. the parent directory holding the .bzr directory).
98
94
 
99
95
    Everything in the bzrdir should have the same file permissions.
100
 
 
101
 
    :cvar hooks: An instance of BzrDirHooks.
102
96
    """
103
97
 
104
98
    def break_lock(self):
195
189
        transport.ensure_base()
196
190
        require_stacking = (stacked_on is not None)
197
191
        format = self.cloning_metadir(require_stacking)
198
 
        # Bug: We create a metadir without knowing if it can support stacking,
199
 
        # we should look up the policy needs first.
200
192
        result = format.initialize_on_transport(transport)
201
193
        repository_policy = None
202
194
        try:
225
217
                force_new_repo, stacked_on, self.root_transport.base,
226
218
                require_stacking=require_stacking)
227
219
            make_working_trees = local_repo.make_working_trees()
228
 
            result_repo, is_new_repo = repository_policy.acquire_repository(
 
220
            result_repo = repository_policy.acquire_repository(
229
221
                make_working_trees, local_repo.is_shared())
230
222
            if not require_stacking and repository_policy._require_stacking:
231
223
                require_stacking = True
232
224
                result._format.require_stacking()
233
 
            if is_new_repo and not require_stacking and revision_id is not None:
234
 
                fetch_spec = graph.PendingAncestryResult(
235
 
                    [revision_id], local_repo)
236
 
                result_repo.fetch(local_repo, fetch_spec=fetch_spec)
237
 
            else:
238
 
                result_repo.fetch(local_repo, revision_id=revision_id)
 
225
            result_repo.fetch(local_repo, revision_id=revision_id)
239
226
        else:
240
227
            result_repo = None
241
228
        # 1 if there is a branch present
392
379
                                    stack_on_pwd=None, require_stacking=False):
393
380
        """Return an object representing a policy to use.
394
381
 
395
 
        This controls whether a new repository is created, and the format of
396
 
        that repository, or some existing shared repository used instead.
 
382
        This controls whether a new repository is created, or a shared
 
383
        repository used instead.
397
384
 
398
385
        If stack_on is supplied, will not seek a containing shared repo.
399
386
 
413
400
                if stack_on is not None:
414
401
                    stack_on_pwd = found_bzrdir.root_transport.base
415
402
                    stop = True
 
403
                    note('Using default stacking branch %s at %s', stack_on,
 
404
                         stack_on_pwd)
416
405
            # does it have a repository ?
417
406
            try:
418
407
                repository = found_bzrdir.open_repository()
421
410
            else:
422
411
                if ((found_bzrdir.root_transport.base !=
423
412
                     self.root_transport.base) and not repository.is_shared()):
424
 
                    # Don't look higher, can't use a higher shared repo.
425
413
                    repository = None
426
 
                    stop = True
427
414
                else:
428
415
                    stop = True
429
416
            if not stop:
453
440
    def _find_or_create_repository(self, force_new_repo):
454
441
        """Create a new repository if needed, returning the repository."""
455
442
        policy = self.determine_repository_policy(force_new_repo)
456
 
        return policy.acquire_repository()[0]
 
443
        return policy.acquire_repository()
457
444
 
458
445
    @staticmethod
459
446
    def create_branch_convenience(base, force_new_repo=False,
814
801
        :param transport: Transport containing the bzrdir.
815
802
        :param _unsupported: private.
816
803
        """
817
 
        for hook in BzrDir.hooks['pre_open']:
818
 
            hook(transport)
819
804
        # Keep initial base since 'transport' may be modified while following
820
805
        # the redirections.
821
806
        base = transport.base
841
826
        BzrDir._check_supported(format, _unsupported)
842
827
        return format.open(transport, _found=True)
843
828
 
844
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
829
    def open_branch(self, unsupported=False):
845
830
        """Open the branch object at this BzrDir if one is present.
846
831
 
847
832
        If unsupported is True, then no longer supported branch formats can
1022
1007
        result_format = self._format.__class__()
1023
1008
        try:
1024
1009
            try:
1025
 
                branch = self.open_branch(ignore_fallbacks=True)
 
1010
                branch = self.open_branch()
1026
1011
                source_repository = branch.repository
1027
1012
                result_format._branch_format = branch._format
1028
1013
            except errors.NotBranchError:
1129
1114
                    source_repository = None
1130
1115
        repository_policy = result.determine_repository_policy(
1131
1116
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1132
 
        result_repo, is_new_repo = repository_policy.acquire_repository()
1133
 
        if is_new_repo and revision_id is not None and not stacked:
1134
 
            fetch_spec = graph.PendingAncestryResult(
1135
 
                [revision_id], source_repository)
1136
 
        else:
1137
 
            fetch_spec = None
 
1117
        result_repo = repository_policy.acquire_repository()
1138
1118
        if source_repository is not None:
1139
1119
            # Fetch while stacked to prevent unstacked fetch from
1140
1120
            # Branch.sprout.
1141
 
            if fetch_spec is None:
1142
 
                result_repo.fetch(source_repository, revision_id=revision_id)
1143
 
            else:
1144
 
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
1121
            result_repo.fetch(source_repository, revision_id=revision_id)
1145
1122
 
1146
1123
        if source_branch is None:
1147
1124
            # this is for sprouting a bzrdir without a branch; is that
1199
1176
                    basis.unlock()
1200
1177
        return result
1201
1178
 
1202
 
    def push_branch(self, source, revision_id=None, overwrite=False, 
1203
 
        remember=False):
1204
 
        """Push the source branch into this BzrDir."""
1205
 
        br_to = None
1206
 
        # If we can open a branch, use its direct repository, otherwise see
1207
 
        # if there is a repository without a branch.
1208
 
        try:
1209
 
            br_to = self.open_branch()
1210
 
        except errors.NotBranchError:
1211
 
            # Didn't find a branch, can we find a repository?
1212
 
            repository_to = self.find_repository()
1213
 
        else:
1214
 
            # Found a branch, so we must have found a repository
1215
 
            repository_to = br_to.repository
1216
 
 
1217
 
        push_result = PushResult()
1218
 
        push_result.source_branch = source
1219
 
        if br_to is None:
1220
 
            # We have a repository but no branch, copy the revisions, and then
1221
 
            # create a branch.
1222
 
            repository_to.fetch(source.repository, revision_id=revision_id)
1223
 
            br_to = source.clone(self, revision_id=revision_id)
1224
 
            if source.get_push_location() is None or remember:
1225
 
                source.set_push_location(br_to.base)
1226
 
            push_result.stacked_on = None
1227
 
            push_result.branch_push_result = None
1228
 
            push_result.old_revno = None
1229
 
            push_result.old_revid = _mod_revision.NULL_REVISION
1230
 
            push_result.target_branch = br_to
1231
 
            push_result.master_branch = None
1232
 
            push_result.workingtree_updated = False
1233
 
        else:
1234
 
            # We have successfully opened the branch, remember if necessary:
1235
 
            if source.get_push_location() is None or remember:
1236
 
                source.set_push_location(br_to.base)
1237
 
            try:
1238
 
                tree_to = self.open_workingtree()
1239
 
            except errors.NotLocalUrl:
1240
 
                push_result.branch_push_result = source.push(br_to, 
1241
 
                    overwrite, stop_revision=revision_id)
1242
 
                push_result.workingtree_updated = False
1243
 
            except errors.NoWorkingTree:
1244
 
                push_result.branch_push_result = source.push(br_to,
1245
 
                    overwrite, stop_revision=revision_id)
1246
 
                push_result.workingtree_updated = None # Not applicable
1247
 
            else:
1248
 
                tree_to.lock_write()
1249
 
                try:
1250
 
                    push_result.branch_push_result = source.push(
1251
 
                        tree_to.branch, overwrite, stop_revision=revision_id)
1252
 
                    tree_to.update()
1253
 
                finally:
1254
 
                    tree_to.unlock()
1255
 
                push_result.workingtree_updated = True
1256
 
            push_result.old_revno = push_result.branch_push_result.old_revno
1257
 
            push_result.old_revid = push_result.branch_push_result.old_revid
1258
 
            push_result.target_branch = \
1259
 
                push_result.branch_push_result.target_branch
1260
 
        return push_result
1261
 
 
1262
 
 
1263
 
class BzrDirHooks(hooks.Hooks):
1264
 
    """Hooks for BzrDir operations."""
1265
 
 
1266
 
    def __init__(self):
1267
 
        """Create the default hooks."""
1268
 
        hooks.Hooks.__init__(self)
1269
 
        self.create_hook(hooks.HookPoint('pre_open',
1270
 
            "Invoked before attempting to open a BzrDir with the transport "
1271
 
            "that the open will use.", (1, 14), None))
1272
 
 
1273
 
# install the default hooks
1274
 
BzrDir.hooks = BzrDirHooks()
1275
 
 
1276
1179
 
1277
1180
class BzrDirPreSplitOut(BzrDir):
1278
1181
    """A common class for the all-in-one formats."""
1421
1324
            format = BzrDirFormat.get_default_format()
1422
1325
        return not isinstance(self._format, format.__class__)
1423
1326
 
1424
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1327
    def open_branch(self, unsupported=False):
1425
1328
        """See BzrDir.open_branch."""
1426
1329
        from bzrlib.branch import BzrBranchFormat4
1427
1330
        format = BzrBranchFormat4()
1672
1575
            pass
1673
1576
        return False
1674
1577
 
1675
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1578
    def open_branch(self, unsupported=False):
1676
1579
        """See BzrDir.open_branch."""
1677
1580
        format = self.find_branch_format()
1678
1581
        self._check_supported(format, unsupported)
1679
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1582
        return format.open(self, _found=True)
1680
1583
 
1681
1584
    def open_repository(self, unsupported=False):
1682
1585
        """See BzrDir.open_repository."""
2533
2436
        self.snapshot_ie(previous_entries, ie, w, rev_id)
2534
2437
        del ie.text_id
2535
2438
 
 
2439
    @symbol_versioning.deprecated_method(symbol_versioning.one_one)
 
2440
    def get_parents(self, revision_ids):
 
2441
        for revision_id in revision_ids:
 
2442
            yield self.revisions[revision_id].parent_ids
 
2443
 
2536
2444
    def get_parent_map(self, revision_ids):
2537
2445
        """See graph._StackedParentsProvider.get_parent_map"""
2538
2446
        return dict((revision_id, self.revisions[revision_id])
2814
2722
                isinstance(self.target_format.workingtree_format,
2815
2723
                    workingtree_4.WorkingTreeFormat5)):
2816
2724
                workingtree_4.Converter4to5().convert(tree)
2817
 
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2818
 
                not isinstance(tree, workingtree_4.WorkingTree6) and
2819
 
                isinstance(self.target_format.workingtree_format,
2820
 
                    workingtree_4.WorkingTreeFormat6)):
2821
 
                workingtree_4.Converter4or5to6().convert(tree)
2822
2725
        return to_convert
2823
2726
 
2824
2727
 
2898
2801
        # Always return a RemoteRepositoryFormat object, but if a specific bzr
2899
2802
        # repository format has been asked for, tell the RemoteRepositoryFormat
2900
2803
        # that it should use that for init() etc.
2901
 
        result = remote.RemoteRepositoryFormat()
 
2804
        result =  remote.RemoteRepositoryFormat()
2902
2805
        custom_format = getattr(self, '_repository_format', None)
2903
2806
        if custom_format:
 
2807
            # We will use the custom format to create repositories over the
 
2808
            # wire; expose its details like rich_root_data for code to query
2904
2809
            if isinstance(custom_format, remote.RemoteRepositoryFormat):
2905
 
                return custom_format
 
2810
                result._custom_format = custom_format._custom_format
2906
2811
            else:
2907
 
                # We will use the custom format to create repositories over the
2908
 
                # wire; expose its details like rich_root_data for code to
2909
 
                # query
2910
2812
                result._custom_format = custom_format
 
2813
            result.rich_root_data = custom_format.rich_root_data
2911
2814
        return result
2912
2815
 
2913
2816
    def get_branch_format(self):
3146
3049
                stack_on = self._get_full_stack_on()
3147
3050
        try:
3148
3051
            branch.set_stacked_on_url(stack_on)
3149
 
        except (errors.UnstackableBranchFormat,
3150
 
                errors.UnstackableRepositoryFormat):
 
3052
        except errors.UnstackableBranchFormat:
3151
3053
            if self._require_stacking:
3152
3054
                raise
3153
3055
 
3187
3089
        :param make_working_trees: If creating a repository, set
3188
3090
            make_working_trees to this value (if non-None)
3189
3091
        :param shared: If creating a repository, make it shared if True
3190
 
        :return: A repository, is_new_flag (True if the repository was
3191
 
            created).
 
3092
        :return: A repository
3192
3093
        """
3193
3094
        raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
3194
3095
 
3214
3115
 
3215
3116
        Creates the desired repository in the bzrdir we already have.
3216
3117
        """
3217
 
        stack_on = self._get_full_stack_on()
3218
 
        if stack_on:
3219
 
            # Stacking is desired. requested by the target, but does the place it
3220
 
            # points at support stacking? If it doesn't then we should
3221
 
            # not implicitly upgrade. We check this here.
3222
 
            format = self._bzrdir._format
3223
 
            if not (format.repository_format.supports_external_lookups
3224
 
                and format.get_branch_format().supports_stacking()):
3225
 
                # May need to upgrade - but only do if the target also
3226
 
                # supports stacking. Note that this currently wastes
3227
 
                # network round trips to check - but we only do this
3228
 
                # when the source can't stack so it will fade away
3229
 
                # as people do upgrade.
3230
 
                try:
3231
 
                    target_dir = BzrDir.open(stack_on,
3232
 
                        possible_transports=[self._bzrdir.root_transport])
3233
 
                except errors.NotBranchError:
3234
 
                    # Nothing there, don't change formats
3235
 
                    pass
3236
 
                else:
3237
 
                    try:
3238
 
                        target_branch = target_dir.open_branch()
3239
 
                    except errors.NotBranchError:
3240
 
                        # No branch, don't change formats
3241
 
                        pass
3242
 
                    else:
3243
 
                        branch_format = target_branch._format
3244
 
                        repo_format = target_branch.repository._format
3245
 
                        if not (branch_format.supports_stacking()
3246
 
                            and repo_format.supports_external_lookups):
3247
 
                            # Doesn't stack itself, don't force an upgrade
3248
 
                            pass
3249
 
                        else:
3250
 
                            # Does support stacking, use its format.
3251
 
                            format.repository_format = repo_format
3252
 
                            format.set_branch_format(branch_format)
3253
 
                            note('Source format does not support stacking, '
3254
 
                                'using format: \'%s\'\n  %s\n',
3255
 
                                branch_format.get_format_description(),
3256
 
                                repo_format.get_format_description())
3257
 
            if not self._require_stacking:
3258
 
                # We have picked up automatic stacking somewhere.
3259
 
                note('Using default stacking branch %s at %s', self._stack_on,
3260
 
                    self._stack_on_pwd)
3261
3118
        repository = self._bzrdir.create_repository(shared=shared)
3262
3119
        self._add_fallback(repository,
3263
3120
                           possible_transports=[self._bzrdir.transport])
3264
3121
        if make_working_trees is not None:
3265
3122
            repository.set_make_working_trees(make_working_trees)
3266
 
        return repository, True
 
3123
        return repository
3267
3124
 
3268
3125
 
3269
3126
class UseExistingRepository(RepositoryAcquisitionPolicy):
3285
3142
    def acquire_repository(self, make_working_trees=None, shared=False):
3286
3143
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
3287
3144
 
3288
 
        Returns an existing repository to use.
 
3145
        Returns an existing repository to use
3289
3146
        """
3290
3147
        self._add_fallback(self._repository,
3291
3148
                       possible_transports=[self._repository.bzrdir.transport])
3292
 
        return self._repository, False
 
3149
        return self._repository
3293
3150
 
3294
3151
 
3295
3152
# Please register new formats after old formats so that formats
3376
3233
format_registry.register_metadir('rich-root-pack',
3377
3234
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3378
3235
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3379
 
         '(needed for bzr-svn and bzr-git).',
 
3236
         '(needed for bzr-svn).',
3380
3237
    branch_format='bzrlib.branch.BzrBranchFormat6',
3381
3238
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3382
3239
    )
3391
3248
format_registry.register_metadir('1.6.1-rich-root',
3392
3249
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3393
3250
    help='A variant of 1.6 that supports rich-root data '
3394
 
         '(needed for bzr-svn and bzr-git).',
 
3251
         '(needed for bzr-svn).',
3395
3252
    branch_format='bzrlib.branch.BzrBranchFormat7',
3396
3253
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3397
3254
    )
3406
3263
format_registry.register_metadir('1.9-rich-root',
3407
3264
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3408
3265
    help='A variant of 1.9 that supports rich-root data '
3409
 
         '(needed for bzr-svn and bzr-git).',
 
3266
         '(needed for bzr-svn).',
3410
3267
    branch_format='bzrlib.branch.BzrBranchFormat7',
3411
3268
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3412
3269
    )
3413
 
format_registry.register_metadir('1.14',
 
3270
format_registry.register_metadir('development-wt5',
3414
3271
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3415
 
    help='A working-tree format that supports content filtering.',
 
3272
    help='A working-tree format that supports views and content filtering.',
3416
3273
    branch_format='bzrlib.branch.BzrBranchFormat7',
3417
3274
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3275
    experimental=True,
3418
3276
    )
3419
 
format_registry.register_metadir('1.14-rich-root',
 
3277
format_registry.register_metadir('development-wt5-rich-root',
3420
3278
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3421
 
    help='A variant of 1.14 that supports rich-root data '
3422
 
         '(needed for bzr-svn and bzr-git).',
 
3279
    help='A variant of development-wt5 that supports rich-root data '
 
3280
         '(needed for bzr-svn).',
3423
3281
    branch_format='bzrlib.branch.BzrBranchFormat7',
3424
3282
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3283
    experimental=True,
3425
3284
    )
3426
3285
# The following two formats should always just be aliases.
3427
3286
format_registry.register_metadir('development',
3473
3332
    hidden=True,
3474
3333
    experimental=True,
3475
3334
    )
3476
 
# These next two formats should be removed when the gc formats are
3477
 
# updated to use WorkingTreeFormat6 and are merged into bzr.dev
3478
 
format_registry.register_metadir('development-wt6',
3479
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3480
 
    help='1.14 with filtered views. '
3481
 
        'Please read '
3482
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3483
 
        'before use.',
3484
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3485
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3486
 
    hidden=True,
3487
 
    experimental=True,
3488
 
    )
3489
 
format_registry.register_metadir('development-wt6-rich-root',
3490
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3491
 
    help='A variant of development-wt6 that supports rich-root data '
3492
 
         '(needed for bzr-svn and bzr-git).',
3493
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3494
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3495
 
    hidden=True,
3496
 
    experimental=True,
3497
 
    )
3498
 
# The following format should be an alias for the rich root equivalent 
3499
 
# of the default format
3500
 
format_registry.register_metadir('default-rich-root',
3501
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3502
 
    help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3503
 
    branch_format='bzrlib.branch.BzrBranchFormat6',
3504
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3505
 
    alias=True,
3506
 
    )
3507
3335
# The current format that is made on 'bzr init'.
3508
3336
format_registry.set_default('pack-0.92')