~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Shannon Weyrick
  • Date: 2011-11-04 13:40:04 UTC
  • mfrom: (6238 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6256.
  • Revision ID: weyrick@mozek.us-20111104134004-033t2wqhc3ydzm0a
Merge

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
import bzrlib.bzrdir
17
18
 
18
19
from cStringIO import StringIO
19
20
 
21
22
lazy_import(globals(), """
22
23
import itertools
23
24
from bzrlib import (
24
 
        bzrdir,
25
 
        cache_utf8,
26
 
        cleanup,
27
 
        config as _mod_config,
28
 
        debug,
29
 
        errors,
30
 
        fetch,
31
 
        graph as _mod_graph,
32
 
        lockdir,
33
 
        lockable_files,
34
 
        remote,
35
 
        repository,
36
 
        revision as _mod_revision,
37
 
        rio,
38
 
        tag as _mod_tag,
39
 
        transport,
40
 
        ui,
41
 
        urlutils,
42
 
        )
 
25
    bzrdir,
 
26
    controldir,
 
27
    cache_utf8,
 
28
    cleanup,
 
29
    config as _mod_config,
 
30
    debug,
 
31
    errors,
 
32
    fetch,
 
33
    graph as _mod_graph,
 
34
    lockdir,
 
35
    lockable_files,
 
36
    remote,
 
37
    repository,
 
38
    revision as _mod_revision,
 
39
    rio,
 
40
    tag as _mod_tag,
 
41
    transport,
 
42
    ui,
 
43
    urlutils,
 
44
    )
43
45
from bzrlib.i18n import gettext, ngettext
44
46
""")
45
47
 
107
109
        for existing_fallback_repo in self.repository._fallback_repositories:
108
110
            if existing_fallback_repo.user_url == url:
109
111
                # This fallback is already configured.  This probably only
110
 
                # happens because BzrDir.sprout is a horrible mess.  To avoid
 
112
                # happens because ControlDir.sprout is a horrible mess.  To avoid
111
113
                # confusing _unstack we don't add this a second time.
112
114
                mutter('duplicate activation of fallback %r on %r', url, self)
113
115
                return
171
173
        For instance, if the branch is at URL/.bzr/branch,
172
174
        Branch.open(URL) -> a Branch instance.
173
175
        """
174
 
        control = bzrdir.BzrDir.open(base, _unsupported,
 
176
        control = controldir.ControlDir.open(base, _unsupported,
175
177
                                     possible_transports=possible_transports)
176
178
        return control.open_branch(unsupported=_unsupported)
177
179
 
178
180
    @staticmethod
179
181
    def open_from_transport(transport, name=None, _unsupported=False):
180
182
        """Open the branch rooted at transport"""
181
 
        control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
 
183
        control = controldir.ControlDir.open_from_transport(transport, _unsupported)
182
184
        return control.open_branch(name=name, unsupported=_unsupported)
183
185
 
184
186
    @staticmethod
193
195
        format, UnknownFormatError or UnsupportedFormatError are raised.
194
196
        If there is one, it is returned, along with the unused portion of url.
195
197
        """
196
 
        control, relpath = bzrdir.BzrDir.open_containing(url,
 
198
        control, relpath = controldir.ControlDir.open_containing(url,
197
199
                                                         possible_transports)
198
200
        return control.open_branch(), relpath
199
201
 
881
883
            # stream from one of them to the other.  This does mean doing
882
884
            # separate SSH connection setup, but unstacking is not a
883
885
            # common operation so it's tolerable.
884
 
            new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
 
886
            new_bzrdir = controldir.ControlDir.open(
 
887
                self.bzrdir.root_transport.base)
885
888
            new_repository = new_bzrdir.find_repository()
886
889
            if new_repository._fallback_repositories:
887
890
                raise AssertionError("didn't expect %r to have "
1004
1007
        """
1005
1008
        raise NotImplementedError(self._gen_revision_history)
1006
1009
 
 
1010
    @deprecated_method(deprecated_in((2, 5, 0)))
1007
1011
    @needs_read_lock
1008
1012
    def revision_history(self):
1009
1013
        """Return sequence of revision ids on this branch.
1011
1015
        This method will cache the revision history for as long as it is safe to
1012
1016
        do so.
1013
1017
        """
 
1018
        return self._revision_history()
 
1019
 
 
1020
    def _revision_history(self):
1014
1021
        if 'evil' in debug.debug_flags:
1015
1022
            mutter_callsite(3, "revision_history scales with history.")
1016
1023
        if self._revision_history_cache is not None:
1086
1093
        """Given a revision id, return its revno"""
1087
1094
        if _mod_revision.is_null(revision_id):
1088
1095
            return 0
1089
 
        history = self.revision_history()
 
1096
        history = self._revision_history()
1090
1097
        try:
1091
1098
            return history.index(revision_id) + 1
1092
1099
        except ValueError:
1389
1396
        # TODO: We should probably also check that self.revision_history
1390
1397
        # matches the repository for older branch formats.
1391
1398
        # If looking for the code that cross-checks repository parents against
1392
 
        # the iter_reverse_revision_history output, that is now a repository
 
1399
        # the Graph.iter_lefthand_ancestry output, that is now a repository
1393
1400
        # specific check.
1394
1401
        return result
1395
1402
 
1451
1458
            from_branch = BranchReferenceFormat().initialize(checkout, 
1452
1459
                target_branch=self)
1453
1460
        else:
1454
 
            checkout_branch = bzrdir.BzrDir.create_branch_convenience(
 
1461
            checkout_branch = controldir.ControlDir.create_branch_convenience(
1455
1462
                to_location, force_new_tree=False, format=format)
1456
1463
            checkout = checkout_branch.bzrdir
1457
1464
            checkout_branch.bind(self)
1595
1602
        return not (self == other)
1596
1603
 
1597
1604
    @classmethod
1598
 
    def find_format(klass, a_bzrdir, name=None):
1599
 
        """Return the format for the branch object in a_bzrdir."""
 
1605
    def find_format(klass, controldir, name=None):
 
1606
        """Return the format for the branch object in controldir."""
1600
1607
        try:
1601
 
            transport = a_bzrdir.get_branch_transport(None, name=name)
 
1608
            transport = controldir.get_branch_transport(None, name=name)
1602
1609
            format_string = transport.get_bytes("format")
1603
1610
            return format_registry.get(format_string)
1604
1611
        except errors.NoSuchFile:
1605
 
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
 
1612
            raise errors.NotBranchError(path=transport.base, bzrdir=controldir)
1606
1613
        except KeyError:
1607
1614
            raise errors.UnknownFormatError(format=format_string, kind='branch')
1608
1615
 
1622
1629
        """
1623
1630
        return format_registry._get_all()
1624
1631
 
1625
 
    def get_reference(self, a_bzrdir, name=None):
1626
 
        """Get the target reference of the branch in a_bzrdir.
 
1632
    def get_reference(self, controldir, name=None):
 
1633
        """Get the target reference of the branch in controldir.
1627
1634
 
1628
1635
        format probing must have been completed before calling
1629
1636
        this method - it is assumed that the format of the branch
1630
 
        in a_bzrdir is correct.
 
1637
        in controldir is correct.
1631
1638
 
1632
 
        :param a_bzrdir: The bzrdir to get the branch data from.
 
1639
        :param controldir: The controldir to get the branch data from.
1633
1640
        :param name: Name of the colocated branch to fetch
1634
1641
        :return: None if the branch is not a reference branch.
1635
1642
        """
1636
1643
        return None
1637
1644
 
1638
1645
    @classmethod
1639
 
    def set_reference(self, a_bzrdir, name, to_branch):
1640
 
        """Set the target reference of the branch in a_bzrdir.
 
1646
    def set_reference(self, controldir, name, to_branch):
 
1647
        """Set the target reference of the branch in controldir.
1641
1648
 
1642
1649
        format probing must have been completed before calling
1643
1650
        this method - it is assumed that the format of the branch
1644
 
        in a_bzrdir is correct.
 
1651
        in controldir is correct.
1645
1652
 
1646
 
        :param a_bzrdir: The bzrdir to set the branch reference for.
 
1653
        :param controldir: The controldir to set the branch reference for.
1647
1654
        :param name: Name of colocated branch to set, None for default
1648
1655
        :param to_branch: branch that the checkout is to reference
1649
1656
        """
1657
1664
        """Return the short format description for this format."""
1658
1665
        raise NotImplementedError(self.get_format_description)
1659
1666
 
1660
 
    def _run_post_branch_init_hooks(self, a_bzrdir, name, branch):
 
1667
    def _run_post_branch_init_hooks(self, controldir, name, branch):
1661
1668
        hooks = Branch.hooks['post_branch_init']
1662
1669
        if not hooks:
1663
1670
            return
1664
 
        params = BranchInitHookParams(self, a_bzrdir, name, branch)
 
1671
        params = BranchInitHookParams(self, controldir, name, branch)
1665
1672
        for hook in hooks:
1666
1673
            hook(params)
1667
1674
 
1668
 
    def initialize(self, a_bzrdir, name=None, repository=None,
 
1675
    def initialize(self, controldir, name=None, repository=None,
1669
1676
                   append_revisions_only=None):
1670
 
        """Create a branch of this format in a_bzrdir.
1671
 
        
 
1677
        """Create a branch of this format in controldir.
 
1678
 
1672
1679
        :param name: Name of the colocated branch to create.
1673
1680
        """
1674
1681
        raise NotImplementedError(self.initialize)
1706
1713
        """
1707
1714
        raise NotImplementedError(self.network_name)
1708
1715
 
1709
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
 
1716
    def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
1710
1717
            found_repository=None):
1711
 
        """Return the branch object for a_bzrdir
 
1718
        """Return the branch object for controldir.
1712
1719
 
1713
 
        :param a_bzrdir: A BzrDir that contains a branch.
 
1720
        :param controldir: A ControlDir that contains a branch.
1714
1721
        :param name: Name of colocated branch to open
1715
1722
        :param _found: a private parameter, do not use it. It is used to
1716
1723
            indicate if format probing has already be done.
1936
1943
    There are 4 fields that hooks may wish to access:
1937
1944
 
1938
1945
    :ivar format: the branch format
1939
 
    :ivar bzrdir: the BzrDir where the branch will be/has been initialized
 
1946
    :ivar bzrdir: the ControlDir where the branch will be/has been initialized
1940
1947
    :ivar name: name of colocated branch, if any (or None)
1941
1948
    :ivar branch: the branch created
1942
1949
 
1945
1952
    branch, which refer to the original branch.
1946
1953
    """
1947
1954
 
1948
 
    def __init__(self, format, a_bzrdir, name, branch):
 
1955
    def __init__(self, format, controldir, name, branch):
1949
1956
        """Create a group of BranchInitHook parameters.
1950
1957
 
1951
1958
        :param format: the branch format
1952
 
        :param a_bzrdir: the BzrDir where the branch will be/has been
 
1959
        :param controldir: the ControlDir where the branch will be/has been
1953
1960
            initialized
1954
1961
        :param name: name of colocated branch, if any (or None)
1955
1962
        :param branch: the branch created
1959
1966
        in branch, which refer to the original branch.
1960
1967
        """
1961
1968
        self.format = format
1962
 
        self.bzrdir = a_bzrdir
 
1969
        self.bzrdir = controldir
1963
1970
        self.name = name
1964
1971
        self.branch = branch
1965
1972
 
1975
1982
 
1976
1983
    There are 4 fields that hooks may wish to access:
1977
1984
 
1978
 
    :ivar control_dir: BzrDir of the checkout to change
 
1985
    :ivar control_dir: ControlDir of the checkout to change
1979
1986
    :ivar to_branch: branch that the checkout is to reference
1980
1987
    :ivar force: skip the check for local commits in a heavy checkout
1981
1988
    :ivar revision_id: revision ID to switch to (or None)
1984
1991
    def __init__(self, control_dir, to_branch, force, revision_id):
1985
1992
        """Create a group of SwitchHook parameters.
1986
1993
 
1987
 
        :param control_dir: BzrDir of the checkout to change
 
1994
        :param control_dir: ControlDir of the checkout to change
1988
1995
        :param to_branch: branch that the checkout is to reference
1989
1996
        :param force: skip the check for local commits in a heavy checkout
1990
1997
        :param revision_id: revision ID to switch to (or None)
2077
2084
        except errors.NoSuchFile:
2078
2085
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2079
2086
 
2080
 
    def __init__(self):
2081
 
        super(BranchFormatMetadir, self).__init__()
2082
 
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2083
 
        self._matchingbzrdir.set_branch_format(self)
 
2087
    @property
 
2088
    def _matchingbzrdir(self):
 
2089
        ret = bzrdir.BzrDirMetaFormat1()
 
2090
        ret.set_branch_format(self)
 
2091
        return ret
2084
2092
 
2085
2093
    def supports_tags(self):
2086
2094
        return True
2248
2256
    supports_reference_locations = False
2249
2257
 
2250
2258
 
2251
 
class BranchReferenceFormat(BranchFormat):
 
2259
class BranchReferenceFormat(BranchFormatMetadir):
2252
2260
    """Bzr branch reference format.
2253
2261
 
2254
2262
    Branch references are used in implementing checkouts, they
2297
2305
        self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2298
2306
        return branch
2299
2307
 
2300
 
    def __init__(self):
2301
 
        super(BranchReferenceFormat, self).__init__()
2302
 
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2303
 
        self._matchingbzrdir.set_branch_format(self)
2304
 
 
2305
2308
    def _make_reference_clone_function(format, a_branch):
2306
2309
        """Create a clone() routine for a branch dynamically."""
2307
2310
        def clone(to_bzrdir, revision_id=None,
2336
2339
                    (format, self))
2337
2340
        if location is None:
2338
2341
            location = self.get_reference(a_bzrdir, name)
2339
 
        real_bzrdir = bzrdir.BzrDir.open(
 
2342
        real_bzrdir = controldir.ControlDir.open(
2340
2343
            location, possible_transports=possible_transports)
2341
2344
        result = real_bzrdir.open_branch(name=name, 
2342
2345
            ignore_fallbacks=ignore_fallbacks)
2715
2718
        self._set_revision_history(history)
2716
2719
 
2717
2720
    def _read_last_revision_info(self):
2718
 
        rh = self.revision_history()
 
2721
        rh = self._revision_history()
2719
2722
        revno = len(rh)
2720
2723
        if revno:
2721
2724
            return (revno, rh[-1])
2775
2778
        if revision_id == _mod_revision.NULL_REVISION:
2776
2779
            new_history = []
2777
2780
        else:
2778
 
            new_history = self.revision_history()
 
2781
            new_history = self._revision_history()
2779
2782
        if revision_id is not None and new_history != []:
2780
2783
            try:
2781
2784
                new_history = new_history[:new_history.index(revision_id) + 1]