~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Vincent Ladeuil
  • Date: 2011-06-27 15:42:09 UTC
  • mfrom: (5993 +trunk)
  • mto: (5993.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 5994.
  • Revision ID: v.ladeuil+lp@free.fr-20110627154209-azubuhbuxsz109hq
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
    revision as _mod_revision,
33
33
    testament as _mod_testament,
34
34
    tsort,
35
 
    gpg,
36
35
    )
37
36
from bzrlib.bundle import serializer
38
 
from bzrlib.i18n import gettext
39
37
""")
40
38
 
41
39
from bzrlib import (
281
279
                raise
282
280
            mutter('abort_write_group failed')
283
281
            log_exception_quietly()
284
 
            note(gettext('bzr: ERROR (ignored): %s'), exc)
 
282
            note('bzr: ERROR (ignored): %s', exc)
285
283
        self._write_group = None
286
284
 
287
285
    def _abort_write_group(self):
341
339
        """
342
340
        self.control_files.break_lock()
343
341
 
 
342
    @needs_read_lock
 
343
    def _eliminate_revisions_not_present(self, revision_ids):
 
344
        """Check every revision id in revision_ids to see if we have it.
 
345
 
 
346
        Returns a set of the present revisions.
 
347
        """
 
348
        result = []
 
349
        graph = self.get_graph()
 
350
        parent_map = graph.get_parent_map(revision_ids)
 
351
        # The old API returned a list, should this actually be a set?
 
352
        return parent_map.keys()
 
353
 
344
354
    @staticmethod
345
 
    def create(controldir):
346
 
        """Construct the current default format repository in controldir."""
347
 
        return RepositoryFormat.get_default_format().initialize(controldir)
 
355
    def create(a_bzrdir):
 
356
        """Construct the current default format repository in a_bzrdir."""
 
357
        return RepositoryFormat.get_default_format().initialize(a_bzrdir)
348
358
 
349
 
    def __init__(self, _format, controldir, control_files):
 
359
    def __init__(self, _format, a_bzrdir, control_files):
350
360
        """instantiate a Repository.
351
361
 
352
362
        :param _format: The format of the repository on disk.
353
 
        :param controldir: The ControlDir of the repository.
 
363
        :param a_bzrdir: The BzrDir of the repository.
354
364
        :param control_files: Control files to use for locking, etc.
355
365
        """
356
366
        # In the future we will have a single api for all stores for
359
369
        super(Repository, self).__init__()
360
370
        self._format = _format
361
371
        # the following are part of the public API for Repository:
362
 
        self.bzrdir = controldir
 
372
        self.bzrdir = a_bzrdir
363
373
        self.control_files = control_files
 
374
        self._transport = control_files._transport
 
375
        self.base = self._transport.base
364
376
        # for tests
365
377
        self._write_group = None
366
378
        # Additional places to query for data.
404
416
        """
405
417
        if self.__class__ is not other.__class__:
406
418
            return False
407
 
        return (self.control_url == other.control_url)
 
419
        return (self._transport.base == other._transport.base)
408
420
 
409
421
    def is_in_write_group(self):
410
422
        """Return True if there is an open write group.
547
559
            def __init__(self):
548
560
                self.first_call = True
549
561
 
550
 
            def __call__(self, controldir):
551
 
                # On the first call, the parameter is always the controldir
 
562
            def __call__(self, bzrdir):
 
563
                # On the first call, the parameter is always the bzrdir
552
564
                # containing the current repo.
553
565
                if not self.first_call:
554
566
                    try:
555
 
                        repository = controldir.open_repository()
 
567
                        repository = bzrdir.open_repository()
556
568
                    except errors.NoRepositoryPresent:
557
569
                        pass
558
570
                    else:
559
571
                        return False, ([], repository)
560
572
                self.first_call = False
561
 
                value = (controldir.list_branches(), None)
 
573
                value = (bzrdir.list_branches(), None)
562
574
                return True, value
563
575
 
564
576
        ret = []
