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
19
18
from cStringIO import StringIO
22
21
lazy_import(globals(), """
24
23
from bzrlib import (
29
config as _mod_config,
38
revision as _mod_revision,
27
config as _mod_config,
36
revision as _mod_revision,
45
43
from bzrlib.i18n import gettext, ngettext
109
107
for existing_fallback_repo in self.repository._fallback_repositories:
110
108
if existing_fallback_repo.user_url == url:
111
109
# This fallback is already configured. This probably only
112
# happens because ControlDir.sprout is a horrible mess. To avoid
110
# happens because BzrDir.sprout is a horrible mess. To avoid
113
111
# confusing _unstack we don't add this a second time.
114
112
mutter('duplicate activation of fallback %r on %r', url, self)
173
171
For instance, if the branch is at URL/.bzr/branch,
174
172
Branch.open(URL) -> a Branch instance.
176
control = controldir.ControlDir.open(base, _unsupported,
174
control = bzrdir.BzrDir.open(base, _unsupported,
177
175
possible_transports=possible_transports)
178
176
return control.open_branch(unsupported=_unsupported)
181
179
def open_from_transport(transport, name=None, _unsupported=False):
182
180
"""Open the branch rooted at transport"""
183
control = controldir.ControlDir.open_from_transport(transport, _unsupported)
181
control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
184
182
return control.open_branch(name=name, unsupported=_unsupported)
195
193
format, UnknownFormatError or UnsupportedFormatError are raised.
196
194
If there is one, it is returned, along with the unused portion of url.
198
control, relpath = controldir.ControlDir.open_containing(url,
196
control, relpath = bzrdir.BzrDir.open_containing(url,
199
197
possible_transports)
200
198
return control.open_branch(), relpath
883
881
# stream from one of them to the other. This does mean doing
884
882
# separate SSH connection setup, but unstacking is not a
885
883
# common operation so it's tolerable.
886
new_bzrdir = controldir.ControlDir.open(
887
self.bzrdir.root_transport.base)
884
new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
888
885
new_repository = new_bzrdir.find_repository()
889
886
if new_repository._fallback_repositories:
890
887
raise AssertionError("didn't expect %r to have "
1008
1005
raise NotImplementedError(self._gen_revision_history)
1010
@deprecated_method(deprecated_in((2, 5, 0)))
1011
1007
@needs_read_lock
1012
1008
def revision_history(self):
1013
1009
"""Return sequence of revision ids on this branch.
1015
1011
This method will cache the revision history for as long as it is safe to
1018
return self._revision_history()
1020
def _revision_history(self):
1021
1014
if 'evil' in debug.debug_flags:
1022
1015
mutter_callsite(3, "revision_history scales with history.")
1023
1016
if self._revision_history_cache is not None:
1093
1086
"""Given a revision id, return its revno"""
1094
1087
if _mod_revision.is_null(revision_id):
1096
history = self._revision_history()
1089
history = self.revision_history()
1098
1091
return history.index(revision_id) + 1
1099
1092
except ValueError:
1396
1389
# TODO: We should probably also check that self.revision_history
1397
1390
# matches the repository for older branch formats.
1398
1391
# If looking for the code that cross-checks repository parents against
1399
# the Graph.iter_lefthand_ancestry output, that is now a repository
1392
# the iter_reverse_revision_history output, that is now a repository
1400
1393
# specific check.
1458
1451
from_branch = BranchReferenceFormat().initialize(checkout,
1459
1452
target_branch=self)
1461
checkout_branch = controldir.ControlDir.create_branch_convenience(
1454
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
1462
1455
to_location, force_new_tree=False, format=format)
1463
1456
checkout = checkout_branch.bzrdir
1464
1457
checkout_branch.bind(self)
1602
1595
return not (self == other)
1605
def find_format(klass, controldir, name=None):
1606
"""Return the format for the branch object in controldir."""
1608
transport = controldir.get_branch_transport(None, name=name)
1609
except errors.NoSuchFile:
1610
raise errors.NotBranchError(path=name, bzrdir=controldir)
1598
def find_format(klass, a_bzrdir, name=None):
1599
"""Return the format for the branch object in a_bzrdir."""
1601
transport = a_bzrdir.get_branch_transport(None, name=name)
1612
1602
format_string = transport.get_bytes("format")
1613
1603
return format_registry.get(format_string)
1614
1604
except errors.NoSuchFile:
1615
raise errors.NotBranchError(path=transport.base, bzrdir=controldir)
1605
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
1616
1606
except KeyError:
1617
1607
raise errors.UnknownFormatError(format=format_string, kind='branch')
1633
1623
return format_registry._get_all()
1635
def get_reference(self, controldir, name=None):
1636
"""Get the target reference of the branch in controldir.
1625
def get_reference(self, a_bzrdir, name=None):
1626
"""Get the target reference of the branch in a_bzrdir.
1638
1628
format probing must have been completed before calling
1639
1629
this method - it is assumed that the format of the branch
1640
in controldir is correct.
1630
in a_bzrdir is correct.
1642
:param controldir: The controldir to get the branch data from.
1632
:param a_bzrdir: The bzrdir to get the branch data from.
1643
1633
:param name: Name of the colocated branch to fetch
1644
1634
:return: None if the branch is not a reference branch.
1649
def set_reference(self, controldir, name, to_branch):
1650
"""Set the target reference of the branch in controldir.
1639
def set_reference(self, a_bzrdir, name, to_branch):
1640
"""Set the target reference of the branch in a_bzrdir.
1652
1642
format probing must have been completed before calling
1653
1643
this method - it is assumed that the format of the branch
1654
in controldir is correct.
1644
in a_bzrdir is correct.
1656
:param controldir: The controldir to set the branch reference for.
1646
:param a_bzrdir: The bzrdir to set the branch reference for.
1657
1647
:param name: Name of colocated branch to set, None for default
1658
1648
:param to_branch: branch that the checkout is to reference
1667
1657
"""Return the short format description for this format."""
1668
1658
raise NotImplementedError(self.get_format_description)
1670
def _run_post_branch_init_hooks(self, controldir, name, branch):
1660
def _run_post_branch_init_hooks(self, a_bzrdir, name, branch):
1671
1661
hooks = Branch.hooks['post_branch_init']
1674
params = BranchInitHookParams(self, controldir, name, branch)
1664
params = BranchInitHookParams(self, a_bzrdir, name, branch)
1675
1665
for hook in hooks:
1678
def initialize(self, controldir, name=None, repository=None,
1668
def initialize(self, a_bzrdir, name=None, repository=None,
1679
1669
append_revisions_only=None):
1680
"""Create a branch of this format in controldir.
1670
"""Create a branch of this format in a_bzrdir.
1682
1672
:param name: Name of the colocated branch to create.
1684
1674
raise NotImplementedError(self.initialize)
1717
1707
raise NotImplementedError(self.network_name)
1719
def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
1709
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
1720
1710
found_repository=None):
1721
"""Return the branch object for controldir.
1711
"""Return the branch object for a_bzrdir
1723
:param controldir: A ControlDir that contains a branch.
1713
:param a_bzrdir: A BzrDir that contains a branch.
1724
1714
:param name: Name of colocated branch to open
1725
1715
:param _found: a private parameter, do not use it. It is used to
1726
1716
indicate if format probing has already be done.
1946
1936
There are 4 fields that hooks may wish to access:
1948
1938
:ivar format: the branch format
1949
:ivar bzrdir: the ControlDir where the branch will be/has been initialized
1939
:ivar bzrdir: the BzrDir where the branch will be/has been initialized
1950
1940
:ivar name: name of colocated branch, if any (or None)
1951
1941
:ivar branch: the branch created
1955
1945
branch, which refer to the original branch.
1958
def __init__(self, format, controldir, name, branch):
1948
def __init__(self, format, a_bzrdir, name, branch):
1959
1949
"""Create a group of BranchInitHook parameters.
1961
1951
:param format: the branch format
1962
:param controldir: the ControlDir where the branch will be/has been
1952
:param a_bzrdir: the BzrDir where the branch will be/has been
1964
1954
:param name: name of colocated branch, if any (or None)
1965
1955
:param branch: the branch created
1986
1976
There are 4 fields that hooks may wish to access:
1988
:ivar control_dir: ControlDir of the checkout to change
1978
:ivar control_dir: BzrDir of the checkout to change
1989
1979
:ivar to_branch: branch that the checkout is to reference
1990
1980
:ivar force: skip the check for local commits in a heavy checkout
1991
1981
:ivar revision_id: revision ID to switch to (or None)
1994
1984
def __init__(self, control_dir, to_branch, force, revision_id):
1995
1985
"""Create a group of SwitchHook parameters.
1997
:param control_dir: ControlDir of the checkout to change
1987
:param control_dir: BzrDir of the checkout to change
1998
1988
:param to_branch: branch that the checkout is to reference
1999
1989
:param force: skip the check for local commits in a heavy checkout
2000
1990
:param revision_id: revision ID to switch to (or None)
2087
2077
except errors.NoSuchFile:
2088
2078
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2091
def _matchingbzrdir(self):
2092
ret = bzrdir.BzrDirMetaFormat1()
2093
ret.set_branch_format(self)
2081
super(BranchFormatMetadir, self).__init__()
2082
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2083
self._matchingbzrdir.set_branch_format(self)
2096
2085
def supports_tags(self):
2259
2248
supports_reference_locations = False
2262
class BranchReferenceFormat(BranchFormatMetadir):
2251
class BranchReferenceFormat(BranchFormat):
2263
2252
"""Bzr branch reference format.
2265
2254
Branch references are used in implementing checkouts, they
2300
2289
raise errors.IncompatibleFormat(self, a_bzrdir._format)
2301
2290
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2302
2291
branch_transport.put_bytes('location',
2303
target_branch.user_url)
2292
target_branch.bzrdir.user_url)
2304
2293
branch_transport.put_bytes('format', self.get_format_string())
2305
2294
branch = self.open(
2306
2295
a_bzrdir, name, _found=True,
2308
2297
self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2301
super(BranchReferenceFormat, self).__init__()
2302
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2303
self._matchingbzrdir.set_branch_format(self)
2311
2305
def _make_reference_clone_function(format, a_branch):
2312
2306
"""Create a clone() routine for a branch dynamically."""
2313
2307
def clone(to_bzrdir, revision_id=None,
2342
2336
(format, self))
2343
2337
if location is None:
2344
2338
location = self.get_reference(a_bzrdir, name)
2345
real_bzrdir = controldir.ControlDir.open(
2339
real_bzrdir = bzrdir.BzrDir.open(
2346
2340
location, possible_transports=possible_transports)
2347
2341
result = real_bzrdir.open_branch(name=name,
2348
2342
ignore_fallbacks=ignore_fallbacks)
2438
2432
raise ValueError('a_bzrdir must be supplied')
2440
2434
self.bzrdir = a_bzrdir
2441
self._user_transport = self.bzrdir.transport.clone('..')
2442
if name is not None:
2443
self._user_transport.set_segment_parameter(
2444
"branch", urlutils.escape(name))
2445
self._base = self._user_transport.base
2435
self._base = self.bzrdir.transport.clone('..').base
2446
2436
self.name = name
2437
# XXX: We should be able to just do
2438
# self.base = self.bzrdir.root_transport.base
2439
# but this does not quite work yet -- mbp 20080522
2447
2440
self._format = _format
2448
2441
if _control_files is None:
2449
2442
raise ValueError('BzrBranch _control_files is None')
2453
2446
Branch.__init__(self)
2455
2448
def __str__(self):
2456
return '%s(%s)' % (self.__class__.__name__, self.user_url)
2449
if self.name is None:
2450
return '%s(%s)' % (self.__class__.__name__, self.user_url)
2452
return '%s(%s,%s)' % (self.__class__.__name__, self.user_url,
2458
2455
__repr__ = __str__
2464
2461
base = property(_get_base, doc="The URL for the root of this branch.")
2467
def user_transport(self):
2468
return self._user_transport
2470
2463
def _get_config(self):
2471
2464
return _mod_config.TransportConfig(self._transport, 'branch.conf')
2473
def _get_config_store(self):
2474
return _mod_config.BranchStore(self)
2476
2466
def is_locked(self):
2477
2467
return self.control_files.is_locked()
2785
2775
if revision_id == _mod_revision.NULL_REVISION:
2786
2776
new_history = []
2788
new_history = self._revision_history()
2778
new_history = self.revision_history()
2789
2779
if revision_id is not None and new_history != []:
2791
2781
new_history = new_history[:new_history.index(revision_id) + 1]
3037
3027
except errors.RevisionNotPresent, e:
3038
3028
raise errors.GhostRevisionsHaveNoRevno(revision_id, e.revision_id)
3039
3029
index = len(self._partial_revision_history_cache) - 1
3041
raise errors.NoSuchRevision(self, revision_id)
3042
3030
if self._partial_revision_history_cache[index] != revision_id:
3043
3031
raise errors.NoSuchRevision(self, revision_id)
3044
3032
return self.revno() - index