~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Packman
  • Date: 2012-01-05 09:50:04 UTC
  • mfrom: (6424 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6426.
  • Revision ID: martin.packman@canonical.com-20120105095004-mia9xb7y0efmto0v
Merge bzr.dev to resolve conflicts in bzrlib.builtins

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
from __future__ import absolute_import
 
18
 
 
19
import bzrlib.bzrdir
17
20
 
18
21
from cStringIO import StringIO
19
22
 
21
24
lazy_import(globals(), """
22
25
import itertools
23
26
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
 
        )
 
27
    bzrdir,
 
28
    controldir,
 
29
    cache_utf8,
 
30
    cleanup,
 
31
    config as _mod_config,
 
32
    debug,
 
33
    errors,
 
34
    fetch,
 
35
    graph as _mod_graph,
 
36
    lockdir,
 
37
    lockable_files,
 
38
    remote,
 
39
    repository,
 
40
    revision as _mod_revision,
 
41
    rio,
 
42
    tag as _mod_tag,
 
43
    transport,
 
44
    ui,
 
45
    urlutils,
 
46
    vf_search,
 
47
    )
 
48
from bzrlib.i18n import gettext, ngettext
43
49
""")
44
50
 
 
51
# Explicitly import bzrlib.bzrdir so that the BzrProber
 
52
# is guaranteed to be registered.
 
53
import bzrlib.bzrdir
 
54
 
45
55
from bzrlib import (
 
56
    bzrdir,
46
57
    controldir,
47
58
    )
48
59
from bzrlib.decorators import (
83
94
    def user_transport(self):
84
95
        return self.bzrdir.user_transport
85
96
 
86
 
    def __init__(self, *ignored, **ignored_too):
 
97
    def __init__(self, possible_transports=None):
87
98
        self.tags = self._format.make_tags(self)
88
99
        self._revision_history_cache = None
89
100
        self._revision_id_to_revno_cache = None
93
104
        self._last_revision_info_cache = None
94
105
        self._master_branch_cache = None
95
106
        self._merge_sorted_revisions_cache = None
96
 
        self._open_hook()
 
107
        self._open_hook(possible_transports)
97
108
        hooks = Branch.hooks['open']
98
109
        for hook in hooks:
99
110
            hook(self)
100
111
 
101
 
    def _open_hook(self):
 
112
    def _open_hook(self, possible_transports):
102
113
        """Called by init to allow simpler extension of the base class."""
103
114
 
104
 
    def _activate_fallback_location(self, url):
 
115
    def _activate_fallback_location(self, url, possible_transports):
105
116
        """Activate the branch/repository from url as a fallback repository."""
106
117
        for existing_fallback_repo in self.repository._fallback_repositories:
107
118
            if existing_fallback_repo.user_url == url:
108
119
                # This fallback is already configured.  This probably only
109
 
                # happens because BzrDir.sprout is a horrible mess.  To avoid
 
120
                # happens because ControlDir.sprout is a horrible mess.  To avoid
110
121
                # confusing _unstack we don't add this a second time.
111
122
                mutter('duplicate activation of fallback %r on %r', url, self)
112
123
                return
113
 
        repo = self._get_fallback_repository(url)
 
124
        repo = self._get_fallback_repository(url, possible_transports)
114
125
        if repo.has_same_location(self.repository):
115
126
            raise errors.UnstackableLocationError(self.user_url, url)
116
127
        self.repository.add_fallback_repository(repo)
170
181
        For instance, if the branch is at URL/.bzr/branch,
171
182
        Branch.open(URL) -> a Branch instance.
172
183
        """
173
 
        control = bzrdir.BzrDir.open(base, _unsupported,
174
 
                                     possible_transports=possible_transports)
175
 
        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)
176
188
 
177
189
    @staticmethod
178
 
    def open_from_transport(transport, name=None, _unsupported=False):
 
190
    def open_from_transport(transport, name=None, _unsupported=False,
 
191
            possible_transports=None):
179
192
        """Open the branch rooted at transport"""
180
 
        control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
181
 
        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)
182
196
 
183
197
    @staticmethod
184
198
    def open_containing(url, possible_transports=None):
192
206
        format, UnknownFormatError or UnsupportedFormatError are raised.
193
207
        If there is one, it is returned, along with the unused portion of url.
194
208
        """
195
 
        control, relpath = bzrdir.BzrDir.open_containing(url,
 
209
        control, relpath = controldir.ControlDir.open_containing(url,
196
210
                                                         possible_transports)
197
 
        return control.open_branch(), relpath
 
211
        branch = control.open_branch(possible_transports=possible_transports)
 
212
        return (branch, relpath)
198
213
 
199
214
    def _push_should_merge_tags(self):
200
215
        """Should _basic_push merge this branch's tags into the target?
214
229
        """
215
230
        return _mod_config.BranchConfig(self)
216
231
 
 
232
    def get_config_stack(self):
 
233
        """Get a bzrlib.config.BranchStack for this Branch.
 
234
 
 
235
        This can then be used to get and set configuration options for the
 
236
        branch.
 
237
 
 
238
        :return: A bzrlib.config.BranchStack.
 
239
        """
 
240
        return _mod_config.BranchStack(self)
 
241
 
217
242
    def _get_config(self):
218
243
        """Get the concrete config for just the config in this branch.
219
244
 
226
251
        """
227
252
        raise NotImplementedError(self._get_config)
228
253
 
229
 
    def _get_fallback_repository(self, url):
 
254
    def _get_fallback_repository(self, url, possible_transports):
230
255
        """Get the repository we fallback to at url."""
231
256
        url = urlutils.join(self.base, url)
232
 
        a_branch = Branch.open(url,
233
 
            possible_transports=[self.bzrdir.root_transport])
 
257
        a_branch = Branch.open(url, possible_transports=possible_transports)
234
258
        return a_branch.repository
235
259
 
236
260
    @needs_read_lock
641
665
        """
642
666
        raise errors.UpgradeRequired(self.user_url)
643
667
 
 
668
    def get_append_revisions_only(self):
 
669
        """Whether it is only possible to append revisions to the history.
 
670
        """
 
671
        if not self._format.supports_set_append_revisions_only():
 
672
            return False
 
673
        return self.get_config_stack().get('append_revisions_only')
 
674
 
644
675
    def set_append_revisions_only(self, enabled):
645
676
        if not self._format.supports_set_append_revisions_only():
646
677
            raise errors.UpgradeRequired(self.user_url)
647
 
        if enabled:
648
 
            value = 'True'
649
 
        else:
650
 
            value = 'False'
651
 
        self.get_config().set_user_option('append_revisions_only', value,
652
 
            warn_masked=True)
 
678
        self.get_config_stack().set('append_revisions_only', enabled)
653
679
 
654
680
    def set_reference_info(self, file_id, tree_path, branch_location):
655
681
        """Set the branch location to use for a tree reference."""
684
710
        """
685
711
        raise errors.UpgradeRequired(self.user_url)
686
712
 
687
 
    def get_commit_builder(self, parents, config=None, timestamp=None,
 
713
    def get_commit_builder(self, parents, config_stack=None, timestamp=None,
688
714
                           timezone=None, committer=None, revprops=None,
689
715
                           revision_id=None, lossy=False):
690
716
        """Obtain a CommitBuilder for this branch.
700
726
            represented, when pushing to a foreign VCS 
701
727
        """
702
728
 
703
 
        if config is None:
704
 
            config = self.get_config()
 
729
        if config_stack is None:
 
730
            config_stack = self.get_config_stack()
705
731
 
706
 
        return self.repository.get_commit_builder(self, parents, config,
 
732
        return self.repository.get_commit_builder(self, parents, config_stack,
707
733
            timestamp, timezone, committer, revprops, revision_id,
708
734
            lossy)
709
735
 
714
740
        """
715
741
        return None
716
742
 
 
743
    @deprecated_method(deprecated_in((2, 5, 0)))
717
744
    def get_revision_delta(self, revno):
718
745
        """Return the delta for one revision.
719
746
 
720
747
        The delta is relative to its mainline predecessor, or the
721
748
        empty tree for revision 1.
722
749
        """
723
 
        rh = self.revision_history()
724
 
        if not (1 <= revno <= len(rh)):
 
750
        try:
 
751
            revid = self.get_rev_id(revno)
 
752
        except errors.NoSuchRevision:
725
753
            raise errors.InvalidRevisionNumber(revno)
726
 
        return self.repository.get_revision_delta(rh[revno-1])
 
754
        return self.repository.get_revision_delta(revid)
727
755
 
728
756
    def get_stacked_on_url(self):
729
757
        """Get the URL this branch is stacked against.
828
856
                return
829
857
            self._unstack()
830
858
        else:
831
 
            self._activate_fallback_location(url)
 
859
            self._activate_fallback_location(url,
 
860
                possible_transports=[self.bzrdir.root_transport])
832
861
        # write this out after the repository is stacked to avoid setting a
833
862
        # stacked config that doesn't work.
834
863
        self._set_config_location('stacked_on_location', url)
840
869
        """
841
870
        pb = ui.ui_factory.nested_progress_bar()
842
871
        try:
843
 
            pb.update("Unstacking")
 
872
            pb.update(gettext("Unstacking"))
844
873
            # The basic approach here is to fetch the tip of the branch,
845
874
            # including all available ghosts, from the existing stacked
846
875
            # repository into a new repository object without the fallbacks. 
860
889
            # stream from one of them to the other.  This does mean doing
861
890
            # separate SSH connection setup, but unstacking is not a
862
891
            # common operation so it's tolerable.
863
 
            new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
 
892
            new_bzrdir = controldir.ControlDir.open(
 
893
                self.bzrdir.root_transport.base)
864
894
            new_repository = new_bzrdir.find_repository()
865
895
            if new_repository._fallback_repositories:
866
896
                raise AssertionError("didn't expect %r to have "
909
939
                    tags_to_fetch = set(self.tags.get_reverse_tag_dict())
910
940
                except errors.TagsNotSupported:
911
941
                    tags_to_fetch = set()
912
 
                fetch_spec = _mod_graph.NotInOtherForRevs(self.repository,
 
942
                fetch_spec = vf_search.NotInOtherForRevs(self.repository,
913
943
                    old_repository, required_ids=[self.last_revision()],
914
944
                    if_present_ids=tags_to_fetch, find_ghosts=True).execute()
915
945
                self.repository.fetch(old_repository, fetch_spec=fetch_spec)
983
1013
        """
984
1014
        raise NotImplementedError(self._gen_revision_history)
985
1015
 
 
1016
    @deprecated_method(deprecated_in((2, 5, 0)))
986
1017
    @needs_read_lock
987
1018
    def revision_history(self):
988
1019
        """Return sequence of revision ids on this branch.
990
1021
        This method will cache the revision history for as long as it is safe to
991
1022
        do so.
992
1023
        """
 
1024
        return self._revision_history()
 
1025
 
 
1026
    def _revision_history(self):
993
1027
        if 'evil' in debug.debug_flags:
994
1028
            mutter_callsite(3, "revision_history scales with history.")
995
1029
        if self._revision_history_cache is not None:
1065
1099
        """Given a revision id, return its revno"""
1066
1100
        if _mod_revision.is_null(revision_id):
1067
1101
            return 0
1068
 
        history = self.revision_history()
 
1102
        history = self._revision_history()
1069
1103
        try:
1070
1104
            return history.index(revision_id) + 1
1071
1105
        except ValueError:
1136
1170
    def _set_config_location(self, name, url, config=None,
1137
1171
                             make_relative=False):
1138
1172
        if config is None:
1139
 
            config = self.get_config()
 
1173
            config = self.get_config_stack()
1140
1174
        if url is None:
1141
1175
            url = ''
1142
1176
        elif make_relative:
1143
1177
            url = urlutils.relative_url(self.base, url)
1144
 
        config.set_user_option(name, url, warn_masked=True)
 
1178
        config.set(name, url)
1145
1179
 
1146
1180
    def _get_config_location(self, name, config=None):
1147
1181
        if config is None:
1148
 
            config = self.get_config()
1149
 
        location = config.get_user_option(name)
 
1182
            config = self.get_config_stack()
 
1183
        location = config.get(name)
1150
1184
        if location == '':
1151
1185
            location = None
1152
1186
        return location
1368
1402
        # TODO: We should probably also check that self.revision_history
1369
1403
        # matches the repository for older branch formats.
1370
1404
        # If looking for the code that cross-checks repository parents against
1371
 
        # the iter_reverse_revision_history output, that is now a repository
 
1405
        # the Graph.iter_lefthand_ancestry output, that is now a repository
1372
1406
        # specific check.
1373
1407
        return result
1374
1408
 
1375
 
    def _get_checkout_format(self):
 
1409
    def _get_checkout_format(self, lightweight=False):
1376
1410
        """Return the most suitable metadir for a checkout of this branch.
1377
1411
        Weaves are used if this branch's repository uses weaves.
1378
1412
        """
1424
1458
        """
1425
1459
        t = transport.get_transport(to_location)
1426
1460
        t.ensure_base()
 
1461
        format = self._get_checkout_format(lightweight=lightweight)
1427
1462
        if lightweight:
1428
 
            format = self._get_checkout_format()
1429
1463
            checkout = format.initialize_on_transport(t)
1430
1464
            from_branch = BranchReferenceFormat().initialize(checkout, 
1431
1465
                target_branch=self)
1432
1466
        else:
1433
 
            format = self._get_checkout_format()
1434
 
            checkout_branch = bzrdir.BzrDir.create_branch_convenience(
 
1467
            checkout_branch = controldir.ControlDir.create_branch_convenience(
1435
1468
                to_location, force_new_tree=False, format=format)
1436
1469
            checkout = checkout_branch.bzrdir
1437
1470
            checkout_branch.bind(self)
1533
1566
            heads that must be fetched if present, but no error is necessary if
1534
1567
            they are not present.
1535
1568
        """
1536
 
        # For bzr native formats must_fetch is just the tip, and if_present_fetch
1537
 
        # are the tags.
 
1569
        # For bzr native formats must_fetch is just the tip, and
 
1570
        # if_present_fetch are the tags.
1538
1571
        must_fetch = set([self.last_revision()])
1539
1572
        if_present_fetch = set()
1540
 
        c = self.get_config()
1541
 
        include_tags = c.get_user_option_as_bool('branch.fetch_tags',
1542
 
                                                 default=False)
1543
 
        if include_tags:
 
1573
        if self.get_config_stack().get('branch.fetch_tags'):
1544
1574
            try:
1545
1575
                if_present_fetch = set(self.tags.get_reverse_tag_dict())
1546
1576
            except errors.TagsNotSupported:
1555
1585
 
1556
1586
    Formats provide three things:
1557
1587
     * An initialization routine,
1558
 
     * a format string,
 
1588
     * a format description
1559
1589
     * an open routine.
1560
1590
 
1561
1591
    Formats are placed in an dict by their format string for reference
1568
1598
    object will be created every time regardless.
1569
1599
    """
1570
1600
 
1571
 
    can_set_append_revisions_only = True
1572
 
 
1573
1601
    def __eq__(self, other):
1574
1602
        return self.__class__ is other.__class__
1575
1603
 
1577
1605
        return not (self == other)
1578
1606
 
1579
1607
    @classmethod
1580
 
    def find_format(klass, a_bzrdir, name=None):
1581
 
        """Return the format for the branch object in a_bzrdir."""
1582
 
        try:
1583
 
            transport = a_bzrdir.get_branch_transport(None, name=name)
1584
 
            format_string = transport.get_bytes("format")
1585
 
            return format_registry.get(format_string)
1586
 
        except errors.NoSuchFile:
1587
 
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
1588
 
        except KeyError:
1589
 
            raise errors.UnknownFormatError(format=format_string, kind='branch')
1590
 
 
1591
 
    @classmethod
1592
1608
    @deprecated_method(deprecated_in((2, 4, 0)))
1593
1609
    def get_default_format(klass):
1594
1610
        """Return the current default format."""
1604
1620
        """
1605
1621
        return format_registry._get_all()
1606
1622
 
1607
 
    def get_reference(self, a_bzrdir, name=None):
1608
 
        """Get the target reference of the branch in a_bzrdir.
 
1623
    def get_reference(self, controldir, name=None):
 
1624
        """Get the target reference of the branch in controldir.
1609
1625
 
1610
1626
        format probing must have been completed before calling
1611
1627
        this method - it is assumed that the format of the branch
1612
 
        in a_bzrdir is correct.
 
1628
        in controldir is correct.
1613
1629
 
1614
 
        :param a_bzrdir: The bzrdir to get the branch data from.
 
1630
        :param controldir: The controldir to get the branch data from.
1615
1631
        :param name: Name of the colocated branch to fetch
1616
1632
        :return: None if the branch is not a reference branch.
1617
1633
        """
1618
1634
        return None
1619
1635
 
1620
1636
    @classmethod
1621
 
    def set_reference(self, a_bzrdir, name, to_branch):
1622
 
        """Set the target reference of the branch in a_bzrdir.
 
1637
    def set_reference(self, controldir, name, to_branch):
 
1638
        """Set the target reference of the branch in controldir.
1623
1639
 
1624
1640
        format probing must have been completed before calling
1625
1641
        this method - it is assumed that the format of the branch
1626
 
        in a_bzrdir is correct.
 
1642
        in controldir is correct.
1627
1643
 
1628
 
        :param a_bzrdir: The bzrdir to set the branch reference for.
 
1644
        :param controldir: The controldir to set the branch reference for.
1629
1645
        :param name: Name of colocated branch to set, None for default
1630
1646
        :param to_branch: branch that the checkout is to reference
1631
1647
        """
1632
1648
        raise NotImplementedError(self.set_reference)
1633
1649
 
1634
 
    def get_format_string(self):
1635
 
        """Return the ASCII format string that identifies this format."""
1636
 
        raise NotImplementedError(self.get_format_string)
1637
 
 
1638
1650
    def get_format_description(self):
1639
1651
        """Return the short format description for this format."""
1640
1652
        raise NotImplementedError(self.get_format_description)
1641
1653
 
1642
 
    def _run_post_branch_init_hooks(self, a_bzrdir, name, branch):
 
1654
    def _run_post_branch_init_hooks(self, controldir, name, branch):
1643
1655
        hooks = Branch.hooks['post_branch_init']
1644
1656
        if not hooks:
1645
1657
            return
1646
 
        params = BranchInitHookParams(self, a_bzrdir, name, branch)
 
1658
        params = BranchInitHookParams(self, controldir, name, branch)
1647
1659
        for hook in hooks:
1648
1660
            hook(params)
1649
1661
 
1650
 
    def initialize(self, a_bzrdir, name=None, repository=None):
1651
 
        """Create a branch of this format in a_bzrdir.
1652
 
        
 
1662
    def initialize(self, controldir, name=None, repository=None,
 
1663
                   append_revisions_only=None):
 
1664
        """Create a branch of this format in controldir.
 
1665
 
1653
1666
        :param name: Name of the colocated branch to create.
1654
1667
        """
1655
1668
        raise NotImplementedError(self.initialize)
1687
1700
        """
1688
1701
        raise NotImplementedError(self.network_name)
1689
1702
 
1690
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
1691
 
            found_repository=None):
1692
 
        """Return the branch object for a_bzrdir
 
1703
    def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
 
1704
            found_repository=None, possible_transports=None):
 
1705
        """Return the branch object for controldir.
1693
1706
 
1694
 
        :param a_bzrdir: A BzrDir that contains a branch.
 
1707
        :param controldir: A ControlDir that contains a branch.
1695
1708
        :param name: Name of colocated branch to open
1696
1709
        :param _found: a private parameter, do not use it. It is used to
1697
1710
            indicate if format probing has already be done.
1739
1752
        """True if this format supports tags stored in the branch"""
1740
1753
        return False  # by default
1741
1754
 
 
1755
    def tags_are_versioned(self):
 
1756
        """Whether the tag container for this branch versions tags."""
 
1757
        return False
 
1758
 
 
1759
    def supports_tags_referencing_ghosts(self):
 
1760
        """True if tags can reference ghost revisions."""
 
1761
        return True
 
1762
 
1742
1763
 
1743
1764
class MetaDirBranchFormatFactory(registry._LazyObjectGetter):
1744
1765
    """A factory for a BranchFormat object, permitting simple lazy registration.
1758
1779
        """
1759
1780
        registry._LazyObjectGetter.__init__(self, module_name, member_name)
1760
1781
        self._format_string = format_string
1761
 
        
 
1782
 
1762
1783
    def get_format_string(self):
1763
1784
        """See BranchFormat.get_format_string."""
1764
1785
        return self._format_string
1909
1930
    There are 4 fields that hooks may wish to access:
1910
1931
 
1911
1932
    :ivar format: the branch format
1912
 
    :ivar bzrdir: the BzrDir where the branch will be/has been initialized
 
1933
    :ivar bzrdir: the ControlDir where the branch will be/has been initialized
1913
1934
    :ivar name: name of colocated branch, if any (or None)
1914
1935
    :ivar branch: the branch created
1915
1936
 
1918
1939
    branch, which refer to the original branch.
1919
1940
    """
1920
1941
 
1921
 
    def __init__(self, format, a_bzrdir, name, branch):
 
1942
    def __init__(self, format, controldir, name, branch):
1922
1943
        """Create a group of BranchInitHook parameters.
1923
1944
 
1924
1945
        :param format: the branch format
1925
 
        :param a_bzrdir: the BzrDir where the branch will be/has been
 
1946
        :param controldir: the ControlDir where the branch will be/has been
1926
1947
            initialized
1927
1948
        :param name: name of colocated branch, if any (or None)
1928
1949
        :param branch: the branch created
1932
1953
        in branch, which refer to the original branch.
1933
1954
        """
1934
1955
        self.format = format
1935
 
        self.bzrdir = a_bzrdir
 
1956
        self.bzrdir = controldir
1936
1957
        self.name = name
1937
1958
        self.branch = branch
1938
1959
 
1948
1969
 
1949
1970
    There are 4 fields that hooks may wish to access:
1950
1971
 
1951
 
    :ivar control_dir: BzrDir of the checkout to change
 
1972
    :ivar control_dir: ControlDir of the checkout to change
1952
1973
    :ivar to_branch: branch that the checkout is to reference
1953
1974
    :ivar force: skip the check for local commits in a heavy checkout
1954
1975
    :ivar revision_id: revision ID to switch to (or None)
1957
1978
    def __init__(self, control_dir, to_branch, force, revision_id):
1958
1979
        """Create a group of SwitchHook parameters.
1959
1980
 
1960
 
        :param control_dir: BzrDir of the checkout to change
 
1981
        :param control_dir: ControlDir of the checkout to change
1961
1982
        :param to_branch: branch that the checkout is to reference
1962
1983
        :param force: skip the check for local commits in a heavy checkout
1963
1984
        :param revision_id: revision ID to switch to (or None)
1976
1997
            self.revision_id)
1977
1998
 
1978
1999
 
1979
 
class BranchFormatMetadir(BranchFormat):
1980
 
    """Common logic for meta-dir based branch formats."""
 
2000
class BranchFormatMetadir(bzrdir.BzrFormat, BranchFormat):
 
2001
    """Base class for branch formats that live in meta directories.
 
2002
    """
 
2003
 
 
2004
    def __init__(self):
 
2005
        BranchFormat.__init__(self)
 
2006
        bzrdir.BzrFormat.__init__(self)
 
2007
 
 
2008
    @classmethod
 
2009
    def find_format(klass, controldir, name=None):
 
2010
        """Return the format for the branch object in controldir."""
 
2011
        try:
 
2012
            transport = controldir.get_branch_transport(None, name=name)
 
2013
        except errors.NoSuchFile:
 
2014
            raise errors.NotBranchError(path=name, bzrdir=controldir)
 
2015
        try:
 
2016
            format_string = transport.get_bytes("format")
 
2017
        except errors.NoSuchFile:
 
2018
            raise errors.NotBranchError(path=transport.base, bzrdir=controldir)
 
2019
        return klass._find_format(format_registry, 'branch', format_string)
1981
2020
 
1982
2021
    def _branch_class(self):
1983
2022
        """What class to instantiate on open calls."""
1984
2023
        raise NotImplementedError(self._branch_class)
1985
2024
 
 
2025
    def _get_initial_config(self, append_revisions_only=None):
 
2026
        if append_revisions_only:
 
2027
            return "append_revisions_only = True\n"
 
2028
        else:
 
2029
            # Avoid writing anything if append_revisions_only is disabled,
 
2030
            # as that is the default.
 
2031
            return ""
 
2032
 
1986
2033
    def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1987
2034
                           repository=None):
1988
2035
        """Initialize a branch in a bzrdir, with specified files
2000
2047
        control_files.create_lock()
2001
2048
        control_files.lock_write()
2002
2049
        try:
2003
 
            utf8_files += [('format', self.get_format_string())]
 
2050
            utf8_files += [('format', self.as_string())]
2004
2051
            for (filename, content) in utf8_files:
2005
2052
                branch_transport.put_bytes(
2006
2053
                    filename, content,
2012
2059
        self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2013
2060
        return branch
2014
2061
 
2015
 
    def network_name(self):
2016
 
        """A simple byte string uniquely identifying this format for RPC calls.
2017
 
 
2018
 
        Metadir branch formats use their format string.
2019
 
        """
2020
 
        return self.get_format_string()
2021
 
 
2022
2062
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
2023
 
            found_repository=None):
 
2063
            found_repository=None, possible_transports=None):
2024
2064
        """See BranchFormat.open()."""
2025
2065
        if not _found:
2026
 
            format = BranchFormat.find_format(a_bzrdir, name=name)
 
2066
            format = BranchFormatMetadir.find_format(a_bzrdir, name=name)
2027
2067
            if format.__class__ != self.__class__:
2028
2068
                raise AssertionError("wrong format %r found for %r" %
2029
2069
                    (format, self))
2038
2078
                              name=name,
2039
2079
                              a_bzrdir=a_bzrdir,
2040
2080
                              _repository=found_repository,
2041
 
                              ignore_fallbacks=ignore_fallbacks)
 
2081
                              ignore_fallbacks=ignore_fallbacks,
 
2082
                              possible_transports=possible_transports)
2042
2083
        except errors.NoSuchFile:
2043
2084
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2044
2085
 
2045
 
    def __init__(self):
2046
 
        super(BranchFormatMetadir, self).__init__()
2047
 
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2048
 
        self._matchingbzrdir.set_branch_format(self)
 
2086
    @property
 
2087
    def _matchingbzrdir(self):
 
2088
        ret = bzrdir.BzrDirMetaFormat1()
 
2089
        ret.set_branch_format(self)
 
2090
        return ret
2049
2091
 
2050
2092
    def supports_tags(self):
2051
2093
        return True
2053
2095
    def supports_leaving_lock(self):
2054
2096
        return True
2055
2097
 
 
2098
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
 
2099
            basedir=None):
 
2100
        BranchFormat.check_support_status(self,
 
2101
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
 
2102
            basedir=basedir)
 
2103
        bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
 
2104
            recommend_upgrade=recommend_upgrade, basedir=basedir)
 
2105
 
2056
2106
 
2057
2107
class BzrBranchFormat5(BranchFormatMetadir):
2058
2108
    """Bzr branch format 5.
2070
2120
    def _branch_class(self):
2071
2121
        return BzrBranch5
2072
2122
 
2073
 
    def get_format_string(self):
 
2123
    @classmethod
 
2124
    def get_format_string(cls):
2074
2125
        """See BranchFormat.get_format_string()."""
2075
2126
        return "Bazaar-NG branch format 5\n"
2076
2127
 
2078
2129
        """See BranchFormat.get_format_description()."""
2079
2130
        return "Branch format 5"
2080
2131
 
2081
 
    def initialize(self, a_bzrdir, name=None, repository=None):
 
2132
    def initialize(self, a_bzrdir, name=None, repository=None,
 
2133
                   append_revisions_only=None):
2082
2134
        """Create a branch of this format in a_bzrdir."""
 
2135
        if append_revisions_only:
 
2136
            raise errors.UpgradeRequired(a_bzrdir.user_url)
2083
2137
        utf8_files = [('revision-history', ''),
2084
2138
                      ('branch-name', ''),
2085
2139
                      ]
2103
2157
    def _branch_class(self):
2104
2158
        return BzrBranch6
2105
2159
 
2106
 
    def get_format_string(self):
 
2160
    @classmethod
 
2161
    def get_format_string(cls):
2107
2162
        """See BranchFormat.get_format_string()."""
2108
2163
        return "Bazaar Branch Format 6 (bzr 0.15)\n"
2109
2164
 
2111
2166
        """See BranchFormat.get_format_description()."""
2112
2167
        return "Branch format 6"
2113
2168
 
2114
 
    def initialize(self, a_bzrdir, name=None, repository=None):
 
2169
    def initialize(self, a_bzrdir, name=None, repository=None,
 
2170
                   append_revisions_only=None):
2115
2171
        """Create a branch of this format in a_bzrdir."""
2116
2172
        utf8_files = [('last-revision', '0 null:\n'),
2117
 
                      ('branch.conf', ''),
 
2173
                      ('branch.conf',
 
2174
                          self._get_initial_config(append_revisions_only)),
2118
2175
                      ('tags', ''),
2119
2176
                      ]
2120
2177
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2133
2190
    def _branch_class(self):
2134
2191
        return BzrBranch8
2135
2192
 
2136
 
    def get_format_string(self):
 
2193
    @classmethod
 
2194
    def get_format_string(cls):
2137
2195
        """See BranchFormat.get_format_string()."""
2138
2196
        return "Bazaar Branch Format 8 (needs bzr 1.15)\n"
2139
2197
 
2141
2199
        """See BranchFormat.get_format_description()."""
2142
2200
        return "Branch format 8"
2143
2201
 
2144
 
    def initialize(self, a_bzrdir, name=None, repository=None):
 
2202
    def initialize(self, a_bzrdir, name=None, repository=None,
 
2203
                   append_revisions_only=None):
2145
2204
        """Create a branch of this format in a_bzrdir."""
2146
2205
        utf8_files = [('last-revision', '0 null:\n'),
2147
 
                      ('branch.conf', ''),
 
2206
                      ('branch.conf',
 
2207
                          self._get_initial_config(append_revisions_only)),
2148
2208
                      ('tags', ''),
2149
2209
                      ('references', '')
2150
2210
                      ]
2172
2232
    This format was introduced in bzr 1.6.
2173
2233
    """
2174
2234
 
2175
 
    def initialize(self, a_bzrdir, name=None, repository=None):
 
2235
    def initialize(self, a_bzrdir, name=None, repository=None,
 
2236
                   append_revisions_only=None):
2176
2237
        """Create a branch of this format in a_bzrdir."""
2177
2238
        utf8_files = [('last-revision', '0 null:\n'),
2178
 
                      ('branch.conf', ''),
 
2239
                      ('branch.conf',
 
2240
                          self._get_initial_config(append_revisions_only)),
2179
2241
                      ('tags', ''),
2180
2242
                      ]
2181
2243
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2183
2245
    def _branch_class(self):
2184
2246
        return BzrBranch7
2185
2247
 
2186
 
    def get_format_string(self):
 
2248
    @classmethod
 
2249
    def get_format_string(cls):
2187
2250
        """See BranchFormat.get_format_string()."""
2188
2251
        return "Bazaar Branch Format 7 (needs bzr 1.6)\n"
2189
2252
 
2204
2267
    supports_reference_locations = False
2205
2268
 
2206
2269
 
2207
 
class BranchReferenceFormat(BranchFormat):
 
2270
class BranchReferenceFormat(BranchFormatMetadir):
2208
2271
    """Bzr branch reference format.
2209
2272
 
2210
2273
    Branch references are used in implementing checkouts, they
2215
2278
     - a format string
2216
2279
    """
2217
2280
 
2218
 
    def get_format_string(self):
 
2281
    @classmethod
 
2282
    def get_format_string(cls):
2219
2283
        """See BranchFormat.get_format_string()."""
2220
2284
        return "Bazaar-NG Branch Reference Format 1\n"
2221
2285
 
2234
2298
        location = transport.put_bytes('location', to_branch.base)
2235
2299
 
2236
2300
    def initialize(self, a_bzrdir, name=None, target_branch=None,
2237
 
            repository=None):
 
2301
            repository=None, append_revisions_only=None):
2238
2302
        """Create a branch of this format in a_bzrdir."""
2239
2303
        if target_branch is None:
2240
2304
            # this format does not implement branch itself, thus the implicit
2245
2309
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
2246
2310
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2247
2311
        branch_transport.put_bytes('location',
2248
 
            target_branch.bzrdir.user_url)
2249
 
        branch_transport.put_bytes('format', self.get_format_string())
 
2312
            target_branch.user_url)
 
2313
        branch_transport.put_bytes('format', self.as_string())
2250
2314
        branch = self.open(
2251
2315
            a_bzrdir, name, _found=True,
2252
2316
            possible_transports=[target_branch.bzrdir.root_transport])
2253
2317
        self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2254
2318
        return branch
2255
2319
 
2256
 
    def __init__(self):
2257
 
        super(BranchReferenceFormat, self).__init__()
2258
 
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
2259
 
        self._matchingbzrdir.set_branch_format(self)
2260
 
 
2261
2320
    def _make_reference_clone_function(format, a_branch):
2262
2321
        """Create a clone() routine for a branch dynamically."""
2263
2322
        def clone(to_bzrdir, revision_id=None,
2286
2345
        :param possible_transports: An optional reusable transports list.
2287
2346
        """
2288
2347
        if not _found:
2289
 
            format = BranchFormat.find_format(a_bzrdir, name=name)
 
2348
            format = BranchFormatMetadir.find_format(a_bzrdir, name=name)
2290
2349
            if format.__class__ != self.__class__:
2291
2350
                raise AssertionError("wrong format %r found for %r" %
2292
2351
                    (format, self))
2293
2352
        if location is None:
2294
2353
            location = self.get_reference(a_bzrdir, name)
2295
 
        real_bzrdir = bzrdir.BzrDir.open(
 
2354
        real_bzrdir = controldir.ControlDir.open(
2296
2355
            location, possible_transports=possible_transports)
2297
2356
        result = real_bzrdir.open_branch(name=name, 
2298
 
            ignore_fallbacks=ignore_fallbacks)
 
2357
            ignore_fallbacks=ignore_fallbacks,
 
2358
            possible_transports=possible_transports)
2299
2359
        # this changes the behaviour of result.clone to create a new reference
2300
2360
        # rather than a copy of the content of the branch.
2301
2361
        # I did not use a proxy object because that needs much more extensive
2382
2442
 
2383
2443
    def __init__(self, _format=None,
2384
2444
                 _control_files=None, a_bzrdir=None, name=None,
2385
 
                 _repository=None, ignore_fallbacks=False):
 
2445
                 _repository=None, ignore_fallbacks=False,
 
2446
                 possible_transports=None):
2386
2447
        """Create new branch object at a particular location."""
2387
2448
        if a_bzrdir is None:
2388
2449
            raise ValueError('a_bzrdir must be supplied')
2389
2450
        else:
2390
2451
            self.bzrdir = a_bzrdir
2391
 
        self._base = self.bzrdir.transport.clone('..').base
 
2452
        self._user_transport = self.bzrdir.transport.clone('..')
 
2453
        if name is not None:
 
2454
            self._user_transport.set_segment_parameter(
 
2455
                "branch", urlutils.escape(name))
 
2456
        self._base = self._user_transport.base
2392
2457
        self.name = name
2393
 
        # XXX: We should be able to just do
2394
 
        #   self.base = self.bzrdir.root_transport.base
2395
 
        # but this does not quite work yet -- mbp 20080522
2396
2458
        self._format = _format
2397
2459
        if _control_files is None:
2398
2460
            raise ValueError('BzrBranch _control_files is None')
2399
2461
        self.control_files = _control_files
2400
2462
        self._transport = _control_files._transport
2401
2463
        self.repository = _repository
2402
 
        Branch.__init__(self)
 
2464
        Branch.__init__(self, possible_transports)
2403
2465
 
2404
2466
    def __str__(self):
2405
 
        if self.name is None:
2406
 
            return '%s(%s)' % (self.__class__.__name__, self.user_url)
2407
 
        else:
2408
 
            return '%s(%s,%s)' % (self.__class__.__name__, self.user_url,
2409
 
                self.name)
 
2467
        return '%s(%s)' % (self.__class__.__name__, self.user_url)
2410
2468
 
2411
2469
    __repr__ = __str__
2412
2470
 
2416
2474
 
2417
2475
    base = property(_get_base, doc="The URL for the root of this branch.")
2418
2476
 
 
2477
    @property
 
2478
    def user_transport(self):
 
2479
        return self._user_transport
 
2480
 
2419
2481
    def _get_config(self):
2420
2482
        return _mod_config.TransportConfig(self._transport, 'branch.conf')
2421
2483
 
 
2484
    def _get_config_store(self):
 
2485
        return _mod_config.BranchStore(self)
 
2486
 
2422
2487
    def is_locked(self):
2423
2488
        return self.control_files.is_locked()
2424
2489
 
2504
2569
            raise errors.InvalidRevisionId(revision_id=revision_id, branch=self)
2505
2570
        revision_id = _mod_revision.ensure_null(revision_id)
2506
2571
        old_revno, old_revid = self.last_revision_info()
2507
 
        if self._get_append_revisions_only():
 
2572
        if self.get_append_revisions_only():
2508
2573
            self._check_history_violation(revision_id)
2509
2574
        self._run_pre_change_branch_tip_hooks(revno, revision_id)
2510
2575
        self._write_last_revision_info(revno, revision_id)
2653
2718
        self._transport.put_bytes('last-revision', out_string,
2654
2719
            mode=self.bzrdir._get_file_mode())
2655
2720
 
 
2721
    @needs_write_lock
 
2722
    def update_feature_flags(self, updated_flags):
 
2723
        """Update the feature flags for this branch.
 
2724
 
 
2725
        :param updated_flags: Dictionary mapping feature names to necessities
 
2726
            A necessity can be None to indicate the feature should be removed
 
2727
        """
 
2728
        self._format._update_feature_flags(updated_flags)
 
2729
        self.control_transport.put_bytes('format', self._format.as_string())
 
2730
 
2656
2731
 
2657
2732
class FullHistoryBzrBranch(BzrBranch):
2658
2733
    """Bzr branch which contains the full revision history."""
2671
2746
        self._set_revision_history(history)
2672
2747
 
2673
2748
    def _read_last_revision_info(self):
2674
 
        rh = self.revision_history()
 
2749
        rh = self._revision_history()
2675
2750
        revno = len(rh)
2676
2751
        if revno:
2677
2752
            return (revno, rh[-1])
2731
2806
        if revision_id == _mod_revision.NULL_REVISION:
2732
2807
            new_history = []
2733
2808
        else:
2734
 
            new_history = self.revision_history()
 
2809
            new_history = self._revision_history()
2735
2810
        if revision_id is not None and new_history != []:
2736
2811
            try:
2737
2812
                new_history = new_history[:new_history.index(revision_id) + 1]
2765
2840
class BzrBranch8(BzrBranch):
2766
2841
    """A branch that stores tree-reference locations."""
2767
2842
 
2768
 
    def _open_hook(self):
 
2843
    def _open_hook(self, possible_transports=None):
2769
2844
        if self._ignore_fallbacks:
2770
2845
            return
 
2846
        if possible_transports is None:
 
2847
            possible_transports = [self.bzrdir.root_transport]
2771
2848
        try:
2772
2849
            url = self.get_stacked_on_url()
2773
2850
        except (errors.UnstackableRepositoryFormat, errors.NotStacked,
2781
2858
                    raise AssertionError(
2782
2859
                        "'transform_fallback_location' hook %s returned "
2783
2860
                        "None, not a URL." % hook_name)
2784
 
            self._activate_fallback_location(url)
 
2861
            self._activate_fallback_location(url,
 
2862
                possible_transports=possible_transports)
2785
2863
 
2786
2864
    def __init__(self, *args, **kwargs):
2787
2865
        self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)
2905
2983
        """See Branch.set_push_location."""
2906
2984
        self._master_branch_cache = None
2907
2985
        result = None
2908
 
        config = self.get_config()
 
2986
        conf = self.get_config_stack()
2909
2987
        if location is None:
2910
 
            if config.get_user_option('bound') != 'True':
 
2988
            if not conf.get('bound'):
2911
2989
                return False
2912
2990
            else:
2913
 
                config.set_user_option('bound', 'False', warn_masked=True)
 
2991
                conf.set('bound', 'False')
2914
2992
                return True
2915
2993
        else:
2916
2994
            self._set_config_location('bound_location', location,
2917
 
                                      config=config)
2918
 
            config.set_user_option('bound', 'True', warn_masked=True)
 
2995
                                      config=conf)
 