565
 
        for branches, repository in controldir.ControlDir.find_bzrdirs(
 
577
        for branches, repository in bzrdir.BzrDir.find_bzrdirs(
566
578
                self.user_transport, evaluate=Evaluator()):
567
579
            if branches is not None:
568
580
                ret.extend(branches)
602
614
        For instance, if the repository is at URL/.bzr/repository,
603
615
        Repository.open(URL) -> a Repository instance.
604
616
        """
605
 
        control = controldir.ControlDir.open(base)
 
617
        control = bzrdir.BzrDir.open(base)
606
618
        return control.open_repository()
607
619
 
608
620
    def copy_content_into(self, destination, revision_id=None):
746
758
                repo.unlock()
747
759
 
748
760
    @needs_read_lock
749
 
    def clone(self, controldir, revision_id=None):
750
 
        """Clone this repository into controldir using the current format.
 
761
    def clone(self, a_bzrdir, revision_id=None):
 
762
        """Clone this repository into a_bzrdir using the current format.
751
763
 
752
764
        Currently no check is made that the format of this repository and
753
765
        the bzrdir format are compatible. FIXME RBC 20060201.
756
768
        """
757
769
        # TODO: deprecate after 0.16; cloning this with all its settings is
758
770
        # probably not very useful -- mbp 20070423
759
 
        dest_repo = self._create_sprouting_repo(
760
 
            controldir, shared=self.is_shared())
 
771
        dest_repo = self._create_sprouting_repo(a_bzrdir, shared=self.is_shared())
761
772
        self.copy_content_into(dest_repo, revision_id)
762
773
        return dest_repo
763
774
 
930
941
        parent_ids.discard(_mod_revision.NULL_REVISION)
931
942
        return parent_ids
932
943
 
 
944
    def fileids_altered_by_revision_ids(self, revision_ids):
 
945
        """Find the file ids and versions affected by revisions.
 
946
 
 
947
        :param revisions: an iterable containing revision ids.
 
948
        :return: a dictionary mapping altered file-ids to an iterable of
 
949
            revision_ids. Each altered file-ids has the exact revision_ids
 
950
            that altered it listed explicitly.
 
951
        """
 
952
        raise NotImplementedError(self.fileids_altered_by_revision_ids)
 
953
 
933
954
    def iter_files_bytes(self, desired_files):
934
955
        """Iterate through file versions.
935
956
 
1184
1205
        plaintext = testament.as_short_text()
1185
1206
        self.store_revision_signature(gpg_strategy, plaintext, revision_id)
1186
1207
 
1187
 
    @needs_read_lock
1188
 
    def verify_revision(self, revision_id, gpg_strategy):
1189
 
        """Verify the signature on a revision.
1190
 
        
1191
 
        :param revision_id: the revision to verify
1192
 
        :gpg_strategy: the GPGStrategy object to used
1193
 
        
1194
 
        :return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value
1195
 
        """
1196
 
        if not self.has_signature_for_revision_id(revision_id):
1197
 
            return gpg.SIGNATURE_NOT_SIGNED, None
1198
 
        signature = self.get_signature_text(revision_id)
1199
 
 
1200
 
        testament = _mod_testament.Testament.from_revision(self, revision_id)
1201
 
        plaintext = testament.as_short_text()
1202
 
 
1203
 
        return gpg_strategy.verify(signature, plaintext)
1204
 
 
1205
1208
    def has_signature_for_revision_id(self, revision_id):
1206
1209
        """Query for a revision signature for revision_id in the repository."""
1207
1210
        raise NotImplementedError(self.has_signature_for_revision_id)
1312
1315
 
1313
1316
    def get_default(self):
1314
1317
        """Return the current default format."""
1315
 
        return controldir.format_registry.make_bzrdir('default').repository_format
 
1318
        from bzrlib import bzrdir
 
1319
        return bzrdir.format_registry.make_bzrdir('default').repository_format
1316
1320
 
1317
1321
 
1318
1322
network_format_registry = registry.FormatRegistry()
1361
1365
    created.
1362
1366
 
1363
1367
    Common instance attributes:
1364
 
    _matchingbzrdir - the controldir format that the repository format was
 
1368
    _matchingbzrdir - the bzrdir format that the repository format was
1365
1369
    originally written to work with. This can be used if manually
1366
1370
    constructing a bzrdir and repository, or more commonly for test suite
1367
1371
    parameterization.
1405
1409
    revision_graph_can_have_wrong_parents = None
1406
1410
    # Does this format support rich root data?
1407
1411
    rich_root_data = None
1408
 
    # Does this format support explicitly versioned directories?
1409
 
    supports_versioned_directories = None
1410
 
    # Can other repositories be nested into one of this format?
1411
 
    supports_nesting_repositories = None
1412
1412
 
1413
1413
    def __repr__(self):
1414
1414
        return "%s()" % self.__class__.__name__
1466
1466
        """Return the short description for this format."""
1467
1467
        raise NotImplementedError(self.get_format_description)
1468
1468
 
1469
 
    def initialize(self, controldir, shared=False):
1470
 
        """Initialize a repository of this format in controldir.
 
1469
    def initialize(self, a_bzrdir, shared=False):
 
1470
        """Initialize a repository of this format in a_bzrdir.
1471
1471
 
1472
 
        :param controldir: The controldir to put the new repository in it.
 
1472
        :param a_bzrdir: The bzrdir to put the new repository in it.
1473
1473
        :param shared: The repository should be initialized as a sharable one.
1474
1474
        :returns: The new repository object.
1475
1475
 
1476
1476
        This may raise UninitializableFormat if shared repository are not
1477
 
        compatible the controldir.
 
1477
        compatible the a_bzrdir.
1478
1478
        """
1479
1479
        raise NotImplementedError(self.initialize)
1480
1480
 
1516
1516
                'Does not support nested trees', target_format,
1517
1517
                from_format=self)
