~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

(jelmer) Use the absolute_import feature everywhere in bzrlib,
 and add a source test to make sure it's used everywhere. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
from bzrlib.lazy_import import lazy_import
18
20
lazy_import(globals(), """
19
21
import itertools
20
22
import time
21
23
 
22
24
from bzrlib import (
23
 
    bzrdir,
24
25
    config,
25
26
    controldir,
26
27
    debug,
39
40
""")
40
41
 
41
42
from bzrlib import (
 
43
    bzrdir,
42
44
    errors,
43
45
    registry,
44
46
    symbol_versioning,
78
80
    # being committed to
79
81
    updates_branch = False
80
82
 
81
 
    def __init__(self, repository, parents, config, timestamp=None,
 
83
    def __init__(self, repository, parents, config_stack, timestamp=None,
82
84
                 timezone=None, committer=None, revprops=None,
83
85
                 revision_id=None, lossy=False):
84
86
        """Initiate a CommitBuilder.
93
95
        :param lossy: Whether to discard data that can not be natively
94
96
            represented, when pushing to a foreign VCS 
95
97
        """
96
 
        self._config = config
 
98
        self._config_stack = config_stack
97
99
        self._lossy = lossy
98
100
 
99
101
        if committer is None:
100
 
            self._committer = self._config.username()
 
102
            self._committer = self._config_stack.get('email')
101
103
        elif not isinstance(committer, unicode):
102
104
            self._committer = committer.decode() # throw if non-ascii
103
105
        else:
675
677
    def _resume_write_group(self, tokens):
676
678
        raise errors.UnsuspendableWriteGroup(self)
677
679
 
678
 
    def fetch(self, source, revision_id=None, find_ghosts=False,
679
 
            fetch_spec=None):
 
680
    def fetch(self, source, revision_id=None, find_ghosts=False):
680
681
        """Fetch the content required to construct revision_id from source.
681
682
 
682
 
        If revision_id is None and fetch_spec is None, then all content is
683
 
        copied.
 
683
        If revision_id is None, then all content is copied.
684
684
 
685
685
        fetch() may not be used when the repository is in a write group -
686
686
        either finish the current write group before using fetch, or use
692
692
        :param revision_id: If specified, all the content needed for this
693
693
            revision ID will be copied to the target.  Fetch will determine for
694
694
            itself which content needs to be copied.
695
 
        :param fetch_spec: If specified, a SearchResult or
696
 
            PendingAncestryResult that describes which revisions to copy.  This
697
 
            allows copying multiple heads at once.  Mutually exclusive with
698
 
            revision_id.
699
695
        """
700
 
        if fetch_spec is not None and revision_id is not None:
701
 
            raise AssertionError(
702
 
                "fetch_spec and revision_id are mutually exclusive.")
703
696
        if self.is_in_write_group():
704
697
            raise errors.InternalBzrError(
705
698
                "May not fetch while in a write group.")
707
700
        # TODO: lift out to somewhere common with RemoteRepository
708
701
        # <https://bugs.launchpad.net/bzr/+bug/401646>
709
702
        if (self.has_same_location(source)
710
 
            and fetch_spec is None
711
703
            and self._has_same_fallbacks(source)):
712
704
            # check that last_revision is in 'from' and then return a
713
705
            # no-operation.
716
708
                self.get_revision(revision_id)
717
709
            return 0, []
718
710
        inter = InterRepository.get(source, self)
719
 
        return inter.fetch(revision_id=revision_id,
720
 
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
 
711
        return inter.fetch(revision_id=revision_id, find_ghosts=find_ghosts)
721
712
 
722
713
    def create_bundle(self, target, base, fileobj, format=None):
723
714
        return serializer.write_bundle(self, target, base, fileobj, format)
724
715
 
725
 
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
716
    def get_commit_builder(self, branch, parents, config_stack, timestamp=None,
726
717
                           timezone=None, committer=None, revprops=None,
727
718
                           revision_id=None, lossy=False):
728
719
        """Obtain a CommitBuilder for this repository.
729
720
 
730
721
        :param branch: Branch to commit to.
731
722
        :param parents: Revision ids of the parents of the new revision.
732
 
        :param config: Configuration to use.
 
723
        :param config_stack: Configuration stack to use.
733
724
        :param timestamp: Optional timestamp recorded for commit.
734
725
        :param timezone: Optional timezone for timestamp.
735
726
        :param committer: Optional committer to set for commit.
1158
1149
                [parents_provider, other_repository._make_parents_provider()])
1159
1150
        return graph.Graph(parents_provider)
1160
1151
 
1161
 
    def revision_ids_to_search_result(self, result_set):
1162
 
        """Convert a set of revision ids to a graph SearchResult."""
1163
 
        result_parents = set()
1164
 
        for parents in self.get_graph().get_parent_map(
1165
 
            result_set).itervalues():
1166
 
            result_parents.update(parents)
1167
 
        included_keys = result_set.intersection(result_parents)
1168
 
        start_keys = result_set.difference(included_keys)
1169
 
        exclude_keys = result_parents.difference(result_set)
1170
 
        result = graph.SearchResult(start_keys, exclude_keys,
1171
 
            len(result_set), result_set)
1172
 
        return result
1173
 
 
1174
1152
    @needs_write_lock
1175
1153
    def set_make_working_trees(self, new_value):
1176
1154
        """Set the policy flag for making working trees when creating branches.
1433
1411
        return not self == other
1434
1412
 
1435
1413
    @classmethod
1436
 
    def find_format(klass, a_bzrdir):
1437
 
        """Return the format for the repository object in a_bzrdir.
1438
 
 
1439
 
        This is used by bzr native formats that have a "format" file in
1440
 
        the repository.  Other methods may be used by different types of
1441
 
        control directory.
1442
 
        """
1443
 
        try:
1444
 
            transport = a_bzrdir.get_repository_transport(None)
1445
 
            format_string = transport.get_bytes("format")
1446
 
            return format_registry.get(format_string)
1447
 
        except errors.NoSuchFile:
1448
 
            raise errors.NoRepositoryPresent(a_bzrdir)
1449
 
        except KeyError:
1450
 
            raise errors.UnknownFormatError(format=format_string,
1451
 
                                            kind='repository')
1452
 
 
1453
 
    @classmethod
1454
1414
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
1455
1415
    def register_format(klass, format):
1456
1416
        format_registry.register(format)
1466
1426
        """Return the current default format."""
1467
1427
        return format_registry.get_default()
1468
1428
 
1469
 
    def get_format_string(self):
1470
 
        """Return the ASCII format string that identifies this format.
1471
 
 
1472
 
        Note that in pre format ?? repositories the format string is
1473
 
        not permitted nor written to disk.
1474
 
        """
1475
 
        raise NotImplementedError(self.get_format_string)
1476
 
 
1477
1429
    def get_format_description(self):
1478
1430
        """Return the short description for this format."""
1479
1431
        raise NotImplementedError(self.get_format_description)
1545
1497
            hook(params)
1546
1498
 
1547
1499
 
1548
 
class MetaDirRepositoryFormat(RepositoryFormat):
 
1500
class RepositoryFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, RepositoryFormat):
1549
1501
    """Common base class for the new repositories using the metadir layout."""
1550
1502
 
1551
1503
    rich_root_data = False
1561
1513
        return matching
1562
1514
 
1563
1515
    def __init__(self):
1564
 
        super(MetaDirRepositoryFormat, self).__init__()
 
1516
        RepositoryFormat.__init__(self)
 
1517
        bzrdir.BzrDirMetaComponentFormat.__init__(self)
1565
1518
 
1566
1519
    def _create_control_files(self, a_bzrdir):
1567
1520
        """Create the required files and the initial control_files object."""
1591
1544
        finally:
1592
1545
            control_files.unlock()
1593
1546
 
1594
 
    def network_name(self):
1595
 
        """Metadir formats have matching disk and network format strings."""
1596
 
        return self.get_format_string()
 
1547
    @classmethod
 
1548
    def find_format(klass, a_bzrdir):
 
1549
        """Return the format for the repository object in a_bzrdir.
 
1550
 
 
1551
        This is used by bzr native formats that have a "format" file in
 
1552
        the repository.  Other methods may be used by different types of
 
1553
        control directory.
 
1554
        """
 
1555
        try:
 
1556
            transport = a_bzrdir.get_repository_transport(None)
 
1557
            format_string = transport.get_bytes("format")
 
1558
        except errors.NoSuchFile:
 
1559
            raise errors.NoRepositoryPresent(a_bzrdir)
 
1560
        return klass._find_format(format_registry, 'repository', format_string)
1597
1561
 
1598
1562
 
1599
1563
# formats which have no format string are not discoverable or independently
1716
1680
        self.target.fetch(self.source, revision_id=revision_id)
1717
1681
 
1718
1682
    @needs_write_lock
1719
 
    def fetch(self, revision_id=None, find_ghosts=False,
1720
 
            fetch_spec=None):
 
1683
    def fetch(self, revision_id=None, find_ghosts=False):
1721
1684
        """Fetch the content required to construct revision_id.
1722
1685
 
1723
1686
        The content is copied from self.source to self.target.