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
21
21
from bzrlib.lazy_import import lazy_import
22
22
lazy_import(globals(), """
23
from itertools import chain
24
24
from bzrlib import (
29
config as _mod_config,
38
revision as _mod_revision,
28
config as _mod_config,
37
revision as _mod_revision,
43
from bzrlib.config import BranchConfig, TransportConfig
44
from bzrlib.tag import (
45
from bzrlib.i18n import gettext, ngettext
48
50
from bzrlib import (
64
66
from bzrlib.trace import mutter, mutter_callsite, note, is_quiet
69
BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
70
BZR_BRANCH_FORMAT_5 = "Bazaar-NG branch, format 5\n"
71
BZR_BRANCH_FORMAT_6 = "Bazaar Branch Format 6 (bzr 0.15)\n"
67
74
class Branch(controldir.ControlComponent):
68
75
"""Branch holding a history of revisions.
109
116
for existing_fallback_repo in self.repository._fallback_repositories:
110
117
if existing_fallback_repo.user_url == url:
111
118
# This fallback is already configured. This probably only
112
# happens because ControlDir.sprout is a horrible mess. To avoid
119
# happens because BzrDir.sprout is a horrible mess. To avoid
113
120
# confusing _unstack we don't add this a second time.
114
121
mutter('duplicate activation of fallback %r on %r', url, self)
173
180
For instance, if the branch is at URL/.bzr/branch,
174
181
Branch.open(URL) -> a Branch instance.
176
control = controldir.ControlDir.open(base, _unsupported,
183
control = bzrdir.BzrDir.open(base, _unsupported,
177
184
possible_transports=possible_transports)
178
185
return control.open_branch(unsupported=_unsupported)
181
188
def open_from_transport(transport, name=None, _unsupported=False):
182
189
"""Open the branch rooted at transport"""
183
control = controldir.ControlDir.open_from_transport(transport, _unsupported)
190
control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
184
191
return control.open_branch(name=name, unsupported=_unsupported)
195
202
format, UnknownFormatError or UnsupportedFormatError are raised.
196
203
If there is one, it is returned, along with the unused portion of url.
198
control, relpath = controldir.ControlDir.open_containing(url,
205
control, relpath = bzrdir.BzrDir.open_containing(url,
199
206
possible_transports)
200
207
return control.open_branch(), relpath
216
223
:return: A bzrlib.config.BranchConfig.
218
return _mod_config.BranchConfig(self)
220
def get_config_stack(self):
221
"""Get a bzrlib.config.BranchStack for this Branch.
223
This can then be used to get and set configuration options for the
226
:return: A bzrlib.config.BranchStack.
228
return _mod_config.BranchStack(self)
225
return BranchConfig(self)
230
227
def _get_config(self):
231
228
"""Get the concrete config for just the config in this branch.
516
513
rev_iter = iter(merge_sorted_revisions)
517
514
if start_revision_id is not None:
518
515
for node in rev_iter:
516
rev_id = node.key[-1]
520
517
if rev_id != start_revision_id:
523
520
# The decision to include the start or not
524
521
# depends on the stop_rule if a stop is provided
525
522
# so pop this node back into the iterator
526
rev_iter = itertools.chain(iter([node]), rev_iter)
523
rev_iter = chain(iter([node]), rev_iter)
528
525
if stop_revision_id is None:
529
526
# Yield everything
530
527
for node in rev_iter:
528
rev_id = node.key[-1]
532
529
yield (rev_id, node.merge_depth, node.revno,
533
530
node.end_of_merge)
534
531
elif stop_rule == 'exclude':
535
532
for node in rev_iter:
533
rev_id = node.key[-1]
537
534
if rev_id == stop_revision_id:
539
536
yield (rev_id, node.merge_depth, node.revno,
540
537
node.end_of_merge)
541
538
elif stop_rule == 'include':
542
539
for node in rev_iter:
540
rev_id = node.key[-1]
544
541
yield (rev_id, node.merge_depth, node.revno,
545
542
node.end_of_merge)
546
543
if rev_id == stop_revision_id:
552
549
ancestors = graph.find_unique_ancestors(start_revision_id,
553
550
[stop_revision_id])
554
551
for node in rev_iter:
552
rev_id = node.key[-1]
556
553
if rev_id not in ancestors:
558
555
yield (rev_id, node.merge_depth, node.revno,
655
652
raise errors.UpgradeRequired(self.user_url)
657
def get_append_revisions_only(self):
658
"""Whether it is only possible to append revisions to the history.
660
if not self._format.supports_set_append_revisions_only():
662
return self.get_config(
663
).get_user_option_as_bool('append_revisions_only')
665
654
def set_append_revisions_only(self, enabled):
666
655
if not self._format.supports_set_append_revisions_only():
667
656
raise errors.UpgradeRequired(self.user_url)
738
@deprecated_method(deprecated_in((2, 5, 0)))
739
727
def get_revision_delta(self, revno):
740
728
"""Return the delta for one revision.
742
730
The delta is relative to its mainline predecessor, or the
743
731
empty tree for revision 1.
746
revid = self.get_rev_id(revno)
747
except errors.NoSuchRevision:
733
rh = self.revision_history()
734
if not (1 <= revno <= len(rh)):
748
735
raise errors.InvalidRevisionNumber(revno)
749
return self.repository.get_revision_delta(revid)
736
return self.repository.get_revision_delta(rh[revno-1])
751
738
def get_stacked_on_url(self):
752
739
"""Get the URL this branch is stacked against.
798
785
other_branch=None):
799
786
"""See Branch.generate_revision_history"""
800
787
graph = self.repository.get_graph()
801
(last_revno, last_revid) = self.last_revision_info()
802
788
known_revision_ids = [
803
(last_revid, last_revno),
789
self.last_revision_info(),
804
790
(_mod_revision.NULL_REVISION, 0),
806
792
if last_rev is not None:
864
850
pb = ui.ui_factory.nested_progress_bar()
866
pb.update(gettext("Unstacking"))
852
pb.update("Unstacking")
867
853
# The basic approach here is to fetch the tip of the branch,
868
854
# including all available ghosts, from the existing stacked
869
855
# repository into a new repository object without the fallbacks.
883
869
# stream from one of them to the other. This does mean doing
884
870
# separate SSH connection setup, but unstacking is not a
885
871
# common operation so it's tolerable.
886
new_bzrdir = controldir.ControlDir.open(
887
self.bzrdir.root_transport.base)
872
new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
888
873
new_repository = new_bzrdir.find_repository()
889
874
if new_repository._fallback_repositories:
890
875
raise AssertionError("didn't expect %r to have "
1008
993
raise NotImplementedError(self._gen_revision_history)
1010
@deprecated_method(deprecated_in((2, 5, 0)))
1011
995
@needs_read_lock
1012
996
def revision_history(self):
1013
997
"""Return sequence of revision ids on this branch.
1015
999
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
1002
if 'evil' in debug.debug_flags:
1022
1003
mutter_callsite(3, "revision_history scales with history.")
1023
1004
if self._revision_history_cache is not None:
1093
1074
"""Given a revision id, return its revno"""
1094
1075
if _mod_revision.is_null(revision_id):
1096
history = self._revision_history()
1077
history = self.revision_history()
1098
1079
return history.index(revision_id) + 1
1099
1080
except ValueError:
1312
1293
if repository_policy is not None:
1313
1294
repository_policy.configure_branch(result)
1314
1295
self.copy_content_into(result, revision_id=revision_id)
1315
master_url = self.get_bound_location()
1316
if master_url is None:
1296
master_branch = self.get_master_branch()
1297
if master_branch is None:
1317
1298
result.set_parent(self.bzrdir.root_transport.base)
1319
result.set_parent(master_url)
1300
result.set_parent(master_branch.bzrdir.root_transport.base)
1321
1302
result.unlock()
1396
1377
# TODO: We should probably also check that self.revision_history
1397
1378
# matches the repository for older branch formats.
1398
1379
# If looking for the code that cross-checks repository parents against
1399
# the Graph.iter_lefthand_ancestry output, that is now a repository
1380
# the iter_reverse_revision_history output, that is now a repository
1400
1381
# specific check.
1403
def _get_checkout_format(self, lightweight=False):
1384
def _get_checkout_format(self):
1404
1385
"""Return the most suitable metadir for a checkout of this branch.
1405
1386
Weaves are used if this branch's repository uses weaves.
1453
1434
t = transport.get_transport(to_location)
1454
1435
t.ensure_base()
1455
format = self._get_checkout_format(lightweight=lightweight)
1456
1436
if lightweight:
1437
format = self._get_checkout_format()
1457
1438
checkout = format.initialize_on_transport(t)
1458
1439
from_branch = BranchReferenceFormat().initialize(checkout,
1459
1440
target_branch=self)
1461
checkout_branch = controldir.ControlDir.create_branch_convenience(
1442
format = self._get_checkout_format()
1443
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
1462
1444
to_location, force_new_tree=False, format=format)
1463
1445
checkout = checkout_branch.bzrdir
1464
1446
checkout_branch.bind(self)
1563
1545
# For bzr native formats must_fetch is just the tip, and if_present_fetch
1564
1546
# are the tags.
1565
1547
must_fetch = set([self.last_revision()])
1566
if_present_fetch = set()
1567
c = self.get_config()
1568
include_tags = c.get_user_option_as_bool('branch.fetch_tags',
1572
if_present_fetch = set(self.tags.get_reverse_tag_dict())
1573
except errors.TagsNotSupported:
1549
if_present_fetch = set(self.tags.get_reverse_tag_dict())
1550
except errors.TagsNotSupported:
1551
if_present_fetch = set()
1575
1552
must_fetch.discard(_mod_revision.NULL_REVISION)
1576
1553
if_present_fetch.discard(_mod_revision.NULL_REVISION)
1577
1554
return must_fetch, if_present_fetch
1602
1581
return not (self == other)
1605
def find_format(klass, controldir, name=None):
1606
"""Return the format for the branch object in controldir."""
1584
def find_format(klass, a_bzrdir, name=None):
1585
"""Return the format for the branch object in a_bzrdir."""
1608
transport = controldir.get_branch_transport(None, name=name)
1587
transport = a_bzrdir.get_branch_transport(None, name=name)
1609
1588
format_string = transport.get_bytes("format")
1610
1589
return format_registry.get(format_string)
1611
1590
except errors.NoSuchFile:
1612
raise errors.NotBranchError(path=transport.base, bzrdir=controldir)
1591
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
1613
1592
except KeyError:
1614
1593
raise errors.UnknownFormatError(format=format_string, kind='branch')
1630
1609
return format_registry._get_all()
1632
def get_reference(self, controldir, name=None):
1633
"""Get the target reference of the branch in controldir.
1611
def get_reference(self, a_bzrdir, name=None):
1612
"""Get the target reference of the branch in a_bzrdir.
1635
1614
format probing must have been completed before calling
1636
1615
this method - it is assumed that the format of the branch
1637
in controldir is correct.
1616
in a_bzrdir is correct.
1639
:param controldir: The controldir to get the branch data from.
1618
:param a_bzrdir: The bzrdir to get the branch data from.
1640
1619
:param name: Name of the colocated branch to fetch
1641
1620
:return: None if the branch is not a reference branch.
1646
def set_reference(self, controldir, name, to_branch):
1647
"""Set the target reference of the branch in controldir.
1625
def set_reference(self, a_bzrdir, name, to_branch):
1626
"""Set the target reference of the branch in a_bzrdir.
1649
1628
format probing must have been completed before calling
1650
1629
this method - it is assumed that the format of the branch
1651
in controldir is correct.
1630
in a_bzrdir is correct.
1653
:param controldir: The controldir to set the branch reference for.
1632
:param a_bzrdir: The bzrdir to set the branch reference for.
1654
1633
:param name: Name of colocated branch to set, None for default
1655
1634
:param to_branch: branch that the checkout is to reference
1664
1643
"""Return the short format description for this format."""
1665
1644
raise NotImplementedError(self.get_format_description)
1667
def _run_post_branch_init_hooks(self, controldir, name, branch):
1646
def _run_post_branch_init_hooks(self, a_bzrdir, name, branch):
1668
1647
hooks = Branch.hooks['post_branch_init']
1671
params = BranchInitHookParams(self, controldir, name, branch)
1650
params = BranchInitHookParams(self, a_bzrdir, name, branch)
1672
1651
for hook in hooks:
1675
def initialize(self, controldir, name=None, repository=None,
1676
append_revisions_only=None):
1677
"""Create a branch of this format in controldir.
1654
def initialize(self, a_bzrdir, name=None, repository=None):
1655
"""Create a branch of this format in a_bzrdir.
1679
1657
:param name: Name of the colocated branch to create.
1681
1659
raise NotImplementedError(self.initialize)
1701
1679
Note that it is normal for branch to be a RemoteBranch when using tags
1702
1680
on a RemoteBranch.
1704
return _mod_tag.DisabledTags(branch)
1682
return DisabledTags(branch)
1706
1684
def network_name(self):
1707
1685
"""A simple byte string uniquely identifying this format for RPC calls.
1714
1692
raise NotImplementedError(self.network_name)
1716
def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
1694
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
1717
1695
found_repository=None):
1718
"""Return the branch object for controldir.
1696
"""Return the branch object for a_bzrdir
1720
:param controldir: A ControlDir that contains a branch.
1698
:param a_bzrdir: A BzrDir that contains a branch.
1721
1699
:param name: Name of colocated branch to open
1722
1700
:param _found: a private parameter, do not use it. It is used to
1723
1701
indicate if format probing has already be done.
1765
1743
"""True if this format supports tags stored in the branch"""
1766
1744
return False # by default
1768
def tags_are_versioned(self):
1769
"""Whether the tag container for this branch versions tags."""
1772
def supports_tags_referencing_ghosts(self):
1773
"""True if tags can reference ghost revisions."""
1777
1747
class MetaDirBranchFormatFactory(registry._LazyObjectGetter):
1778
1748
"""A factory for a BranchFormat object, permitting simple lazy registration.
1943
1913
There are 4 fields that hooks may wish to access:
1945
1915
:ivar format: the branch format
1946
:ivar bzrdir: the ControlDir where the branch will be/has been initialized
1916
:ivar bzrdir: the BzrDir where the branch will be/has been initialized
1947
1917
:ivar name: name of colocated branch, if any (or None)
1948
1918
:ivar branch: the branch created
1952
1922
branch, which refer to the original branch.
1955
def __init__(self, format, controldir, name, branch):
1925
def __init__(self, format, a_bzrdir, name, branch):
1956
1926
"""Create a group of BranchInitHook parameters.
1958
1928
:param format: the branch format
1959
:param controldir: the ControlDir where the branch will be/has been
1929
:param a_bzrdir: the BzrDir where the branch will be/has been
1961
1931
:param name: name of colocated branch, if any (or None)
1962
1932
:param branch: the branch created
1983
1953
There are 4 fields that hooks may wish to access:
1985
:ivar control_dir: ControlDir of the checkout to change
1955
:ivar control_dir: BzrDir of the checkout to change
1986
1956
:ivar to_branch: branch that the checkout is to reference
1987
1957
:ivar force: skip the check for local commits in a heavy checkout
1988
1958
:ivar revision_id: revision ID to switch to (or None)
1991
1961
def __init__(self, control_dir, to_branch, force, revision_id):
1992
1962
"""Create a group of SwitchHook parameters.
1994
:param control_dir: ControlDir of the checkout to change
1964
:param control_dir: BzrDir of the checkout to change
1995
1965
:param to_branch: branch that the checkout is to reference
1996
1966
:param force: skip the check for local commits in a heavy checkout
1997
1967
:param revision_id: revision ID to switch to (or None)
2017
1987
"""What class to instantiate on open calls."""
2018
1988
raise NotImplementedError(self._branch_class)
2020
def _get_initial_config(self, append_revisions_only=None):
2021
if append_revisions_only:
2022
return "append_revisions_only = True\n"
2024
# Avoid writing anything if append_revisions_only is disabled,
2025
# as that is the default.
2028
1990
def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
2029
1991
repository=None):
2030
1992
"""Initialize a branch in a bzrdir, with specified files
2084
2046
except errors.NoSuchFile:
2085
2047
raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2088
def _matchingbzrdir(self):
2089
ret = bzrdir.BzrDirMetaFormat1()
2090
ret.set_branch_format(self)
2050
super(BranchFormatMetadir, self).__init__()
2051
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2052
self._matchingbzrdir.set_branch_format(self)
2093
2054
def supports_tags(self):
2121
2082
"""See BranchFormat.get_format_description()."""
2122
2083
return "Branch format 5"
2124
def initialize(self, a_bzrdir, name=None, repository=None,
2125
append_revisions_only=None):
2085
def initialize(self, a_bzrdir, name=None, repository=None):
2126
2086
"""Create a branch of this format in a_bzrdir."""
2127
if append_revisions_only:
2128
raise errors.UpgradeRequired(a_bzrdir.user_url)
2129
2087
utf8_files = [('revision-history', ''),
2130
2088
('branch-name', ''),
2157
2115
"""See BranchFormat.get_format_description()."""
2158
2116
return "Branch format 6"
2160
def initialize(self, a_bzrdir, name=None, repository=None,
2161
append_revisions_only=None):
2118
def initialize(self, a_bzrdir, name=None, repository=None):
2162
2119
"""Create a branch of this format in a_bzrdir."""
2163
2120
utf8_files = [('last-revision', '0 null:\n'),
2165
self._get_initial_config(append_revisions_only)),
2121
('branch.conf', ''),
2168
2124
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2170
2126
def make_tags(self, branch):
2171
2127
"""See bzrlib.branch.BranchFormat.make_tags()."""
2172
return _mod_tag.BasicTags(branch)
2128
return BasicTags(branch)
2174
2130
def supports_set_append_revisions_only(self):
2189
2145
"""See BranchFormat.get_format_description()."""
2190
2146
return "Branch format 8"
2192
def initialize(self, a_bzrdir, name=None, repository=None,
2193
append_revisions_only=None):
2148
def initialize(self, a_bzrdir, name=None, repository=None):
2194
2149
"""Create a branch of this format in a_bzrdir."""
2195
2150
utf8_files = [('last-revision', '0 null:\n'),
2197
self._get_initial_config(append_revisions_only)),
2151
('branch.conf', ''),
2199
2153
('references', '')
2203
2157
def make_tags(self, branch):
2204
2158
"""See bzrlib.branch.BranchFormat.make_tags()."""
2205
return _mod_tag.BasicTags(branch)
2159
return BasicTags(branch)
2207
2161
def supports_set_append_revisions_only(self):
2222
2176
This format was introduced in bzr 1.6.
2225
def initialize(self, a_bzrdir, name=None, repository=None,
2226
append_revisions_only=None):
2179
def initialize(self, a_bzrdir, name=None, repository=None):
2227
2180
"""Create a branch of this format in a_bzrdir."""
2228
2181
utf8_files = [('last-revision', '0 null:\n'),
2230
self._get_initial_config(append_revisions_only)),
2182
('branch.conf', ''),
2233
2185
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2252
2204
def make_tags(self, branch):
2253
2205
"""See bzrlib.branch.BranchFormat.make_tags()."""
2254
return _mod_tag.BasicTags(branch)
2206
return BasicTags(branch)
2256
2208
supports_reference_locations = False
2259
class BranchReferenceFormat(BranchFormatMetadir):
2211
class BranchReferenceFormat(BranchFormat):
2260
2212
"""Bzr branch reference format.
2262
2214
Branch references are used in implementing checkouts, they
2286
2238
location = transport.put_bytes('location', to_branch.base)
2288
2240
def initialize(self, a_bzrdir, name=None, target_branch=None,
2289
repository=None, append_revisions_only=None):
2290
2242
"""Create a branch of this format in a_bzrdir."""
2291
2243
if target_branch is None:
2292
2244
# this format does not implement branch itself, thus the implicit
2293
2245
# creation contract must see it as uninitializable
2294
2246
raise errors.UninitializableFormat(self)
2295
2247
mutter('creating branch reference in %s', a_bzrdir.user_url)
2296
if a_bzrdir._format.fixed_components:
2297
raise errors.IncompatibleFormat(self, a_bzrdir._format)
2298
2248
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2299
2249
branch_transport.put_bytes('location',
2300
2250
target_branch.bzrdir.user_url)
2305
2255
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)
2308
2263
def _make_reference_clone_function(format, a_branch):
2309
2264
"""Create a clone() routine for a branch dynamically."""
2310
2265
def clone(to_bzrdir, revision_id=None,
2339
2294
(format, self))
2340
2295
if location is None:
2341
2296
location = self.get_reference(a_bzrdir, name)
2342
real_bzrdir = controldir.ControlDir.open(
2297
real_bzrdir = bzrdir.BzrDir.open(
2343
2298
location, possible_transports=possible_transports)
2344
2299
result = real_bzrdir.open_branch(name=name,
2345
2300
ignore_fallbacks=ignore_fallbacks)
2464
2419
base = property(_get_base, doc="The URL for the root of this branch.")
2466
2421
def _get_config(self):
2467
return _mod_config.TransportConfig(self._transport, 'branch.conf')
2422
return TransportConfig(self._transport, 'branch.conf')
2469
2424
def is_locked(self):
2470
2425
return self.control_files.is_locked()
2551
2506
raise errors.InvalidRevisionId(revision_id=revision_id, branch=self)
2552
2507
revision_id = _mod_revision.ensure_null(revision_id)
2553
2508
old_revno, old_revid = self.last_revision_info()
2554
if self.get_append_revisions_only():
2509
if self._get_append_revisions_only():
2555
2510
self._check_history_violation(revision_id)
2556
2511
self._run_pre_change_branch_tip_hooks(revno, revision_id)
2557
2512
self._write_last_revision_info(revno, revision_id)
2778
2733
if revision_id == _mod_revision.NULL_REVISION:
2779
2734
new_history = []
2781
new_history = self._revision_history()
2736
new_history = self.revision_history()
2782
2737
if revision_id is not None and new_history != []:
2784
2739
new_history = new_history[:new_history.index(revision_id) + 1]
2987
2942
# you can always ask for the URL; but you might not be able to use it
2988
2943
# if the repo can't support stacking.
2989
2944
## self._check_stackable_repo()
2990
# stacked_on_location is only ever defined in branch.conf, so don't
2991
# waste effort reading the whole stack of config files.
2992
config = self.get_config()._get_branch_data_config()
2993
stacked_url = self._get_config_location('stacked_on_location',
2945
stacked_url = self._get_config_location('stacked_on_location')
2995
2946
if stacked_url is None:
2996
2947
raise errors.NotStacked(self)
2997
2948
return stacked_url
2950
def _get_append_revisions_only(self):
2951
return self.get_config(
2952
).get_user_option_as_bool('append_revisions_only')
2999
2954
@needs_read_lock
3000
2955
def get_rev_id(self, revno, history=None):
3001
2956
"""Find the revision id of the specified revno."""
3087
3042
:ivar local_branch: target branch if there is a Master, else None
3088
3043
:ivar target_branch: Target/destination branch object. (write locked)
3089
3044
:ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to
3090
:ivar tag_updates: A dict with new tags, see BasicTags.merge_to
3093
3047
@deprecated_method(deprecated_in((2, 3, 0)))
3099
3053
return self.new_revno - self.old_revno
3101
3055
def report(self, to_file):
3102
tag_conflicts = getattr(self, "tag_conflicts", None)
3103
tag_updates = getattr(self, "tag_updates", None)
3104
3056
if not is_quiet():
3105
if self.old_revid != self.new_revid:
3057
if self.old_revid == self.new_revid:
3058
to_file.write('No revisions to pull.\n')
3106
3060
to_file.write('Now on revision %d.\n' % self.new_revno)
3108
to_file.write('%d tag(s) updated.\n' % len(tag_updates))
3109
if self.old_revid == self.new_revid and not tag_updates:
3110
if not tag_conflicts:
3111
to_file.write('No revisions or tags to pull.\n')
3113
to_file.write('No revisions to pull.\n')
3114
3061
self._show_tag_conficts(to_file)
3142
3089
return self.new_revno - self.old_revno
3144
3091
def report(self, to_file):
3145
# TODO: This function gets passed a to_file, but then
3146
# ignores it and calls note() instead. This is also
3147
# inconsistent with PullResult(), which writes to stdout.
3148
# -- JRV20110901, bug #838853
3149
tag_conflicts = getattr(self, "tag_conflicts", None)
3150
tag_updates = getattr(self, "tag_updates", None)
3152
if self.old_revid != self.new_revid:
3153
note(gettext('Pushed up to revision %d.') % self.new_revno)
3155
note(ngettext('%d tag updated.', '%d tags updated.', len(tag_updates)) % len(tag_updates))
3156
if self.old_revid == self.new_revid and not tag_updates:
3157
if not tag_conflicts:
3158
note(gettext('No new revisions or tags to push.'))
3160
note(gettext('No new revisions to push.'))
3092
"""Write a human-readable description of the result."""
3093
if self.old_revid == self.new_revid:
3094
note('No new revisions to push.')
3096
note('Pushed up to revision %d.' % self.new_revno)
3161
3097
self._show_tag_conficts(to_file)
3177
3113
:param verbose: Requests more detailed display of what was checked,
3180
note(gettext('checked branch {0} format {1}').format(
3181
self.branch.user_url, self.branch._format))
3116
note('checked branch %s format %s', self.branch.user_url,
3117
self.branch._format)
3182
3118
for error in self.errors:
3183
note(gettext('found error:%s'), error)
3119
note('found error:%s', error)
3186
3122
class Converter5to6(object):
3227
3163
class Converter7to8(object):
3228
"""Perform an in-place upgrade of format 7 to format 8"""
3164
"""Perform an in-place upgrade of format 6 to format 7"""
3230
3166
def convert(self, branch):
3231
3167
format = BzrBranchFormat8()
3404
3340
if local and not bound_location:
3405
3341
raise errors.LocalRequiresBoundBranch()
3406
3342
master_branch = None
3407
source_is_master = False
3409
# bound_location comes from a config file, some care has to be
3410
# taken to relate it to source.user_url
3411
normalized = urlutils.normalize_url(bound_location)
3413
relpath = self.source.user_transport.relpath(normalized)
3414
source_is_master = (relpath == '')
3415
except (errors.PathNotChild, errors.InvalidURL):
3416
source_is_master = False
3343
source_is_master = (self.source.user_url == bound_location)
3417
3344
if not local and bound_location and not source_is_master:
3418
3345
# not pulling from master, so we need to update master.
3419
3346
master_branch = self.target.get_master_branch(possible_transports)
3471
3398
self._update_revisions(stop_revision, overwrite=overwrite,
3473
3400
if self.source._push_should_merge_tags():
3474
result.tag_updates, result.tag_conflicts = (
3475
self.source.tags.merge_to(self.target.tags, overwrite))
3401
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3476
3403
result.new_revno, result.new_revid = self.target.last_revision_info()
3561
3488
# TODO: The old revid should be specified when merging tags,
3562
3489
# so a tags implementation that versions tags can only
3563
3490
# pull in the most recent changes. -- JRV20090506
3564
result.tag_updates, result.tag_conflicts = (
3565
self.source.tags.merge_to(self.target.tags, overwrite,
3566
ignore_master=not merge_tags_to_master))
3491
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3492
overwrite, ignore_master=not merge_tags_to_master)
3567
3493
result.new_revno, result.new_revid = self.target.last_revision_info()
3568
3494
if _hook_master:
3569
3495
result.master_branch = _hook_master