1518
1518
 
1519
 
    def open(self, controldir, _found=False):
1520
 
        """Return an instance of this format for a controldir.
 
1519
    def open(self, a_bzrdir, _found=False):
 
1520
        """Return an instance of this format for the bzrdir a_bzrdir.
1521
1521
 
1522
1522
        _found is a private parameter, do not use it.
1523
1523
        """
1524
1524
        raise NotImplementedError(self.open)
1525
1525
 
1526
 
    def _run_post_repo_init_hooks(self, repository, controldir, shared):
1527
 
        from bzrlib.controldir import ControlDir, RepoInitHookParams
1528
 
        hooks = ControlDir.hooks['post_repo_init']
 
1526
    def _run_post_repo_init_hooks(self, repository, a_bzrdir, shared):
 
1527
        from bzrlib.bzrdir import BzrDir, RepoInitHookParams
 
1528
        hooks = BzrDir.hooks['post_repo_init']
1529
1529
        if not hooks:
1530
1530
            return
1531
 
        params = RepoInitHookParams(repository, self, controldir, shared)
 
1531
        params = RepoInitHookParams(repository, self, a_bzrdir, shared)
1532
1532
        for hook in hooks:
1533
1533
            hook(params)
1534
1534
 
1540
1540
    supports_tree_reference = False
1541
1541
    supports_external_lookups = False
1542
1542
    supports_leaving_lock = True
1543
 
    supports_nesting_repositories = True
1544
1543
 
1545
1544
    @property
1546
1545
    def _matchingbzrdir(self):
1587
1586
# formats which have no format string are not discoverable or independently
1588
1587
# creatable on disk, so are not registered in format_registry.  They're
1589
1588
# all in bzrlib.repofmt.knitreponow.  When an instance of one of these is
1590
 
# needed, it's constructed directly by the ControlDir.  Non-native formats where
 
1589
# needed, it's constructed directly by the BzrDir.  Non-native formats where
1591
1590
# the repository is not separately opened are similar.
1592
1591
 
1593
1592
format_registry.register_lazy(
1791
1790
        # trigger an assertion if not such
1792
1791
        repo._format.get_format_string()
1793
1792
        self.repo_dir = repo.bzrdir
1794
 
        pb.update(gettext('Moving repository to repository.backup'))
 
1793
        pb.update('Moving repository to repository.backup')
1795
1794
        self.repo_dir.transport.move('repository', 'repository.backup')
1796
1795
        backup_transport =  self.repo_dir.transport.clone('repository.backup')
1797
1796
        repo._format.check_conversion_target(self.target_format)
1798
1797
        self.source_repo = repo._format.open(self.repo_dir,
1799
1798
            _found=True,
1800
1799
            _override_transport=backup_transport)
1801
 
        pb.update(gettext('Creating new repository'))
 
1800
        pb.update('Creating new repository')
1802
1801
        converted = self.target_format.initialize(self.repo_dir,
1803
1802
                                                  self.source_repo.is_shared())
1804
1803
        converted.lock_write()
1805
1804
        try:
1806
 
            pb.update(gettext('Copying content'))
 
1805
            pb.update('Copying content')
1807
1806
            self.source_repo.copy_content_into(converted)
1808
1807
        finally:
1809
1808
            converted.unlock()
1810
 
        pb.update(gettext('Deleting old repository content'))
 
1809
        pb.update('Deleting old repository content')
1811
1810
        self.repo_dir.transport.delete_tree('repository.backup')
1812
 
        ui.ui_factory.note(gettext('repository converted'))
 
1811
        ui.ui_factory.note('repository converted')
1813
1812
        pb.finished()
1814
1813
 
1815
1814
 
1881
1880
        for list_part in self.list_parts:
1882
1881
            full_list.extend(list_part)
1883
1882
        return iter(full_list)
1884
 
 
1885
 
    def __repr__(self):
1886
 
        return "%s.%s(%s)" % (self.__module__, self.__class__.__name__,
1887
 
                              self.list_parts)