2996
            conf.set('bound', 'True')
2919
2997
        return True
2920
2998
 
2921
2999
    def _get_bound_location(self, bound):
2922
3000
        """Return the bound location in the config file.
2923
3001
 
2924
3002
        Return None if the bound parameter does not match"""
2925
 
        config = self.get_config()
2926
 
        config_bound = (config.get_user_option('bound') == 'True')
2927
 
        if config_bound != bound:
 
3003
        conf = self.get_config_stack()
 
3004
        if conf.get('bound') != bound:
2928
3005
            return None
2929
 
        return self._get_config_location('bound_location', config=config)
 
3006
        return self._get_config_location('bound_location', config=conf)
2930
3007
 
2931
3008
    def get_bound_location(self):
2932
3009
        """See Branch.set_push_location."""
2942
3019
        ## self._check_stackable_repo()
2943
3020
        # stacked_on_location is only ever defined in branch.conf, so don't
2944
3021
        # waste effort reading the whole stack of config files.
2945
 
        config = self.get_config()._get_branch_data_config()
 
3022
        conf = _mod_config.BranchOnlyStack(self)
2946
3023
        stacked_url = self._get_config_location('stacked_on_location',
2947
 
            config=config)
 
3024
                                                config=conf)
2948
3025
        if stacked_url is None:
