~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Martin Packman
  • Date: 2011-11-29 16:14:12 UTC
  • mto: This revision was merged to the branch mainline in revision 6327.
  • Revision ID: martin.packman@canonical.com-20111129161412-mx4yu5mg6xsaty46
Require the dulwich package when using py2exe with the git plugin enabled

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
 
 
19
17
from bzrlib.lazy_import import lazy_import
20
18
lazy_import(globals(), """
21
19
import itertools
22
20
import time
23
21
 
24
22
from bzrlib import (
 
23
    bzrdir,
25
24
    config,
26
25
    controldir,
27
26
    debug,
40
39
""")
41
40
 
42
41
from bzrlib import (
43
 
    bzrdir,
44
42
    errors,
45
43
    registry,
46
44
    symbol_versioning,
80
78
    # being committed to
81
79
    updates_branch = False
82
80
 
83
 
    def __init__(self, repository, parents, config_stack, timestamp=None,
 
81
    def __init__(self, repository, parents, config, timestamp=None,
84
82
                 timezone=None, committer=None, revprops=None,
85
83
                 revision_id=None, lossy=False):
86
84
        """Initiate a CommitBuilder.
95
93
        :param lossy: Whether to discard data that can not be natively
96
94
            represented, when pushing to a foreign VCS 
97
95
        """
98
 
        self._config_stack = config_stack
 
96
        self._config = config
99
97
        self._lossy = lossy
100
98
 
101
99
        if committer is None:
102
 
            self._committer = self._config_stack.get('email')
 
100
            self._committer = self._config.username()
103
101
        elif not isinstance(committer, unicode):
104
102
            self._committer = committer.decode() # throw if non-ascii
105
103
        else:
677
675
    def _resume_write_group(self, tokens):
678
676
        raise errors.UnsuspendableWriteGroup(self)
679
677
 
680
 
    def fetch(self, source, revision_id=None, find_ghosts=False):
 
678
    def fetch(self, source, revision_id=None, find_ghosts=False,
 
679
            fetch_spec=None):
681
680
        """Fetch the content required to construct revision_id from source.
682
681
 
683
 
        If revision_id is None, then all content is copied.
 
682
        If revision_id is None and fetch_spec is None, then all content is
 
683
        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.
695
699
        """
 
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.")
696
703
        if self.is_in_write_group():
697
704
            raise errors.InternalBzrError(
698
705
                "May not fetch while in a write group.")
700
707
        # TODO: lift out to somewhere common with RemoteRepository
701
708
        # <https://bugs.launchpad.net/bzr/+bug/401646>
702
709
        if (self.has_same_location(source)
 
710
            and fetch_spec is None
703
711
            and self._has_same_fallbacks(source)):
704
712
            # check that last_revision is in 'from' and then return a
705
713
            # no-operation.
708
716
                self.get_revision(revision_id)
709
717
            return 0, []
710
718
        inter = InterRepository.get(source, self)
711
 
        return inter.fetch(revision_id=revision_id, find_ghosts=find_ghosts)
 
719
        return inter.fetch(revision_id=revision_id,
 
720
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
712
721
 
713
722
    def create_bundle(self, target, base, fileobj, format=None):
714
723
        return serializer.write_bundle(self, target, base, fileobj, format)
715
724
 
716
 
    def get_commit_builder(self, branch, parents, config_stack, timestamp=None,
 
725
    def get_commit_builder(self, branch, parents, config, timestamp=None,
717
726
                           timezone=None, committer=None, revprops=None,
718
727
                           revision_id=None, lossy=False):
719
728
        """Obtain a CommitBuilder for this repository.
720
729
 
721
730
        :param branch: Branch to commit to.
722
731
        :param parents: Revision ids of the parents of the new revision.
723
 
        :param config_stack: Configuration stack to use.
 
732
        :param config: Configuration to use.
724
733
        :param timestamp: Optional timestamp recorded for commit.
725
734
        :param timezone: Optional timezone for timestamp.
726
735
        :param committer: Optional committer to set for commit.
1149
1158
                [parents_provider, other_repository._make_parents_provider()])
1150
1159
        return graph.Graph(parents_provider)
1151
1160
 
 
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
 
1152
1174
    @needs_write_lock
1153
1175
    def set_make_working_trees(self, new_value):
1154
1176
        """Set the policy flag for making working trees when creating branches.
1411
1433
        return not self == other
1412
1434
 
1413
1435
    @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
1414
1454
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
1415
1455
    def register_format(klass, format):
1416
1456
        format_registry.register(format)
1426
1466
        """Return the current default format."""
1427
1467
        return format_registry.get_default()
1428
1468
 
 
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
 
1429
1477
    def get_format_description(self):
1430
1478
        """Return the short description for this format."""
1431
1479
        raise NotImplementedError(self.get_format_description)
1497
1545
            hook(params)
1498
1546
 
1499
1547
 
1500
 
class RepositoryFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, RepositoryFormat):
 
1548
class MetaDirRepositoryFormat(RepositoryFormat):
1501
1549
    """Common base class for the new repositories using the metadir layout."""
1502
1550
 
1503
1551
    rich_root_data = False
1513
1561
        return matching
1514
1562
 
1515
1563
    def __init__(self):
1516
 
        RepositoryFormat.__init__(self)
1517
 
        bzrdir.BzrDirMetaComponentFormat.__init__(self)
 
1564
        super(MetaDirRepositoryFormat, self).__init__()
1518
1565
 
1519
1566
    def _create_control_files(self, a_bzrdir):
1520
1567
        """Create the required files and the initial control_files object."""
1544
1591
        finally:
1545
1592
            control_files.unlock()
1546
1593
 
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)
 
1594
    def network_name(self):
 
1595
        """Metadir formats have matching disk and network format strings."""
 
1596
        return self.get_format_string()
1561
1597
 
1562
1598
 
1563
1599
# formats which have no format string are not discoverable or independently
1680
1716
        self.target.fetch(self.source, revision_id=revision_id)
1681
1717
 
1682
1718
    @needs_write_lock
1683
 
    def fetch(self, revision_id=None, find_ghosts=False):
 
1719
    def fetch(self, revision_id=None, find_ghosts=False,
 
1720
            fetch_spec=None):
1684
1721
        """Fetch the content required to construct revision_id.
1685
1722
 
1686
1723
        The content is copied from self.source to self.target.