1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
1
# Copyright (C) 2005-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
168
168
control = bzrdir.BzrDir.open(base, _unsupported,
169
169
possible_transports=possible_transports)
170
return control.open_branch(_unsupported)
170
return control.open_branch(unsupported=_unsupported)
173
def open_from_transport(transport, _unsupported=False):
173
def open_from_transport(transport, name=None, _unsupported=False):
174
174
"""Open the branch rooted at transport"""
175
175
control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
176
return control.open_branch(_unsupported)
176
return control.open_branch(name=name, unsupported=_unsupported)
179
179
def open_containing(url, possible_transports=None):
217
217
def _get_fallback_repository(self, url):
218
218
"""Get the repository we fallback to at url."""
219
219
url = urlutils.join(self.base, url)
220
a_bzrdir = bzrdir.BzrDir.open(url,
220
a_branch = Branch.open(url,
221
221
possible_transports=[self.bzrdir.root_transport])
222
return a_bzrdir.open_branch().repository
222
return a_branch.repository
224
224
def _get_tags_bytes(self):
225
225
"""Get the bytes of a serialised tags dict.
1317
1317
if lightweight:
1318
1318
format = self._get_checkout_format()
1319
1319
checkout = format.initialize_on_transport(t)
1320
from_branch = BranchReferenceFormat().initialize(checkout, self)
1320
from_branch = BranchReferenceFormat().initialize(checkout,
1322
1323
format = self._get_checkout_format()
1323
1324
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
1365
1366
def supports_tags(self):
1366
1367
return self._format.supports_tags()
1369
def automatic_tag_name(self, revision_id):
1370
"""Try to automatically find the tag name for a revision.
1372
:param revision_id: Revision id of the revision.
1373
:return: A tag name or None if no tag name could be determined.
1375
for hook in Branch.hooks['automatic_tag_name']:
1376
ret = hook(self, revision_id)
1368
1381
def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
1370
1383
"""Ensure that revision_b is a descendant of revision_a.
1434
1447
return not (self == other)
1437
def find_format(klass, a_bzrdir):
1450
def find_format(klass, a_bzrdir, name=None):
1438
1451
"""Return the format for the branch object in a_bzrdir."""
1440
transport = a_bzrdir.get_branch_transport(None)
1453
transport = a_bzrdir.get_branch_transport(None, name=name)
1441
1454
format_string = transport.get_bytes("format")
1442
1455
return klass._formats[format_string]
1443
1456
except errors.NoSuchFile:
1483
1496
"""Return the short format description for this format."""
1484
1497
raise NotImplementedError(self.get_format_description)
1486
def _initialize_helper(self, a_bzrdir, utf8_files, lock_type='metadir',
1499
def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1500
lock_type='metadir', set_format=True):
1488
1501
"""Initialize a branch in a bzrdir, with specified files
1490
1503
:param a_bzrdir: The bzrdir to initialize the branch in
1491
1504
:param utf8_files: The files to create as a list of
1492
1505
(filename, content) tuples
1506
:param name: Name of colocated branch to create, if any
1493
1507
:param set_format: If True, set the format with
1494
1508
self.get_format_string. (BzrBranch4 has its format set
1496
1510
:return: a branch in this format
1498
1512
mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
1499
branch_transport = a_bzrdir.get_branch_transport(self)
1513
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1501
1515
'metadir': ('lock', lockdir.LockDir),
1502
1516
'branch4': ('branch-lock', lockable_files.TransportLock),
1525
1539
control_files.unlock()
1526
return self.open(a_bzrdir, _found=True)
1540
return self.open(a_bzrdir, name, _found=True)
1528
def initialize(self, a_bzrdir):
1529
"""Create a branch of this format in a_bzrdir."""
1542
def initialize(self, a_bzrdir, name=None):
1543
"""Create a branch of this format in a_bzrdir.
1545
:param name: Name of the colocated branch to create.
1530
1547
raise NotImplementedError(self.initialize)
1532
1549
def is_supported(self):
1563
1580
raise NotImplementedError(self.network_name)
1565
def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1582
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1566
1583
"""Return the branch object for a_bzrdir
1568
1585
:param a_bzrdir: A BzrDir that contains a branch.
1586
:param name: Name of colocated branch to open
1569
1587
:param _found: a private parameter, do not use it. It is used to
1570
1588
indicate if format probing has already be done.
1571
1589
:param ignore_fallbacks: when set, no fallback branches will be opened
1679
1697
"multiple hooks installed for transform_fallback_location, "
1680
1698
"all are called with the url returned from the previous hook."
1681
1699
"The order is however undefined.", (1, 9), None))
1700
self.create_hook(HookPoint('automatic_tag_name',
1701
"Called to determine an automatic tag name for a revision."
1702
"automatic_tag_name is called with (branch, revision_id) and "
1703
"should return a tag name or None if no tag name could be "
1704
"determined. The first non-None tag name returned will be used.",
1684
1709
# install the default hooks into the Branch class.
1735
1760
"""See BranchFormat.get_format_description()."""
1736
1761
return "Branch format 4"
1738
def initialize(self, a_bzrdir):
1763
def initialize(self, a_bzrdir, name=None):
1739
1764
"""Create a branch of this format in a_bzrdir."""
1740
1765
utf8_files = [('revision-history', ''),
1741
1766
('branch-name', ''),
1743
return self._initialize_helper(a_bzrdir, utf8_files,
1768
return self._initialize_helper(a_bzrdir, utf8_files, name=name,
1744
1769
lock_type='branch4', set_format=False)
1746
1771
def __init__(self):
1751
1776
"""The network name for this format is the control dirs disk label."""
1752
1777
return self._matchingbzrdir.get_format_string()
1754
def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1779
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1755
1780
"""See BranchFormat.open()."""
1757
1782
# we are being called directly and must probe.
1780
1806
return self.get_format_string()
1782
def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1808
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1783
1809
"""See BranchFormat.open()."""
1785
format = BranchFormat.find_format(a_bzrdir)
1811
format = BranchFormat.find_format(a_bzrdir, name=name)
1786
1812
if format.__class__ != self.__class__:
1787
1813
raise AssertionError("wrong format %r found for %r" %
1788
1814
(format, self))
1790
transport = a_bzrdir.get_branch_transport(None)
1816
transport = a_bzrdir.get_branch_transport(None, name=name)
1791
1817
control_files = lockable_files.LockableFiles(transport, 'lock',
1792
1818
lockdir.LockDir)
1793
1819
return self._branch_class()(_format=self,
1794
1820
_control_files=control_files,
1795
1822
a_bzrdir=a_bzrdir,
1796
1823
_repository=a_bzrdir.find_repository(),
1797
1824
ignore_fallbacks=ignore_fallbacks)
1831
1858
"""See BranchFormat.get_format_description()."""
1832
1859
return "Branch format 5"
1834
def initialize(self, a_bzrdir):
1861
def initialize(self, a_bzrdir, name=None):
1835
1862
"""Create a branch of this format in a_bzrdir."""
1836
1863
utf8_files = [('revision-history', ''),
1837
1864
('branch-name', ''),
1839
return self._initialize_helper(a_bzrdir, utf8_files)
1866
return self._initialize_helper(a_bzrdir, utf8_files, name)
1841
1868
def supports_tags(self):
1864
1891
"""See BranchFormat.get_format_description()."""
1865
1892
return "Branch format 6"
1867
def initialize(self, a_bzrdir):
1894
def initialize(self, a_bzrdir, name=None):
1868
1895
"""Create a branch of this format in a_bzrdir."""
1869
1896
utf8_files = [('last-revision', '0 null:\n'),
1870
1897
('branch.conf', ''),
1873
return self._initialize_helper(a_bzrdir, utf8_files)
1900
return self._initialize_helper(a_bzrdir, utf8_files, name)
1875
1902
def make_tags(self, branch):
1876
1903
"""See bzrlib.branch.BranchFormat.make_tags()."""
1894
1921
"""See BranchFormat.get_format_description()."""
1895
1922
return "Branch format 8"
1897
def initialize(self, a_bzrdir):
1924
def initialize(self, a_bzrdir, name=None):
1898
1925
"""Create a branch of this format in a_bzrdir."""
1899
1926
utf8_files = [('last-revision', '0 null:\n'),
1900
1927
('branch.conf', ''),
1902
1929
('references', '')
1904
return self._initialize_helper(a_bzrdir, utf8_files)
1931
return self._initialize_helper(a_bzrdir, utf8_files, name)
1906
1933
def __init__(self):
1907
1934
super(BzrBranchFormat8, self).__init__()
1930
1957
This format was introduced in bzr 1.6.
1933
def initialize(self, a_bzrdir):
1960
def initialize(self, a_bzrdir, name=None):
1934
1961
"""Create a branch of this format in a_bzrdir."""
1935
1962
utf8_files = [('last-revision', '0 null:\n'),
1936
1963
('branch.conf', ''),
1939
return self._initialize_helper(a_bzrdir, utf8_files)
1966
return self._initialize_helper(a_bzrdir, utf8_files, name)
1941
1968
def _branch_class(self):
1942
1969
return BzrBranch7
1984
2011
transport = a_bzrdir.get_branch_transport(None)
1985
2012
location = transport.put_bytes('location', to_branch.base)
1987
def initialize(self, a_bzrdir, target_branch=None):
2014
def initialize(self, a_bzrdir, name=None, target_branch=None):
1988
2015
"""Create a branch of this format in a_bzrdir."""
1989
2016
if target_branch is None:
1990
2017
# this format does not implement branch itself, thus the implicit
1991
2018
# creation contract must see it as uninitializable
1992
2019
raise errors.UninitializableFormat(self)
1993
2020
mutter('creating branch reference in %s', a_bzrdir.transport.base)
1994
branch_transport = a_bzrdir.get_branch_transport(self)
2021
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1995
2022
branch_transport.put_bytes('location',
1996
2023
target_branch.bzrdir.root_transport.base)
1997
2024
branch_transport.put_bytes('format', self.get_format_string())
1998
2025
return self.open(
1999
a_bzrdir, _found=True,
2026
a_bzrdir, name, _found=True,
2000
2027
possible_transports=[target_branch.bzrdir.root_transport])
2002
2029
def __init__(self):
2009
2036
def clone(to_bzrdir, revision_id=None,
2010
2037
repository_policy=None):
2011
2038
"""See Branch.clone()."""
2012
return format.initialize(to_bzrdir, a_branch)
2039
return format.initialize(to_bzrdir, target_branch=a_branch)
2013
2040
# cannot obey revision_id limits when cloning a reference ...
2014
2041
# FIXME RBC 20060210 either nuke revision_id for clone, or
2015
2042
# emit some sort of warning/error to the caller ?!
2018
def open(self, a_bzrdir, _found=False, location=None,
2045
def open(self, a_bzrdir, name=None, _found=False, location=None,
2019
2046
possible_transports=None, ignore_fallbacks=False):
2020
2047
"""Return the branch that the branch reference in a_bzrdir points at.
2022
2049
:param a_bzrdir: A BzrDir that contains a branch.
2050
:param name: Name of colocated branch to open, if any
2023
2051
:param _found: a private parameter, do not use it. It is used to
2024
2052
indicate if format probing has already be done.
2025
2053
:param ignore_fallbacks: when set, no fallback branches will be opened
2030
2058
:param possible_transports: An optional reusable transports list.
2033
format = BranchFormat.find_format(a_bzrdir)
2061
format = BranchFormat.find_format(a_bzrdir, name=name)
2034
2062
if format.__class__ != self.__class__:
2035
2063
raise AssertionError("wrong format %r found for %r" %
2036
2064
(format, self))
2038
2066
location = self.get_reference(a_bzrdir)
2039
2067
real_bzrdir = bzrdir.BzrDir.open(
2040
2068
location, possible_transports=possible_transports)
2041
result = real_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2069
result = real_bzrdir.open_branch(name=name,
2070
ignore_fallbacks=ignore_fallbacks)
2042
2071
# this changes the behaviour of result.clone to create a new reference
2043
2072
# rather than a copy of the content of the branch.
2044
2073
# I did not use a proxy object because that needs much more extensive
2090
2119
:ivar repository: Repository for this branch.
2091
2120
:ivar base: The url of the base directory for this branch; the one
2092
2121
containing the .bzr directory.
2122
:ivar name: Optional colocated branch name as it exists in the control
2095
2126
def __init__(self, _format=None,
2096
_control_files=None, a_bzrdir=None, _repository=None,
2097
ignore_fallbacks=False):
2127
_control_files=None, a_bzrdir=None, name=None,
2128
_repository=None, ignore_fallbacks=False):
2098
2129
"""Create new branch object at a particular location."""
2099
2130
if a_bzrdir is None:
2100
2131
raise ValueError('a_bzrdir must be supplied')
2102
2133
self.bzrdir = a_bzrdir
2103
2134
self._base = self.bzrdir.transport.clone('..').base
2104
2136
# XXX: We should be able to just do
2105
2137
# self.base = self.bzrdir.root_transport.base
2106
2138
# but this does not quite work yet -- mbp 20080522
2113
2145
Branch.__init__(self)
2115
2147
def __str__(self):
2116
return '%s(%r)' % (self.__class__.__name__, self.base)
2148
if self.name is None:
2149
return '%s(%r)' % (self.__class__.__name__, self.base)
2151
return '%s(%r,%r)' % (self.__class__.__name__, self.base, self.name)
2118
2153
__repr__ = __str__