2949
3026
            raise errors.NotStacked(self)
2950
 
        return stacked_url
2951
 
 
2952
 
    def _get_append_revisions_only(self):
2953
 
        return self.get_config(
2954
 
            ).get_user_option_as_bool('append_revisions_only')
 
3027
        return stacked_url.encode('utf-8')
2955
3028
 
2956
3029
    @needs_read_lock
2957
3030
    def get_rev_id(self, revno, history=None):
2987
3060
            except errors.RevisionNotPresent, e:
2988
3061
                raise errors.GhostRevisionsHaveNoRevno(revision_id, e.revision_id)
2989
3062
            index = len(self._partial_revision_history_cache) - 1
 
3063
            if index < 0:
 
3064
                raise errors.NoSuchRevision(self, revision_id)
2990
3065
            if self._partial_revision_history_cache[index] != revision_id:
2991
3066
                raise errors.NoSuchRevision(self, revision_id)
2992
3067
        return self.revno() - index
3044
3119
    :ivar local_branch: target branch if there is a Master, else None
3045
3120
    :ivar target_branch: Target/destination branch object. (write locked)
3046
3121
    :ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to
 
3122
    :ivar tag_updates: A dict with new tags, see BasicTags.merge_to
3047
3123
    """
3048
3124
 
3049
3125
    @deprecated_method(deprecated_in((2, 3, 0)))
3055
3131
        return self.new_revno - self.old_revno
3056
3132
 
3057
3133
    def report(self, to_file):
 
3134
        tag_conflicts = getattr(self, "tag_conflicts", None)
 
3135
        tag_updates = getattr(self, "tag_updates", None)
3058
3136
        if not is_quiet():
3059
 
            if self.old_revid == self.new_revid:
3060
 
                to_file.write('No revisions to pull.\n')
3061
 
            else:
 
3137
            if self.old_revid != self.new_revid:
3062
3138
                to_file.write('Now on revision %d.\n' % self.new_revno)
 
3139
            if tag_updates:
 
3140
                to_file.write('%d tag(s) updated.\n' % len(tag_updates))
 
3141
            if self.old_revid == self.new_revid and not tag_updates:
 
3142
                if not tag_conflicts:
 
3143
                    to_file.write('No revisions or tags to pull.\n')
 
3144
                else:
 
3145
                    to_file.write('No revisions to pull.\n')
3063
3146
        self._show_tag_conficts(to_file)
3064
3147
 
3065
3148
 
3091
3174
        return self.new_revno - self.old_revno
3092
3175
 
3093
3176
    def report(self, to_file):
3094
 
        """Write a human-readable description of the result."""
3095
 
        if self.old_revid == self.new_revid:
3096
 
            note('No new revisions to push.')
3097
 
        else:
3098
 
            note('Pushed up to revision %d.' % self.new_revno)
 
3177
        # TODO: This function gets passed a to_file, but then
 
3178
        # ignores it and calls note() instead. This is also
 
3179
        # inconsistent with PullResult(), which writes to stdout.
 
3180
        # -- JRV20110901, bug #838853
 
3181
        tag_conflicts = getattr(self, "tag_conflicts", None)
 
3182
        tag_updates = getattr(self, "tag_updates", None)
 
3183
        if not is_quiet():
 
3184
            if self.old_revid != self.new_revid:
 
3185
                note(gettext('Pushed up to revision %d.') % self.new_revno)
 
3186
            if tag_updates:
 
3187
                note(ngettext('%d tag updated.', '%d tags updated.', len(tag_updates)) % len(tag_updates))
 
3188
            if self.old_revid == self.new_revid and not tag_updates:
 
3189
                if not tag_conflicts:
 
3190
                    note(gettext('No new revisions or tags to push.'))
 
3191
                else:
 
3192
                    note(gettext('No new revisions to push.'))
3099
3193
        self._show_tag_conficts(to_file)
3100
3194
 
3101
3195
 
3115
3209
        :param verbose: Requests more detailed display of what was checked,
3116
3210
            if any.
3117
3211
        """
