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
17
from __future__ import absolute_import
18
21
from cStringIO import StringIO
21
23
from bzrlib.lazy_import import lazy_import
22
24
lazy_import(globals(), """
23
from itertools import chain
24
26
from bzrlib import (
28
config as _mod_config,
37
revision as _mod_revision,
43
from bzrlib.config import BranchConfig, TransportConfig
44
from bzrlib.tag import (
31
config as _mod_config,
40
revision as _mod_revision,
48
from bzrlib.i18n import gettext, ngettext
51
# Explicitly import bzrlib.bzrdir so that the BzrProber
52
# is guaranteed to be registered.
50
55
from bzrlib import (
53
59
from bzrlib.decorators import (
103
104
self._last_revision_info_cache = None
104
105
self._master_branch_cache = None
105
106
self._merge_sorted_revisions_cache = None
107
self._open_hook(possible_transports)
107
108
hooks = Branch.hooks['open']
108
109
for hook in hooks:
111
def _open_hook(self):
112
def _open_hook(self, possible_transports):
112
113
"""Called by init to allow simpler extension of the base class."""
114
def _activate_fallback_location(self, url):
115
def _activate_fallback_location(self, url, possible_transports):
115
116
"""Activate the branch/repository from url as a fallback repository."""
116
117
for existing_fallback_repo in self.repository._fallback_repositories:
117
118
if existing_fallback_repo.user_url == url:
118
119
# This fallback is already configured. This probably only
119
# happens because BzrDir.sprout is a horrible mess. To avoid
120
# happens because ControlDir.sprout is a horrible mess. To avoid
120
121
# confusing _unstack we don't add this a second time.
121
122
mutter('duplicate activation of fallback %r on %r', url, self)
123
repo = self._get_fallback_repository(url)
124
repo = self._get_fallback_repository(url, possible_transports)
124
125
if repo.has_same_location(self.repository):
125
126
raise errors.UnstackableLocationError(self.user_url, url)
126
127
self.repository.add_fallback_repository(repo)
180
181
For instance, if the branch is at URL/.bzr/branch,
181
182
Branch.open(URL) -> a Branch instance.
183
control = bzrdir.BzrDir.open(base, _unsupported,
184
possible_transports=possible_transports)
185
return control.open_branch(unsupported=_unsupported)
184
control = controldir.ControlDir.open(base,
185
possible_transports=possible_transports, _unsupported=_unsupported)
186
return control.open_branch(unsupported=_unsupported,
187
possible_transports=possible_transports)
188
def open_from_transport(transport, name=None, _unsupported=False):
190
def open_from_transport(transport, name=None, _unsupported=False,
191
possible_transports=None):
189
192
"""Open the branch rooted at transport"""
190
control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
191
return control.open_branch(name=name, unsupported=_unsupported)
193
control = controldir.ControlDir.open_from_transport(transport, _unsupported)
194
return control.open_branch(name=name, unsupported=_unsupported,
195
possible_transports=possible_transports)
194
198
def open_containing(url, possible_transports=None):
652
666
raise errors.UpgradeRequired(self.user_url)
668
def get_append_revisions_only(self):
669
"""Whether it is only possible to append revisions to the history.
671
if not self._format.supports_set_append_revisions_only():
673
return self.get_config_stack().get('append_revisions_only')
654
675
def set_append_revisions_only(self, enabled):
655
676
if not self._format.supports_set_append_revisions_only():
656
677
raise errors.UpgradeRequired(self.user_url)
661
self.get_config().set_user_option('append_revisions_only', value,
678
self.get_config_stack().set('append_revisions_only', enabled)
664
680
def set_reference_info(self, file_id, tree_path, branch_location):
665
681
"""Set the branch location to use for a tree reference."""
743
@deprecated_method(deprecated_in((2, 5, 0)))
727
744
def get_revision_delta(self, revno):
728
745
"""Return the delta for one revision.
730
747
The delta is relative to its mainline predecessor, or the
731
748
empty tree for revision 1.
733
rh = self.revision_history()
734
if not (1 <= revno <= len(rh)):
751
revid = self.get_rev_id(revno)
752
except errors.NoSuchRevision:
735
753
raise errors.InvalidRevisionNumber(revno)
736
return self.repository.get_revision_delta(rh[revno-1])
754
return self.repository.get_revision_delta(revid)
738
756
def get_stacked_on_url(self):
739
757
"""Get the URL this branch is stacked against.
748
766
"""Print `file` to stdout."""
749
767
raise NotImplementedError(self.print_file)
751
@deprecated_method(deprecated_in((2, 4, 0)))
752
def set_revision_history(self, rev_history):
753
"""See Branch.set_revision_history."""
754
self._set_revision_history(rev_history)
757
def _set_revision_history(self, rev_history):
758
if len(rev_history) == 0:
759
revid = _mod_revision.NULL_REVISION
761
revid = rev_history[-1]
762
if rev_history != self._lefthand_history(revid):
763
raise errors.NotLefthandHistory(rev_history)
764
self.set_last_revision_info(len(rev_history), revid)
765
self._cache_revision_history(rev_history)
766
for hook in Branch.hooks['set_rh']:
767
hook(self, rev_history)
769
769
@needs_write_lock
770
770
def set_last_revision_info(self, revno, revision_id):
771
771
"""Set the last revision of this branch.
1145
1142
def _set_config_location(self, name, url, config=None,
1146
1143
make_relative=False):
1147
1144
if config is None:
1148
config = self.get_config()
1145
config = self.get_config_stack()
1149
1146
if url is None:
1151
1148
elif make_relative:
1152
1149
url = urlutils.relative_url(self.base, url)
1153
config.set_user_option(name, url, warn_masked=True)
1150
config.set(name, url)
1155
1152
def _get_config_location(self, name, config=None):
1156
1153
if config is None:
1157
config = self.get_config()
1158
location = config.get_user_option(name)
1154
config = self.get_config_stack()
1155
location = config.get(name)
1159
1156
if location == '':
1160
1157
location = None
1161
1158
return location
1163
1160
def get_child_submit_format(self):
1164
1161
"""Return the preferred format of submissions to this branch."""
1165
return self.get_config().get_user_option("child_submit_format")
1162
return self.get_config_stack().get('child_submit_format')
1167
1164
def get_submit_branch(self):
1168
1165
"""Return the submit location of the branch.
1434
1429
t = transport.get_transport(to_location)
1435
1430
t.ensure_base()
1431
format = self._get_checkout_format(lightweight=lightweight)
1433
checkout = format.initialize_on_transport(t)
1434
except errors.AlreadyControlDirError:
1435
# It's fine if the control directory already exists,
1436
# as long as there is no existing branch and working tree.
1437
checkout = controldir.ControlDir.open_from_transport(t)
1439
checkout.open_branch()
1440
except errors.NotBranchError:
1443
raise errors.AlreadyControlDirError(t.base)
1444
if checkout.control_transport.base == self.bzrdir.control_transport.base:
1445
# When checking out to the same control directory,
1446
# always create a lightweight checkout
1436
1449
if lightweight:
1437
format = self._get_checkout_format()
1438
checkout = format.initialize_on_transport(t)
1439
from_branch = BranchReferenceFormat().initialize(checkout,
1450
from_branch = checkout.set_branch_reference(target_branch=self)
1442
format = self._get_checkout_format()
1443
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
1444
to_location, force_new_tree=False, format=format)
1445
checkout = checkout_branch.bzrdir
1452
policy = checkout.determine_repository_policy()
1453
repo = policy.acquire_repository()[0]
1454
checkout_branch = checkout.create_branch()
1446
1455
checkout_branch.bind(self)
1447
1456
# pull up to the specified revision_id to set the initial
1448
1457
# branch tip correctly, and seed it with history.
1449
1458
checkout_branch.pull(self, stop_revision=revision_id)
1451
1460
tree = checkout.create_workingtree(revision_id,
1452
1461
from_branch=from_branch,
1453
1462
accelerator_tree=accelerator_tree,
1542
1551
heads that must be fetched if present, but no error is necessary if
1543
1552
they are not present.
1545
# For bzr native formats must_fetch is just the tip, and if_present_fetch
1554
# For bzr native formats must_fetch is just the tip, and
1555
# if_present_fetch are the tags.
1547
1556
must_fetch = set([self.last_revision()])
1549
if_present_fetch = set(self.tags.get_reverse_tag_dict())
1550
except errors.TagsNotSupported:
1551
if_present_fetch = set()
1557
if_present_fetch = set()
1558
if self.get_config_stack().get('branch.fetch_tags'):
1560
if_present_fetch = set(self.tags.get_reverse_tag_dict())
1561
except errors.TagsNotSupported:
1552
1563
must_fetch.discard(_mod_revision.NULL_REVISION)
1553
1564
if_present_fetch.discard(_mod_revision.NULL_REVISION)
1554
1565
return must_fetch, if_present_fetch
1572
1583
object will be created every time regardless.
1575
can_set_append_revisions_only = True
1577
1586
def __eq__(self, other):
1578
1587
return self.__class__ is other.__class__
1580
1589
def __ne__(self, other):
1581
1590
return not (self == other)
1584
def find_format(klass, a_bzrdir, name=None):
1585
"""Return the format for the branch object in a_bzrdir."""
1587
transport = a_bzrdir.get_branch_transport(None, name=name)
1588
format_string = transport.get_bytes("format")
1589
return format_registry.get(format_string)
1590
except errors.NoSuchFile:
1591
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
1593
raise errors.UnknownFormatError(format=format_string, kind='branch')
1596
@deprecated_method(deprecated_in((2, 4, 0)))
1597
def get_default_format(klass):
1598
"""Return the current default format."""
1599
return format_registry.get_default()
1602
@deprecated_method(deprecated_in((2, 4, 0)))
1603
def get_formats(klass):
1604
"""Get all the known formats.
1606
Warning: This triggers a load of all lazy registered formats: do not
1607
use except when that is desireed.
1609
return format_registry._get_all()
1611
def get_reference(self, a_bzrdir, name=None):
1612
"""Get the target reference of the branch in a_bzrdir.
1592
def get_reference(self, controldir, name=None):
1593
"""Get the target reference of the branch in controldir.
1614
1595
format probing must have been completed before calling
1615
1596
this method - it is assumed that the format of the branch
1616
in a_bzrdir is correct.
1597
in controldir is correct.
1618
:param a_bzrdir: The bzrdir to get the branch data from.
1599
:param controldir: The controldir to get the branch data from.
1619
1600
:param name: Name of the colocated branch to fetch
1620
1601
:return: None if the branch is not a reference branch.
1625
def set_reference(self, a_bzrdir, name, to_branch):
1626
"""Set the target reference of the branch in a_bzrdir.
1606
def set_reference(self, controldir, name, to_branch):
1607
"""Set the target reference of the branch in controldir.
1628
1609
format probing must have been completed before calling
1629
1610
this method - it is assumed that the format of the branch
1630
in a_bzrdir is correct.
1611
in controldir is correct.
1632
:param a_bzrdir: The bzrdir to set the branch reference for.
1613
:param controldir: The controldir to set the branch reference for.
1633
1614
:param name: Name of colocated branch to set, None for default
1634
1615
:param to_branch: branch that the checkout is to reference
1636
1617
raise NotImplementedError(self.set_reference)
1638
def get_format_string(self):
1639
"""Return the ASCII format string that identifies this format."""
1640
raise NotImplementedError(self.get_format_string)
1642
1619
def get_format_description(self):
1643
1620
"""Return the short format description for this format."""
1644
1621
raise NotImplementedError(self.get_format_description)
1646
def _run_post_branch_init_hooks(self, a_bzrdir, name, branch):
1623
def _run_post_branch_init_hooks(self, controldir, name, branch):
1647
1624
hooks = Branch.hooks['post_branch_init']
1650
params = BranchInitHookParams(self, a_bzrdir, name, branch)
1627
params = BranchInitHookParams(self, controldir, name, branch)
1651
1628
for hook in hooks:
1654
def initialize(self, a_bzrdir, name=None, repository=None):
1655
"""Create a branch of this format in a_bzrdir.
1631
def initialize(self, controldir, name=None, repository=None,
1632
append_revisions_only=None):
1633
"""Create a branch of this format in controldir.
1657
1635
:param name: Name of the colocated branch to create.
1659
1637
raise NotImplementedError(self.initialize)
1692
1670
raise NotImplementedError(self.network_name)
1694
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
1695
found_repository=None):
1696
"""Return the branch object for a_bzrdir
1672
def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
1673
found_repository=None, possible_transports=None):
1674
"""Return the branch object for controldir.
1698
:param a_bzrdir: A BzrDir that contains a branch.
1676
:param controldir: A ControlDir that contains a branch.
1699
1677
:param name: Name of colocated branch to open
1700
1678
:param _found: a private parameter, do not use it. It is used to
1701
1679
indicate if format probing has already be done.
1705
1683
raise NotImplementedError(self.open)
1708
@deprecated_method(deprecated_in((2, 4, 0)))
1709
def register_format(klass, format):
1710
"""Register a metadir format.
1712
See MetaDirBranchFormatFactory for the ability to register a format
1713
without loading the code the format needs until it is actually used.
1715
format_registry.register(format)
1718
@deprecated_method(deprecated_in((2, 4, 0)))
1719
def set_default_format(klass, format):
1720
format_registry.set_default(format)
1722
1685
def supports_set_append_revisions_only(self):
1723
1686
"""True if this format supports set_append_revisions_only."""
1922
1887
branch, which refer to the original branch.
1925
def __init__(self, format, a_bzrdir, name, branch):
1890
def __init__(self, format, controldir, name, branch):
1926
1891
"""Create a group of BranchInitHook parameters.
1928
1893
:param format: the branch format
1929
:param a_bzrdir: the BzrDir where the branch will be/has been
1894
:param controldir: the ControlDir where the branch will be/has been
1931
1896
:param name: name of colocated branch, if any (or None)
1932
1897
:param branch: the branch created
1980
1945
self.revision_id)
1983
class BranchFormatMetadir(BranchFormat):
1984
"""Common logic for meta-dir based branch formats."""
1948
class BranchFormatMetadir(bzrdir.BzrFormat, BranchFormat):
1949
"""Base class for branch formats that live in meta directories.
1953
BranchFormat.__init__(self)
1954
bzrdir.BzrFormat.__init__(self)
1957
def find_format(klass, controldir, name=None):
1958
"""Return the format for the branch object in controldir."""
1960
transport = controldir.get_branch_transport(None, name=name)
1961
except errors.NoSuchFile:
1962
raise errors.NotBranchError(path=name, bzrdir=controldir)
1964
format_string = transport.get_bytes("format")
1965
except errors.NoSuchFile:
1966
raise errors.NotBranchError(path=transport.base, bzrdir=controldir)
1967
return klass._find_format(format_registry, 'branch', format_string)
1986
1969
def _branch_class(self):
1987
1970
"""What class to instantiate on open calls."""
1988
1971
raise NotImplementedError(self._branch_class)
1973
def _get_initial_config(self, append_revisions_only=None):
1974
if append_revisions_only:
1975
return "append_revisions_only = True\n"
1977
# Avoid writing anything if append_revisions_only is disabled,
1978
# as that is the default.
1990
1981
def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1991
1982
repository=None):
1992
"""Initialize a branch in a bzrdir, with specified files
1983
"""Initialize a branch in a control dir, with specified files
1994
1985
:param a_bzrdir: The bzrdir to initialize the branch in
1995
1986
:param utf8_files: The files to create as a list of
2016
2009
self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2019
def network_name(self):
2020
"""A simple byte string uniquely identifying this format for RPC calls.
2022
Metadir branch formats use their format string.
2024
return self.get_format_string()
2026
2012
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
2027
found_repository=None):
2013
found_repository=None, possible_transports=None):
2028
2014
"""See BranchFormat.open()."""
2016
name = a_bzrdir._get_selected_branch()
2030
format = BranchFormat.find_format(a_bzrdir, name=name)
2018
format = BranchFormatMetadir.find_format(a_bzrdir, name=name)
2031
2019
if format.__class__ != self.__class__:
2032
2020
raise AssertionError("wrong format %r found for %r" %
2033
2021
(format, self))
2043
2031
a_bzrdir=a_bzrdir,
2044
2032
_repository=found_repository,
2045
ignore_fallbacks=ignore_fallbacks)
2033
ignore_fallbacks=ignore_fallbacks,
2034
possible_transports=possible_transports)
2046
2035
except errors.NoSuchFile:
2047
2036
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2050
super(BranchFormatMetadir, self).__init__()
2051
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2052
self._matchingbzrdir.set_branch_format(self)
2039
def _matchingbzrdir(self):
2040
ret = bzrdir.BzrDirMetaFormat1()
2041
ret.set_branch_format(self)
2054
2044
def supports_tags(self):
2115
2118
"""See BranchFormat.get_format_description()."""
2116
2119
return "Branch format 6"
2118
def initialize(self, a_bzrdir, name=None, repository=None):
2121
def initialize(self, a_bzrdir, name=None, repository=None,
2122
append_revisions_only=None):
2119
2123
"""Create a branch of this format in a_bzrdir."""
2120
2124
utf8_files = [('last-revision', '0 null:\n'),
2121
('branch.conf', ''),
2126
self._get_initial_config(append_revisions_only)),
2124
2129
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2126
2131
def make_tags(self, branch):
2127
2132
"""See bzrlib.branch.BranchFormat.make_tags()."""
2128
return BasicTags(branch)
2133
return _mod_tag.BasicTags(branch)
2130
2135
def supports_set_append_revisions_only(self):
2176
2184
This format was introduced in bzr 1.6.
2179
def initialize(self, a_bzrdir, name=None, repository=None):
2187
def initialize(self, a_bzrdir, name=None, repository=None,
2188
append_revisions_only=None):
2180
2189
"""Create a branch of this format in a_bzrdir."""
2181
2190
utf8_files = [('last-revision', '0 null:\n'),
2182
('branch.conf', ''),
2192
self._get_initial_config(append_revisions_only)),
2185
2195
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2238
2250
location = transport.put_bytes('location', to_branch.base)
2240
2252
def initialize(self, a_bzrdir, name=None, target_branch=None,
2253
repository=None, append_revisions_only=None):
2242
2254
"""Create a branch of this format in a_bzrdir."""
2243
2255
if target_branch is None:
2244
2256
# this format does not implement branch itself, thus the implicit
2245
2257
# creation contract must see it as uninitializable
2246
2258
raise errors.UninitializableFormat(self)
2247
2259
mutter('creating branch reference in %s', a_bzrdir.user_url)
2260
if a_bzrdir._format.fixed_components:
2261
raise errors.IncompatibleFormat(self, a_bzrdir._format)
2263
name = a_bzrdir._get_selected_branch()
2248
2264
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2249
2265
branch_transport.put_bytes('location',
2250
target_branch.bzrdir.user_url)
2251
branch_transport.put_bytes('format', self.get_format_string())
2253
a_bzrdir, name, _found=True,
2266
target_branch.user_url)
2267
branch_transport.put_bytes('format', self.as_string())
2268
branch = self.open(a_bzrdir, name, _found=True,
2254
2269
possible_transports=[target_branch.bzrdir.root_transport])
2255
2270
self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2259
super(BranchReferenceFormat, self).__init__()
2260
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2261
self._matchingbzrdir.set_branch_format(self)
2263
2273
def _make_reference_clone_function(format, a_branch):
2264
2274
"""Create a clone() routine for a branch dynamically."""
2265
2275
def clone(to_bzrdir, revision_id=None,
2288
2298
:param possible_transports: An optional reusable transports list.
2301
name = a_bzrdir._get_selected_branch()
2291
format = BranchFormat.find_format(a_bzrdir, name=name)
2303
format = BranchFormatMetadir.find_format(a_bzrdir, name=name)
2292
2304
if format.__class__ != self.__class__:
2293
2305
raise AssertionError("wrong format %r found for %r" %
2294
2306
(format, self))
2295
2307
if location is None:
2296
2308
location = self.get_reference(a_bzrdir, name)
2297
real_bzrdir = bzrdir.BzrDir.open(
2309
real_bzrdir = controldir.ControlDir.open(
2298
2310
location, possible_transports=possible_transports)
2299
result = real_bzrdir.open_branch(name=name,
2300
ignore_fallbacks=ignore_fallbacks)
2311
result = real_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks,
2312
possible_transports=possible_transports)
2301
2313
# this changes the behaviour of result.clone to create a new reference
2302
2314
# rather than a copy of the content of the branch.
2303
2315
# I did not use a proxy object because that needs much more extensive
2385
2397
def __init__(self, _format=None,
2386
2398
_control_files=None, a_bzrdir=None, name=None,
2387
_repository=None, ignore_fallbacks=False):
2399
_repository=None, ignore_fallbacks=False,
2400
possible_transports=None):
2388
2401
"""Create new branch object at a particular location."""
2389
2402
if a_bzrdir is None:
2390
2403
raise ValueError('a_bzrdir must be supplied')
2392
self.bzrdir = a_bzrdir
2393
self._base = self.bzrdir.transport.clone('..').base
2405
raise ValueError('name must be supplied')
2406
self.bzrdir = a_bzrdir
2407
self._user_transport = self.bzrdir.transport.clone('..')
2409
self._user_transport.set_segment_parameter(
2410
"branch", urlutils.escape(name))
2411
self._base = self._user_transport.base
2394
2412
self.name = name
2395
# XXX: We should be able to just do
2396
# self.base = self.bzrdir.root_transport.base
2397
# but this does not quite work yet -- mbp 20080522
2398
2413
self._format = _format
2399
2414
if _control_files is None:
2400
2415
raise ValueError('BzrBranch _control_files is None')
2401
2416
self.control_files = _control_files
2402
2417
self._transport = _control_files._transport
2403
2418
self.repository = _repository
2404
Branch.__init__(self)
2419
self.conf_store = None
2420
Branch.__init__(self, possible_transports)
2406
2422
def __str__(self):
2407
if self.name is None:
2408
return '%s(%s)' % (self.__class__.__name__, self.user_url)
2410
return '%s(%s,%s)' % (self.__class__.__name__, self.user_url,
2423
return '%s(%s)' % (self.__class__.__name__, self.user_url)
2413
2425
__repr__ = __str__
2673
2706
self._set_revision_history(history)
2675
2708
def _read_last_revision_info(self):
2676
rh = self.revision_history()
2709
rh = self._revision_history()
2677
2710
revno = len(rh)
2679
2712
return (revno, rh[-1])
2681
2714
return (0, _mod_revision.NULL_REVISION)
2683
@deprecated_method(deprecated_in((2, 4, 0)))
2685
def set_revision_history(self, rev_history):
2686
"""See Branch.set_revision_history."""
2687
self._set_revision_history(rev_history)
2689
2716
def _set_revision_history(self, rev_history):
2690
2717
if 'evil' in debug.debug_flags:
2691
2718
mutter_callsite(3, "set_revision_history scales with history.")
2907
2935
"""See Branch.set_push_location."""
2908
2936
self._master_branch_cache = None
2910
config = self.get_config()
2938
conf = self.get_config_stack()
2911
2939
if location is None:
2912
if config.get_user_option('bound') != 'True':
2940
if not conf.get('bound'):
2915
config.set_user_option('bound', 'False', warn_masked=True)
2943
conf.set('bound', 'False')
2918
2946
self._set_config_location('bound_location', location,
2920
config.set_user_option('bound', 'True', warn_masked=True)
2948
conf.set('bound', 'True')
2923
2951
def _get_bound_location(self, bound):
2924
2952
"""Return the bound location in the config file.
2926
2954
Return None if the bound parameter does not match"""
2927
config = self.get_config()
2928
config_bound = (config.get_user_option('bound') == 'True')
2929
if config_bound != bound:
2955
conf = self.get_config_stack()
2956
if conf.get('bound') != bound:
2931
return self._get_config_location('bound_location', config=config)
2958
return self._get_config_location('bound_location', config=conf)
2933
2960
def get_bound_location(self):
2934
"""See Branch.set_push_location."""
2961
"""See Branch.get_bound_location."""
2935
2962
return self._get_bound_location(True)
2937
2964
def get_old_bound_location(self):
2944
2971
## self._check_stackable_repo()
2945
2972
# stacked_on_location is only ever defined in branch.conf, so don't
2946
2973
# waste effort reading the whole stack of config files.
2947
config = self.get_config()._get_branch_data_config()
2974
conf = _mod_config.BranchOnlyStack(self)
2948
2975
stacked_url = self._get_config_location('stacked_on_location',
2950
2977
if stacked_url is None:
2951
2978
raise errors.NotStacked(self)
2954
def _get_append_revisions_only(self):
2955
return self.get_config(
2956
).get_user_option_as_bool('append_revisions_only')
2979
return stacked_url.encode('utf-8')
2958
2981
@needs_read_lock
2959
2982
def get_rev_id(self, revno, history=None):
3046
3071
:ivar local_branch: target branch if there is a Master, else None
3047
3072
:ivar target_branch: Target/destination branch object. (write locked)
3048
3073
:ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to
3074
:ivar tag_updates: A dict with new tags, see BasicTags.merge_to
3051
@deprecated_method(deprecated_in((2, 3, 0)))
3053
"""Return the relative change in revno.
3055
:deprecated: Use `new_revno` and `old_revno` instead.
3057
return self.new_revno - self.old_revno
3059
3077
def report(self, to_file):
3078
tag_conflicts = getattr(self, "tag_conflicts", None)
3079
tag_updates = getattr(self, "tag_updates", None)
3060
3080
if not is_quiet():
3061
if self.old_revid == self.new_revid:
3062
to_file.write('No revisions to pull.\n')
3081
if self.old_revid != self.new_revid:
3064
3082
to_file.write('Now on revision %d.\n' % self.new_revno)
3084
to_file.write('%d tag(s) updated.\n' % len(tag_updates))
3085
if self.old_revid == self.new_revid and not tag_updates:
3086
if not tag_conflicts:
3087
to_file.write('No revisions or tags to pull.\n')
3089
to_file.write('No revisions to pull.\n')
3065
3090
self._show_tag_conficts(to_file)
3084
3109
target, otherwise it will be None.
3087
@deprecated_method(deprecated_in((2, 3, 0)))
3089
"""Return the relative change in revno.
3091
:deprecated: Use `new_revno` and `old_revno` instead.
3093
return self.new_revno - self.old_revno
3095
3112
def report(self, to_file):
3096
"""Write a human-readable description of the result."""
3097
if self.old_revid == self.new_revid:
3098
note('No new revisions to push.')
3100
note('Pushed up to revision %d.' % self.new_revno)
3113
# TODO: This function gets passed a to_file, but then
3114
# ignores it and calls note() instead. This is also
3115
# inconsistent with PullResult(), which writes to stdout.
3116
# -- JRV20110901, bug #838853
3117
tag_conflicts = getattr(self, "tag_conflicts", None)
3118
tag_updates = getattr(self, "tag_updates", None)
3120
if self.old_revid != self.new_revid:
3121
note(gettext('Pushed up to revision %d.') % self.new_revno)
3123
note(ngettext('%d tag updated.', '%d tags updated.', len(tag_updates)) % len(tag_updates))
3124
if self.old_revid == self.new_revid and not tag_updates:
3125
if not tag_conflicts:
3126
note(gettext('No new revisions or tags to push.'))
3128
note(gettext('No new revisions to push.'))
3101
3129
self._show_tag_conficts(to_file)
3134
3162
# Copy source data into target
3135
3163
new_branch._write_last_revision_info(*branch.last_revision_info())
3136
new_branch.set_parent(branch.get_parent())
3137
new_branch.set_bound_location(branch.get_bound_location())
3138
new_branch.set_push_location(branch.get_push_location())
3164
new_branch.lock_write()
3166
new_branch.set_parent(branch.get_parent())
3167
new_branch.set_bound_location(branch.get_bound_location())
3168
new_branch.set_push_location(branch.get_push_location())
3140
3172
# New branch has no tags by default
3141
3173
new_branch.tags._set_tag_dict({})
3143
3175
# Copying done; now update target format
3144
3176
new_branch._transport.put_bytes('format',
3145
format.get_format_string(),
3146
3178
mode=new_branch.bzrdir._get_file_mode())
3148
3180
# Clean up old files
3149
3181
new_branch._transport.delete('revision-history')
3151
branch.set_parent(None)
3152
except errors.NoSuchFile:
3154
branch.set_bound_location(None)
3185
branch.set_parent(None)
3186
except errors.NoSuchFile:
3188
branch.set_bound_location(None)
3157
3193
class Converter6to7(object):
3161
3197
format = BzrBranchFormat7()
3162
3198
branch._set_config_location('stacked_on_location', '')
3163
3199
# update target format
3164
branch._transport.put_bytes('format', format.get_format_string())
3200
branch._transport.put_bytes('format', format.as_string())
3167
3203
class Converter7to8(object):
3168
"""Perform an in-place upgrade of format 6 to format 7"""
3204
"""Perform an in-place upgrade of format 7 to format 8"""
3170
3206
def convert(self, branch):
3171
3207
format = BzrBranchFormat8()
3172
3208
branch._transport.put_bytes('references', '')
3173
3209
# update target format
3174
branch._transport.put_bytes('format', format.get_format_string())
3210
branch._transport.put_bytes('format', format.as_string())
3177
3213
class InterBranch(InterObject):
3344
3380
if local and not bound_location:
3345
3381
raise errors.LocalRequiresBoundBranch()
3346
3382
master_branch = None
3347
source_is_master = (self.source.user_url == bound_location)
3383
source_is_master = False
3385
# bound_location comes from a config file, some care has to be
3386
# taken to relate it to source.user_url
3387
normalized = urlutils.normalize_url(bound_location)
3389
relpath = self.source.user_transport.relpath(normalized)
3390
source_is_master = (relpath == '')
3391
except (errors.PathNotChild, errors.InvalidURL):
3392
source_is_master = False
3348
3393
if not local and bound_location and not source_is_master:
3349
3394
# not pulling from master, so we need to update master.
3350
3395
master_branch = self.target.get_master_branch(possible_transports)
3492
3537
# TODO: The old revid should be specified when merging tags,
3493
3538
# so a tags implementation that versions tags can only
3494
3539
# pull in the most recent changes. -- JRV20090506
3495
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3496
overwrite, ignore_master=not merge_tags_to_master)
3540
result.tag_updates, result.tag_conflicts = (
3541
self.source.tags.merge_to(self.target.tags, overwrite,
3542
ignore_master=not merge_tags_to_master))
3497
3543
result.new_revno, result.new_revid = self.target.last_revision_info()
3498
3544
if _hook_master:
3499
3545
result.master_branch = _hook_master