3118
 
        note('checked branch %s format %s', self.branch.user_url,
3119
 
            self.branch._format)
 
3212
        note(gettext('checked branch {0} format {1}').format(
 
3213
                                self.branch.user_url, self.branch._format))
3120
3214
        for error in self.errors:
3121
 
            note('found error:%s', error)
 
3215
            note(gettext('found error:%s'), error)
3122
3216
 
3123
3217
 
3124
3218
class Converter5to6(object):
3140
3234
 
3141
3235
        # Copying done; now update target format
3142
3236
        new_branch._transport.put_bytes('format',
3143
 
            format.get_format_string(),
 
3237
            format.as_string(),
3144
3238
            mode=new_branch.bzrdir._get_file_mode())
3145
3239
 
3146
3240
        # Clean up old files
3159
3253
        format = BzrBranchFormat7()
3160
3254
        branch._set_config_location('stacked_on_location', '')
3161
3255
        # update target format
3162
 
        branch._transport.put_bytes('format', format.get_format_string())
 
3256
        branch._transport.put_bytes('format', format.as_string())
3163
3257
 
3164
3258
 
3165
3259
class Converter7to8(object):
3169
3263
        format = BzrBranchFormat8()
3170
3264
        branch._transport.put_bytes('references', '')
3171
3265
        # update target format
3172
 
        branch._transport.put_bytes('format', format.get_format_string())
 
3266
        branch._transport.put_bytes('format', format.as_string())
3173
3267
 
3174
3268
 
3175
3269
class InterBranch(InterObject):
3409
3503
            self._update_revisions(stop_revision, overwrite=overwrite,
3410
3504
                    graph=graph)
3411
3505
        if self.source._push_should_merge_tags():
3412
 
            result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3413
 
                overwrite)
 
3506
            result.tag_updates, result.tag_conflicts = (
 
3507
                self.source.tags.merge_to(self.target.tags, overwrite))
3414
3508
        result.new_revno, result.new_revid = self.target.last_revision_info()
3415
3509
        return result
3416
3510
 
3499
3593
            # TODO: The old revid should be specified when merging tags, 
3500
3594
            # so a tags implementation that versions tags can only 
3501
3595
            # pull in the most recent changes. -- JRV20090506
3502
 
            result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3503
 
                overwrite, ignore_master=not merge_tags_to_master)
 
3596
            result.tag_updates, result.tag_conflicts = (
 
3597
                self.source.tags.merge_to(self.target.tags, overwrite,
 
3598
                    ignore_master=not merge_tags_to_master))
3504
3599
            result.new_revno, result.new_revid = self.target.last_revision_info()
3505
3600
            if _hook_master:
3506
3601
                result.master_branch = _hook_master