~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin
  • Date: 2011-04-15 21:22:57 UTC
  • mto: This revision was merged to the branch mainline in revision 5797.
  • Revision ID: gzlist@googlemail.com-20110415212257-jgtovwwp4be7egd9
Add release notes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
        bzrdir,
26
26
        cache_utf8,
27
27
        config as _mod_config,
28
 
        controldir,
29
28
        debug,
30
29
        errors,
 
30
        fetch,
 
31
        graph as _mod_graph,
31
32
        lockdir,
32
33
        lockable_files,
33
34
        remote,
41
42
        urlutils,
42
43
        )
43
44
from bzrlib.config import BranchConfig, TransportConfig
44
 
from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5RichRoot
45
45
from bzrlib.tag import (
46
46
    BasicTags,
47
47
    DisabledTags,
48
48
    )
49
49
""")
50
50
 
51
 
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
52
 
from bzrlib.hooks import HookPoint, Hooks
 
51
from bzrlib import (
 
52
    controldir,
 
53
    )
 
54
from bzrlib.decorators import (
 
55
    needs_read_lock,
 
56
    needs_write_lock,
 
57
    only_raises,
 
58
    )
 
59
from bzrlib.hooks import Hooks
53
60
from bzrlib.inter import InterObject
54
61
from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
55
62
from bzrlib import registry
71
78
    :ivar base:
72
79
        Base directory/url of the branch; using control_url and
73
80
        control_transport is more standardized.
74
 
 
75
 
    hooks: An instance of BranchHooks.
 
81
    :ivar hooks: An instance of BranchHooks.
 
82
    :ivar _master_branch_cache: cached result of get_master_branch, see
 
83
        _clear_cached_state.
76
84
    """
77
85
    # this is really an instance variable - FIXME move it there
78
86
    # - RBC 20060112
92
100
        self._revision_id_to_revno_cache = None
93
101
        self._partial_revision_id_to_revno_cache = {}
94
102
        self._partial_revision_history_cache = []
 
103
        self._tags_bytes = None
95
104
        self._last_revision_info_cache = None
 
105
        self._master_branch_cache = None
96
106
        self._merge_sorted_revisions_cache = None
97
107
        self._open_hook()
98
108
        hooks = Branch.hooks['open']
104
114
 
105
115
    def _activate_fallback_location(self, url):
106
116
        """Activate the branch/repository from url as a fallback repository."""
 
117
        for existing_fallback_repo in self.repository._fallback_repositories:
 
118
            if existing_fallback_repo.user_url == url:
 
119
                # This fallback is already configured.  This probably only
 
120
                # happens because BzrDir.sprout is a horrible mess.  To avoid
 
121
                # confusing _unstack we don't add this a second time.
 
122
                mutter('duplicate activation of fallback %r on %r', url, self)
 
123
                return
107
124
        repo = self._get_fallback_repository(url)
108
125
        if repo.has_same_location(self.repository):
109
126
            raise errors.UnstackableLocationError(self.user_url, url)
227
244
            possible_transports=[self.bzrdir.root_transport])
228
245
        return a_branch.repository
229
246
 
 
247
    @needs_read_lock
230
248
    def _get_tags_bytes(self):
231
249
        """Get the bytes of a serialised tags dict.
232
250
 
239
257
        :return: The bytes of the tags file.
240
258
        :seealso: Branch._set_tags_bytes.
241
259
        """
242
 
        return self._transport.get_bytes('tags')
 
260
        if self._tags_bytes is None:
 
261
            self._tags_bytes = self._transport.get_bytes('tags')
 
262
        return self._tags_bytes
243
263
 
244
264
    def _get_nick(self, local=False, possible_transports=None):
245
265
        config = self.get_config()
649
669
        raise errors.UnsupportedOperation(self.get_reference_info, self)
650
670
 
651
671
    @needs_write_lock
652
 
    def fetch(self, from_branch, last_revision=None, pb=None):
 
672
    def fetch(self, from_branch, last_revision=None, fetch_spec=None):
653
673
        """Copy revisions from from_branch into this branch.
654
674
 
655
675
        :param from_branch: Where to copy from.
656
676
        :param last_revision: What revision to stop at (None for at the end
657
677
                              of the branch.
658
 
        :param pb: An optional progress bar to use.
 
678
        :param fetch_spec: If specified, a SearchResult or
 
679
            PendingAncestryResult that describes which revisions to copy.  This
 
680
            allows copying multiple heads at once.  Mutually exclusive with
 
681
            last_revision.
659
682
        :return: None
660
683
        """
661
 
        if self.base == from_branch.base:
662
 
            return (0, [])
663
 
        if pb is not None:
664
 
            symbol_versioning.warn(
665
 
                symbol_versioning.deprecated_in((1, 14, 0))
666
 
                % "pb parameter to fetch()")
667
 
        from_branch.lock_read()
668
 
        try:
669
 
            if last_revision is None:
670
 
                last_revision = from_branch.last_revision()
671
 
                last_revision = _mod_revision.ensure_null(last_revision)
672
 
            return self.repository.fetch(from_branch.repository,
673
 
                                         revision_id=last_revision,
674
 
                                         pb=pb)
675
 
        finally:
676
 
            from_branch.unlock()
 
684
        return InterBranch.get(from_branch, self).fetch(last_revision,
 
685
            fetch_spec)
677
686
 
678
687
    def get_bound_location(self):
679
688
        """Return the URL of the branch we are bound to.
790
799
 
791
800
    def _unstack(self):
792
801
        """Change a branch to be unstacked, copying data as needed.
793
 
        
 
802
 
794
803
        Don't call this directly, use set_stacked_on_url(None).
795
804
        """
796
805
        pb = ui.ui_factory.nested_progress_bar()
805
814
            old_repository = self.repository
806
815
            if len(old_repository._fallback_repositories) != 1:
807
816
                raise AssertionError("can't cope with fallback repositories "
808
 
                    "of %r" % (self.repository,))
 
817
                    "of %r (fallbacks: %r)" % (old_repository,
 
818
                        old_repository._fallback_repositories))
809
819
            # Open the new repository object.
810
820
            # Repositories don't offer an interface to remove fallback
811
821
            # repositories today; take the conceptually simpler option and just
859
869
                # XXX: If you unstack a branch while it has a working tree
860
870
                # with a pending merge, the pending-merged revisions will no
861
871
                # longer be present.  You can (probably) revert and remerge.
862
 
                #
863
 
                # XXX: This only fetches up to the tip of the repository; it
864
 
                # doesn't bring across any tags.  That's fairly consistent
865
 
                # with how branch works, but perhaps not ideal.
866
 
                self.repository.fetch(old_repository,
867
 
                    revision_id=self.last_revision(),
868
 
                    find_ghosts=True)
 
872
                try:
 
873
                    tags_to_fetch = set(self.tags.get_reverse_tag_dict())
 
874
                except errors.TagsNotSupported:
 
875
                    tags_to_fetch = set()
 
876
                fetch_spec = _mod_graph.NotInOtherForRevs(self.repository,
 
877
                    old_repository, required_ids=[self.last_revision()],
 
878
                    if_present_ids=tags_to_fetch, find_ghosts=True).execute()
 
879
                self.repository.fetch(old_repository, fetch_spec=fetch_spec)
869
880
            finally:
870
881
                old_repository.unlock()
871
882
        finally:
876
887
 
877
888
        :seealso: Branch._get_tags_bytes.
878
889
        """
879
 
        return _run_with_write_locked_target(self, self._transport.put_bytes,
880
 
            'tags', bytes)
 
890
        return _run_with_write_locked_target(self, self._set_tags_bytes_locked,
 
891
                bytes)
 
892
 
 
893
    def _set_tags_bytes_locked(self, bytes):
 
894
        self._tags_bytes = bytes
 
895
        return self._transport.put_bytes('tags', bytes)
881
896
 
882
897
    def _cache_revision_history(self, rev_history):
883
898
        """Set the cached revision history to rev_history.
910
925
        self._revision_history_cache = None
911
926
        self._revision_id_to_revno_cache = None
912
927
        self._last_revision_info_cache = None
 
928
        self._master_branch_cache = None
913
929
        self._merge_sorted_revisions_cache = None
914
930
        self._partial_revision_history_cache = []
915
931
        self._partial_revision_id_to_revno_cache = {}
 
932
        self._tags_bytes = None
916
933
 
917
934
    def _gen_revision_history(self):
918
935
        """Return sequence of revision hashes on to this branch.
979
996
        else:
980
997
            return (0, _mod_revision.NULL_REVISION)
981
998
 
982
 
    @deprecated_method(deprecated_in((1, 6, 0)))
983
 
    def missing_revisions(self, other, stop_revision=None):
984
 
        """Return a list of new revisions that would perfectly fit.
985
 
 
986
 
        If self and other have not diverged, return a list of the revisions
987
 
        present in other, but missing from self.
988
 
        """
989
 
        self_history = self.revision_history()
990
 
        self_len = len(self_history)
991
 
        other_history = other.revision_history()
992
 
        other_len = len(other_history)
993
 
        common_index = min(self_len, other_len) -1
994
 
        if common_index >= 0 and \
995
 
            self_history[common_index] != other_history[common_index]:
996
 
            raise errors.DivergedBranches(self, other)
997
 
 
998
 
        if stop_revision is None:
999
 
            stop_revision = other_len
1000
 
        else:
1001
 
            if stop_revision > other_len:
1002
 
                raise errors.NoSuchRevision(self, stop_revision)
1003
 
        return other_history[self_len:stop_revision]
1004
 
 
1005
999
    def update_revisions(self, other, stop_revision=None, overwrite=False,
1006
 
                         graph=None):
 
1000
                         graph=None, fetch_tags=True):
1007
1001
        """Pull in new perfect-fit revisions.
1008
1002
 
1009
1003
        :param other: Another Branch to pull from
1012
1006
            to see if it is a proper descendant.
1013
1007
        :param graph: A Graph object that can be used to query history
1014
1008
            information. This can be None.
 
1009
        :param fetch_tags: Flag that specifies if tags from other should be
 
1010
            fetched too.
1015
1011
        :return: None
1016
1012
        """
1017
1013
        return InterBranch.get(other, self).update_revisions(stop_revision,
1018
 
            overwrite, graph)
 
1014
            overwrite, graph, fetch_tags=fetch_tags)
1019
1015
 
 
1016
    @deprecated_method(deprecated_in((2, 4, 0)))
1020
1017
    def import_last_revision_info(self, source_repo, revno, revid):
1021
1018
        """Set the last revision info, importing from another repo if necessary.
1022
1019
 
1023
 
        This is used by the bound branch code to upload a revision to
1024
 
        the master branch first before updating the tip of the local branch.
1025
 
 
1026
1020
        :param source_repo: Source repository to optionally fetch from
1027
1021
        :param revno: Revision number of the new tip
1028
1022
        :param revid: Revision id of the new tip
1031
1025
            self.repository.fetch(source_repo, revision_id=revid)
1032
1026
        self.set_last_revision_info(revno, revid)
1033
1027
 
 
1028
    def import_last_revision_info_and_tags(self, source, revno, revid):
 
1029
        """Set the last revision info, importing from another repo if necessary.
 
1030
 
 
1031
        This is used by the bound branch code to upload a revision to
 
1032
        the master branch first before updating the tip of the local branch.
 
1033
        Revisions referenced by source's tags are also transferred.
 
1034
 
 
1035
        :param source: Source branch to optionally fetch from
 
1036
        :param revno: Revision number of the new tip
 
1037
        :param revid: Revision id of the new tip
 
1038
        """
 
1039
        if not self.repository.has_same_location(source.repository):
 
1040
            try:
 
1041
                tags_to_fetch = set(source.tags.get_reverse_tag_dict())
 
1042
            except errors.TagsNotSupported:
 
1043
                tags_to_fetch = set()
 
1044
            fetch_spec = _mod_graph.NotInOtherForRevs(self.repository,
 
1045
                source.repository, [revid],
 
1046
                if_present_ids=tags_to_fetch).execute()
 
1047
            self.repository.fetch(source.repository, fetch_spec=fetch_spec)
 
1048
        self.set_last_revision_info(revno, revid)
 
1049
 
1034
1050
    def revision_id_to_revno(self, revision_id):
1035
1051
        """Given a revision id, return its revno"""
1036
1052
        if _mod_revision.is_null(revision_id):
1257
1273
        return result
1258
1274
 
1259
1275
    @needs_read_lock
1260
 
    def sprout(self, to_bzrdir, revision_id=None, repository_policy=None):
 
1276
    def sprout(self, to_bzrdir, revision_id=None, repository_policy=None,
 
1277
            repository=None):
1261
1278
        """Create a new line of development from the branch, into to_bzrdir.
1262
1279
 
1263
1280
        to_bzrdir controls the branch format.
1268
1285
        if (repository_policy is not None and
1269
1286
            repository_policy.requires_stacking()):
1270
1287
            to_bzrdir._format.require_stacking(_skip_repo=True)
1271
 
        result = to_bzrdir.create_branch()
 
1288
        result = to_bzrdir.create_branch(repository=repository)
1272
1289
        result.lock_write()
1273
1290
        try:
1274
1291
            if repository_policy is not None:
1362
1379
        """Return the most suitable metadir for a checkout of this branch.
1363
1380
        Weaves are used if this branch's repository uses weaves.
1364
1381
        """
1365
 
        if isinstance(self.bzrdir, bzrdir.BzrDirPreSplitOut):
1366
 
            from bzrlib.repofmt import weaverepo
1367
 
            format = bzrdir.BzrDirMetaFormat1()
1368
 
            format.repository_format = weaverepo.RepositoryFormat7()
1369
 
        else:
1370
 
            format = self.repository.bzrdir.checkout_metadir()
1371
 
            format.set_branch_format(self._format)
 
1382
        format = self.repository.bzrdir.checkout_metadir()
 
1383
        format.set_branch_format(self._format)
1372
1384
        return format
1373
1385
 
1374
1386
    def create_clone_on_transport(self, to_transport, revision_id=None,
1514
1526
        else:
1515
1527
            raise AssertionError("invalid heads: %r" % (heads,))
1516
1528
 
1517
 
 
1518
 
class BranchFormat(object):
 
1529
    def heads_to_fetch(self):
 
1530
        """Return the heads that must and that should be fetched to copy this
 
1531
        branch into another repo.
 
1532
 
 
1533
        :returns: a 2-tuple of (must_fetch, if_present_fetch).  must_fetch is a
 
1534
            set of heads that must be fetched.  if_present_fetch is a set of
 
1535
            heads that must be fetched if present, but no error is necessary if
 
1536
            they are not present.
 
1537
        """
 
1538
        # For bzr native formats must_fetch is just the tip, and if_present_fetch
 
1539
        # are the tags.
 
1540
        must_fetch = set([self.last_revision()])
 
1541
        try:
 
1542
            if_present_fetch = set(self.tags.get_reverse_tag_dict())
 
1543
        except errors.TagsNotSupported:
 
1544
            if_present_fetch = set()
 
1545
        must_fetch.discard(_mod_revision.NULL_REVISION)
 
1546
        if_present_fetch.discard(_mod_revision.NULL_REVISION)
 
1547
        return must_fetch, if_present_fetch
 
1548
 
 
1549
 
 
1550
class BranchFormat(controldir.ControlComponentFormat):
1519
1551
    """An encapsulation of the initialization and open routines for a format.
1520
1552
 
1521
1553
    Formats provide three things:
1533
1565
    object will be created every time regardless.
1534
1566
    """
1535
1567
 
1536
 
    _default_format = None
1537
 
    """The default format used for new branches."""
1538
 
 
1539
 
    _formats = {}
1540
 
    """The known formats."""
1541
 
 
1542
1568
    can_set_append_revisions_only = True
1543
1569
 
1544
1570
    def __eq__(self, other):
1553
1579
        try:
1554
1580
            transport = a_bzrdir.get_branch_transport(None, name=name)
1555
1581
            format_string = transport.get_bytes("format")
1556
 
            format = klass._formats[format_string]
1557
 
            if isinstance(format, MetaDirBranchFormatFactory):
1558
 
                return format()
1559
 
            return format
 
1582
            return format_registry.get(format_string)
1560
1583
        except errors.NoSuchFile:
1561
1584
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
1562
1585
        except KeyError:
1563
1586
            raise errors.UnknownFormatError(format=format_string, kind='branch')
1564
1587
 
1565
1588
    @classmethod
 
1589
    @deprecated_method(deprecated_in((2, 4, 0)))
1566
1590
    def get_default_format(klass):
1567
1591
        """Return the current default format."""
1568
 
        return klass._default_format
 
1592
        return format_registry.get_default()
1569
1593
 
1570
1594
    @classmethod
 
1595
    @deprecated_method(deprecated_in((2, 4, 0)))
1571
1596
    def get_formats(klass):
1572
1597
        """Get all the known formats.
1573
1598
 
1574
1599
        Warning: This triggers a load of all lazy registered formats: do not
1575
1600
        use except when that is desireed.
1576
1601
        """
1577
 
        result = []
1578
 
        for fmt in klass._formats.values():
1579
 
            if isinstance(fmt, MetaDirBranchFormatFactory):
1580
 
                fmt = fmt()
1581
 
            result.append(fmt)
1582
 
        return result
 
1602
        return format_registry._get_all()
1583
1603
 
1584
1604
    def get_reference(self, a_bzrdir, name=None):
1585
1605
        """Get the target reference of the branch in a_bzrdir.
1624
1644
        for hook in hooks:
1625
1645
            hook(params)
1626
1646
 
1627
 
    def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1628
 
                           lock_type='metadir', set_format=True):
1629
 
        """Initialize a branch in a bzrdir, with specified files
1630
 
 
1631
 
        :param a_bzrdir: The bzrdir to initialize the branch in
1632
 
        :param utf8_files: The files to create as a list of
1633
 
            (filename, content) tuples
1634
 
        :param name: Name of colocated branch to create, if any
1635
 
        :param set_format: If True, set the format with
1636
 
            self.get_format_string.  (BzrBranch4 has its format set
1637
 
            elsewhere)
1638
 
        :return: a branch in this format
1639
 
        """
1640
 
        mutter('creating branch %r in %s', self, a_bzrdir.user_url)
1641
 
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1642
 
        lock_map = {
1643
 
            'metadir': ('lock', lockdir.LockDir),
1644
 
            'branch4': ('branch-lock', lockable_files.TransportLock),
1645
 
        }
1646
 
        lock_name, lock_class = lock_map[lock_type]
1647
 
        control_files = lockable_files.LockableFiles(branch_transport,
1648
 
            lock_name, lock_class)
1649
 
        control_files.create_lock()
1650
 
        try:
1651
 
            control_files.lock_write()
1652
 
        except errors.LockContention:
1653
 
            if lock_type != 'branch4':
1654
 
                raise
1655
 
            lock_taken = False
1656
 
        else:
1657
 
            lock_taken = True
1658
 
        if set_format:
1659
 
            utf8_files += [('format', self.get_format_string())]
1660
 
        try:
1661
 
            for (filename, content) in utf8_files:
1662
 
                branch_transport.put_bytes(
1663
 
                    filename, content,
1664
 
                    mode=a_bzrdir._get_file_mode())
1665
 
        finally:
1666
 
            if lock_taken:
1667
 
                control_files.unlock()
1668
 
        branch = self.open(a_bzrdir, name, _found=True)
1669
 
        self._run_post_branch_init_hooks(a_bzrdir, name, branch)
1670
 
        return branch
1671
 
 
1672
 
    def initialize(self, a_bzrdir, name=None):
 
1647
    def initialize(self, a_bzrdir, name=None, repository=None):
1673
1648
        """Create a branch of this format in a_bzrdir.
1674
1649
        
1675
1650
        :param name: Name of the colocated branch to create.
1709
1684
        """
1710
1685
        raise NotImplementedError(self.network_name)
1711
1686
 
1712
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
 
1687
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
 
1688
            found_repository=None):
1713
1689
        """Return the branch object for a_bzrdir
1714
1690
 
1715
1691
        :param a_bzrdir: A BzrDir that contains a branch.
1722
1698
        raise NotImplementedError(self.open)
1723
1699
 
1724
1700
    @classmethod
 
1701
    @deprecated_method(deprecated_in((2, 4, 0)))
1725
1702
    def register_format(klass, format):
1726
1703
        """Register a metadir format.
1727
 
        
 
1704
 
1728
1705
        See MetaDirBranchFormatFactory for the ability to register a format
1729
1706
        without loading the code the format needs until it is actually used.
1730
1707
        """
1731
 
        klass._formats[format.get_format_string()] = format
1732
 
        # Metadir formats have a network name of their format string, and get
1733
 
        # registered as factories.
1734
 
        if isinstance(format, MetaDirBranchFormatFactory):
1735
 
            network_format_registry.register(format.get_format_string(), format)
1736
 
        else:
1737
 
            network_format_registry.register(format.get_format_string(),
1738
 
                format.__class__)
 
1708
        format_registry.register(format)
1739
1709
 
1740
1710
    @classmethod
 
1711
    @deprecated_method(deprecated_in((2, 4, 0)))
1741
1712
    def set_default_format(klass, format):
1742
 
        klass._default_format = format
 
1713
        format_registry.set_default(format)
1743
1714
 
1744
1715
    def supports_set_append_revisions_only(self):
1745
1716
        """True if this format supports set_append_revisions_only."""
1749
1720
        """True if this format records a stacked-on branch."""
1750
1721
        return False
1751
1722
 
 
1723
    def supports_leaving_lock(self):
 
1724
        """True if this format supports leaving locks in place."""
 
1725
        return False # by default
 
1726
 
1752
1727
    @classmethod
 
1728
    @deprecated_method(deprecated_in((2, 4, 0)))
1753
1729
    def unregister_format(klass, format):
1754
 
        del klass._formats[format.get_format_string()]
 
1730
        format_registry.remove(format)
1755
1731
 
1756
1732
    def __str__(self):
1757
1733
        return self.get_format_description().rstrip()
1802
1778
        These are all empty initially, because by default nothing should get
1803
1779
        notified.
1804
1780
        """
1805
 
        Hooks.__init__(self)
1806
 
        self.create_hook(HookPoint('set_rh',
 
1781
        Hooks.__init__(self, "bzrlib.branch", "Branch.hooks")
 
1782
        self.add_hook('set_rh',
1807
1783
            "Invoked whenever the revision history has been set via "
1808
1784
            "set_revision_history. The api signature is (branch, "
1809
1785
            "revision_history), and the branch will be write-locked. "
1810
1786
            "The set_rh hook can be expensive for bzr to trigger, a better "
1811
 
            "hook to use is Branch.post_change_branch_tip.", (0, 15), None))
1812
 
        self.create_hook(HookPoint('open',
 
1787
            "hook to use is Branch.post_change_branch_tip.", (0, 15))
 
1788
        self.add_hook('open',
1813
1789
            "Called with the Branch object that has been opened after a "
1814
 
            "branch is opened.", (1, 8), None))
1815
 
        self.create_hook(HookPoint('post_push',
 
1790
            "branch is opened.", (1, 8))
 
1791
        self.add_hook('post_push',
1816
1792
            "Called after a push operation completes. post_push is called "
1817
1793
            "with a bzrlib.branch.BranchPushResult object and only runs in the "
1818
 
            "bzr client.", (0, 15), None))
1819
 
        self.create_hook(HookPoint('post_pull',
 
1794
            "bzr client.", (0, 15))
 
1795
        self.add_hook('post_pull',
1820
1796
            "Called after a pull operation completes. post_pull is called "
1821
1797
            "with a bzrlib.branch.PullResult object and only runs in the "
1822
 
            "bzr client.", (0, 15), None))
1823
 
        self.create_hook(HookPoint('pre_commit',
 
1798
            "bzr client.", (0, 15))
 
1799
        self.add_hook('pre_commit',
1824
1800
            "Called after a commit is calculated but before it is "
1825
1801
            "completed. pre_commit is called with (local, master, old_revno, "
1826
1802
            "old_revid, future_revno, future_revid, tree_delta, future_tree"
1829
1805
            "basis revision. hooks MUST NOT modify this delta. "
1830
1806
            " future_tree is an in-memory tree obtained from "
1831
1807
            "CommitBuilder.revision_tree() and hooks MUST NOT modify this "
1832
 
            "tree.", (0,91), None))
1833
 
        self.create_hook(HookPoint('post_commit',
 
1808
            "tree.", (0,91))
 
1809
        self.add_hook('post_commit',
1834
1810
            "Called in the bzr client after a commit has completed. "
1835
1811
            "post_commit is called with (local, master, old_revno, old_revid, "
1836
1812
            "new_revno, new_revid). old_revid is NULL_REVISION for the first "
1837
 
            "commit to a branch.", (0, 15), None))
1838
 
        self.create_hook(HookPoint('post_uncommit',
 
1813
            "commit to a branch.", (0, 15))
 
1814
        self.add_hook('post_uncommit',
1839
1815
            "Called in the bzr client after an uncommit completes. "
1840
1816
            "post_uncommit is called with (local, master, old_revno, "
1841
1817
            "old_revid, new_revno, new_revid) where local is the local branch "
1842
1818
            "or None, master is the target branch, and an empty branch "
1843
 
            "receives new_revno of 0, new_revid of None.", (0, 15), None))
1844
 
        self.create_hook(HookPoint('pre_change_branch_tip',
 
1819
            "receives new_revno of 0, new_revid of None.", (0, 15))
 
1820
        self.add_hook('pre_change_branch_tip',
1845
1821
            "Called in bzr client and server before a change to the tip of a "
1846
1822
            "branch is made. pre_change_branch_tip is called with a "
1847
1823
            "bzrlib.branch.ChangeBranchTipParams. Note that push, pull, "
1848
 
            "commit, uncommit will all trigger this hook.", (1, 6), None))
1849
 
        self.create_hook(HookPoint('post_change_branch_tip',
 
1824
            "commit, uncommit will all trigger this hook.", (1, 6))
 
1825
        self.add_hook('post_change_branch_tip',
1850
1826
            "Called in bzr client and server after a change to the tip of a "
1851
1827
            "branch is made. post_change_branch_tip is called with a "
1852
1828
            "bzrlib.branch.ChangeBranchTipParams. Note that push, pull, "
1853
 
            "commit, uncommit will all trigger this hook.", (1, 4), None))
1854
 
        self.create_hook(HookPoint('transform_fallback_location',
 
1829
            "commit, uncommit will all trigger this hook.", (1, 4))
 
1830
        self.add_hook('transform_fallback_location',
1855
1831
            "Called when a stacked branch is activating its fallback "
1856
1832
            "locations. transform_fallback_location is called with (branch, "
1857
1833
            "url), and should return a new url. Returning the same url "
1862
1838
            "fallback locations have not been activated. When there are "
1863
1839
            "multiple hooks installed for transform_fallback_location, "
1864
1840
            "all are called with the url returned from the previous hook."
1865
 
            "The order is however undefined.", (1, 9), None))
1866
 
        self.create_hook(HookPoint('automatic_tag_name',
 
1841
            "The order is however undefined.", (1, 9))
 
1842
        self.add_hook('automatic_tag_name',
1867
1843
            "Called to determine an automatic tag name for a revision. "
1868
1844
            "automatic_tag_name is called with (branch, revision_id) and "
1869
1845
            "should return a tag name or None if no tag name could be "
1870
1846
            "determined. The first non-None tag name returned will be used.",
1871
 
            (2, 2), None))
1872
 
        self.create_hook(HookPoint('post_branch_init',
 
1847
            (2, 2))
 
1848
        self.add_hook('post_branch_init',
1873
1849
            "Called after new branch initialization completes. "
1874
1850
            "post_branch_init is called with a "
1875
1851
            "bzrlib.branch.BranchInitHookParams. "
1876
1852
            "Note that init, branch and checkout (both heavyweight and "
1877
 
            "lightweight) will all trigger this hook.", (2, 2), None))
1878
 
        self.create_hook(HookPoint('post_switch',
 
1853
            "lightweight) will all trigger this hook.", (2, 2))
 
1854
        self.add_hook('post_switch',
1879
1855
            "Called after a checkout switches branch. "
1880
1856
            "post_switch is called with a "
1881
 
            "bzrlib.branch.SwitchHookParams.", (2, 2), None))
 
1857
            "bzrlib.branch.SwitchHookParams.", (2, 2))
1882
1858
 
1883
1859
 
1884
1860
 
1997
1973
            self.revision_id)
1998
1974
 
1999
1975
 
2000
 
class BzrBranchFormat4(BranchFormat):
2001
 
    """Bzr branch format 4.
2002
 
 
2003
 
    This format has:
2004
 
     - a revision-history file.
2005
 
     - a branch-lock lock file [ to be shared with the bzrdir ]
2006
 
    """
2007
 
 
2008
 
    def get_format_description(self):
2009
 
        """See BranchFormat.get_format_description()."""
2010
 
        return "Branch format 4"
2011
 
 
2012
 
    def initialize(self, a_bzrdir, name=None):
2013
 
        """Create a branch of this format in a_bzrdir."""
2014
 
        utf8_files = [('revision-history', ''),
2015
 
                      ('branch-name', ''),
2016
 
                      ]
2017
 
        return self._initialize_helper(a_bzrdir, utf8_files, name=name,
2018
 
                                       lock_type='branch4', set_format=False)
2019
 
 
2020
 
    def __init__(self):
2021
 
        super(BzrBranchFormat4, self).__init__()
2022
 
        self._matchingbzrdir = bzrdir.BzrDirFormat6()
2023
 
 
2024
 
    def network_name(self):
2025
 
        """The network name for this format is the control dirs disk label."""
2026
 
        return self._matchingbzrdir.get_format_string()
2027
 
 
2028
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
2029
 
        """See BranchFormat.open()."""
2030
 
        if not _found:
2031
 
            # we are being called directly and must probe.
2032
 
            raise NotImplementedError
2033
 
        return BzrBranch(_format=self,
2034
 
                         _control_files=a_bzrdir._control_files,
2035
 
                         a_bzrdir=a_bzrdir,
2036
 
                         name=name,
2037
 
                         _repository=a_bzrdir.open_repository())
2038
 
 
2039
 
    def __str__(self):
2040
 
        return "Bazaar-NG branch format 4"
2041
 
 
2042
 
 
2043
1976
class BranchFormatMetadir(BranchFormat):
2044
1977
    """Common logic for meta-dir based branch formats."""
2045
1978
 
2047
1980
        """What class to instantiate on open calls."""
2048
1981
        raise NotImplementedError(self._branch_class)
2049
1982
 
 
1983
    def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
 
1984
                           repository=None):
 
1985
        """Initialize a branch in a bzrdir, with specified files
 
1986
 
 
1987
        :param a_bzrdir: The bzrdir to initialize the branch in
 
1988
        :param utf8_files: The files to create as a list of
 
1989
            (filename, content) tuples
 
1990
        :param name: Name of colocated branch to create, if any
 
1991
        :return: a branch in this format
 
1992
        """
 
1993
        mutter('creating branch %r in %s', self, a_bzrdir.user_url)
 
1994
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
 
1995
        control_files = lockable_files.LockableFiles(branch_transport,
 
1996
            'lock', lockdir.LockDir)
 
1997
        control_files.create_lock()
 
1998
        control_files.lock_write()
 
1999
        try:
 
2000
            utf8_files += [('format', self.get_format_string())]
 
2001
            for (filename, content) in utf8_files:
 
2002
                branch_transport.put_bytes(
 
2003
                    filename, content,
 
2004
                    mode=a_bzrdir._get_file_mode())
 
2005
        finally:
 
2006
            control_files.unlock()
 
2007
        branch = self.open(a_bzrdir, name, _found=True,
 
2008
                found_repository=repository)
 
2009
        self._run_post_branch_init_hooks(a_bzrdir, name, branch)
 
2010
        return branch
 
2011
 
2050
2012
    def network_name(self):
2051
2013
        """A simple byte string uniquely identifying this format for RPC calls.
2052
2014
 
2054
2016
        """
2055
2017
        return self.get_format_string()
2056
2018
 
2057
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
 
2019
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False,
 
2020
            found_repository=None):
2058
2021
        """See BranchFormat.open()."""
2059
2022
        if not _found:
2060
2023
            format = BranchFormat.find_format(a_bzrdir, name=name)
2065
2028
        try:
2066
2029
            control_files = lockable_files.LockableFiles(transport, 'lock',
2067
2030
                                                         lockdir.LockDir)
 
2031
            if found_repository is None:
 
2032
                found_repository = a_bzrdir.find_repository()
2068
2033
            return self._branch_class()(_format=self,
2069
2034
                              _control_files=control_files,
2070
2035
                              name=name,
2071
2036
                              a_bzrdir=a_bzrdir,
2072
 
                              _repository=a_bzrdir.find_repository(),
 
2037
                              _repository=found_repository,
2073
2038
                              ignore_fallbacks=ignore_fallbacks)
2074
2039
        except errors.NoSuchFile:
2075
2040
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
2082
2047
    def supports_tags(self):
2083
2048
        return True
2084
2049
 
 
2050
    def supports_leaving_lock(self):
 
2051
        return True
 
2052
 
2085
2053
 
2086
2054
class BzrBranchFormat5(BranchFormatMetadir):
2087
2055
    """Bzr branch format 5.
2107
2075
        """See BranchFormat.get_format_description()."""
2108
2076
        return "Branch format 5"
2109
2077
 
2110
 
    def initialize(self, a_bzrdir, name=None):
 
2078
    def initialize(self, a_bzrdir, name=None, repository=None):
2111
2079
        """Create a branch of this format in a_bzrdir."""
2112
2080
        utf8_files = [('revision-history', ''),
2113
2081
                      ('branch-name', ''),
2114
2082
                      ]
2115
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
2083
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2116
2084
 
2117
2085
    def supports_tags(self):
2118
2086
        return False
2140
2108
        """See BranchFormat.get_format_description()."""
2141
2109
        return "Branch format 6"
2142
2110
 
2143
 
    def initialize(self, a_bzrdir, name=None):
 
2111
    def initialize(self, a_bzrdir, name=None, repository=None):
2144
2112
        """Create a branch of this format in a_bzrdir."""
2145
2113
        utf8_files = [('last-revision', '0 null:\n'),
2146
2114
                      ('branch.conf', ''),
2147
2115
                      ('tags', ''),
2148
2116
                      ]
2149
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
2117
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2150
2118
 
2151
2119
    def make_tags(self, branch):
2152
2120
        """See bzrlib.branch.BranchFormat.make_tags()."""
2170
2138
        """See BranchFormat.get_format_description()."""
2171
2139
        return "Branch format 8"
2172
2140
 
2173
 
    def initialize(self, a_bzrdir, name=None):
 
2141
    def initialize(self, a_bzrdir, name=None, repository=None):
2174
2142
        """Create a branch of this format in a_bzrdir."""
2175
2143
        utf8_files = [('last-revision', '0 null:\n'),
2176
2144
                      ('branch.conf', ''),
2177
2145
                      ('tags', ''),
2178
2146
                      ('references', '')
2179
2147
                      ]
2180
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
2181
 
 
2182
 
    def __init__(self):
2183
 
        super(BzrBranchFormat8, self).__init__()
2184
 
        self._matchingbzrdir.repository_format = \
2185
 
            RepositoryFormatKnitPack5RichRoot()
 
2148
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2186
2149
 
2187
2150
    def make_tags(self, branch):
2188
2151
        """See bzrlib.branch.BranchFormat.make_tags()."""
2197
2160
    supports_reference_locations = True
2198
2161
 
2199
2162
 
2200
 
class BzrBranchFormat7(BzrBranchFormat8):
 
2163
class BzrBranchFormat7(BranchFormatMetadir):
2201
2164
    """Branch format with last-revision, tags, and a stacked location pointer.
2202
2165
 
2203
2166
    The stacked location pointer is passed down to the repository and requires
2206
2169
    This format was introduced in bzr 1.6.
2207
2170
    """
2208
2171
 
2209
 
    def initialize(self, a_bzrdir, name=None):
 
2172
    def initialize(self, a_bzrdir, name=None, repository=None):
2210
2173
        """Create a branch of this format in a_bzrdir."""
2211
2174
        utf8_files = [('last-revision', '0 null:\n'),
2212
2175
                      ('branch.conf', ''),
2213
2176
                      ('tags', ''),
2214
2177
                      ]
2215
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
2178
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2216
2179
 
2217
2180
    def _branch_class(self):
2218
2181
        return BzrBranch7
2228
2191
    def supports_set_append_revisions_only(self):
2229
2192
        return True
2230
2193
 
 
2194
    def supports_stacking(self):
 
2195
        return True
 
2196
 
 
2197
    def make_tags(self, branch):
 
2198
        """See bzrlib.branch.BranchFormat.make_tags()."""
 
2199
        return BasicTags(branch)
 
2200
 
2231
2201
    supports_reference_locations = False
2232
2202
 
2233
2203
 
2260
2230
        transport = a_bzrdir.get_branch_transport(None, name=name)
2261
2231
        location = transport.put_bytes('location', to_branch.base)
2262
2232
 
2263
 
    def initialize(self, a_bzrdir, name=None, target_branch=None):
 
2233
    def initialize(self, a_bzrdir, name=None, target_branch=None,
 
2234
            repository=None):
2264
2235
        """Create a branch of this format in a_bzrdir."""
2265
2236
        if target_branch is None:
2266
2237
            # this format does not implement branch itself, thus the implicit
2294
2265
        return clone
2295
2266
 
2296
2267
    def open(self, a_bzrdir, name=None, _found=False, location=None,
2297
 
             possible_transports=None, ignore_fallbacks=False):
 
2268
             possible_transports=None, ignore_fallbacks=False,
 
2269
             found_repository=None):
2298
2270
        """Return the branch that the branch reference in a_bzrdir points at.
2299
2271
 
2300
2272
        :param a_bzrdir: A BzrDir that contains a branch.
2331
2303
        return result
2332
2304
 
2333
2305
 
 
2306
class BranchFormatRegistry(controldir.ControlComponentFormatRegistry):
 
2307
    """Branch format registry."""
 
2308
 
 
2309
    def __init__(self, other_registry=None):
 
2310
        super(BranchFormatRegistry, self).__init__(other_registry)
 
2311
        self._default_format = None
 
2312
 
 
2313
    def set_default(self, format):
 
2314
        self._default_format = format
 
2315
 
 
2316
    def get_default(self):
 
2317
        return self._default_format
 
2318
 
 
2319
 
2334
2320
network_format_registry = registry.FormatRegistry()
2335
2321
"""Registry of formats indexed by their network name.
2336
2322
 
2339
2325
BranchFormat.network_name() for more detail.
2340
2326
"""
2341
2327
 
 
2328
format_registry = BranchFormatRegistry(network_format_registry)
 
2329
 
2342
2330
 
2343
2331
# formats which have no format string are not discoverable
2344
2332
# and not independently creatable, so are not registered.
2346
2334
__format6 = BzrBranchFormat6()
2347
2335
__format7 = BzrBranchFormat7()
2348
2336
__format8 = BzrBranchFormat8()
2349
 
BranchFormat.register_format(__format5)
2350
 
BranchFormat.register_format(BranchReferenceFormat())
2351
 
BranchFormat.register_format(__format6)
2352
 
BranchFormat.register_format(__format7)
2353
 
BranchFormat.register_format(__format8)
2354
 
BranchFormat.set_default_format(__format7)
2355
 
_legacy_formats = [BzrBranchFormat4(),
2356
 
    ]
2357
 
network_format_registry.register(
2358
 
    _legacy_formats[0].network_name(), _legacy_formats[0].__class__)
 
2337
format_registry.register(__format5)
 
2338
format_registry.register(BranchReferenceFormat())
 
2339
format_registry.register(__format6)
 
2340
format_registry.register(__format7)
 
2341
format_registry.register(__format8)
 
2342
format_registry.set_default(__format7)
2359
2343
 
2360
2344
 
2361
2345
class BranchWriteLockResult(LogicalLockResult):
2637
2621
        result.target_branch = target
2638
2622
        result.old_revno, result.old_revid = target.last_revision_info()
2639
2623
        self.update_references(target)
2640
 
        if result.old_revid != self.last_revision():
 
2624
        if result.old_revid != stop_revision:
2641
2625
            # We assume that during 'push' this repository is closer than
2642
2626
            # the target.
2643
2627
            graph = self.repository.get_graph(target.repository)
2644
2628
            target.update_revisions(self, stop_revision,
2645
2629
                overwrite=overwrite, graph=graph)
2646
2630
        if self._push_should_merge_tags():
2647
 
            result.tag_conflicts = self.tags.merge_to(target.tags,
2648
 
                overwrite)
 
2631
            result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
2649
2632
        result.new_revno, result.new_revid = target.last_revision_info()
2650
2633
        return result
2651
2634
 
2683
2666
        """Return the branch we are bound to.
2684
2667
 
2685
2668
        :return: Either a Branch, or None
2686
 
 
2687
 
        This could memoise the branch, but if thats done
2688
 
        it must be revalidated on each new lock.
2689
 
        So for now we just don't memoise it.
2690
 
        # RBC 20060304 review this decision.
2691
2669
        """
 
2670
        if self._master_branch_cache is None:
 
2671
            self._master_branch_cache = self._get_master_branch(
 
2672
                possible_transports)
 
2673
        return self._master_branch_cache
 
2674
 
 
2675
    def _get_master_branch(self, possible_transports):
2692
2676
        bound_loc = self.get_bound_location()
2693
2677
        if not bound_loc:
2694
2678
            return None
2705
2689
 
2706
2690
        :param location: URL to the target branch
2707
2691
        """
 
2692
        self._master_branch_cache = None
2708
2693
        if location:
2709
2694
            self._transport.put_bytes('bound', location+'\n',
2710
2695
                mode=self.bzrdir._get_file_mode())
2962
2947
 
2963
2948
    def set_bound_location(self, location):
2964
2949
        """See Branch.set_push_location."""
 
2950
        self._master_branch_cache = None
2965
2951
        result = None
2966
2952
        config = self.get_config()
2967
2953
        if location is None:
3044
3030
        try:
3045
3031
            index = self._partial_revision_history_cache.index(revision_id)
3046
3032
        except ValueError:
3047
 
            self._extend_partial_history(stop_revision=revision_id)
 
3033
            try:
 
3034
                self._extend_partial_history(stop_revision=revision_id)
 
3035
            except errors.RevisionNotPresent, e:
 
3036
                raise errors.GhostRevisionsHaveNoRevno(revision_id, e.revision_id)
3048
3037
            index = len(self._partial_revision_history_cache) - 1
3049
3038
            if self._partial_revision_history_cache[index] != revision_id:
3050
3039
                raise errors.NoSuchRevision(self, revision_id)
3298
3287
 
3299
3288
    @needs_write_lock
3300
3289
    def update_revisions(self, stop_revision=None, overwrite=False,
3301
 
                         graph=None):
 
3290
                         graph=None, fetch_tags=True):
3302
3291
        """Pull in new perfect-fit revisions.
3303
3292
 
3304
3293
        :param stop_revision: Updated until the given revision
3306
3295
            to see if it is a proper descendant.
3307
3296
        :param graph: A Graph object that can be used to query history
3308
3297
            information. This can be None.
 
3298
        :param fetch_tags: Flag that specifies if tags from source should be
 
3299
            fetched too.
3309
3300
        :return: None
3310
3301
        """
3311
3302
        raise NotImplementedError(self.update_revisions)
3328
3319
        """
3329
3320
        raise NotImplementedError(self.copy_content_into)
3330
3321
 
 
3322
    @needs_write_lock
 
3323
    def fetch(self, stop_revision=None, fetch_spec=None):
 
3324
        """Fetch revisions.
 
3325
 
 
3326
        :param stop_revision: Last revision to fetch
 
3327
        :param fetch_spec: Fetch spec.
 
3328
        """
 
3329
        raise NotImplementedError(self.fetch)
 
3330
 
3331
3331
 
3332
3332
class GenericInterBranch(InterBranch):
3333
3333
    """InterBranch implementation that uses public Branch functions."""
3339
3339
 
3340
3340
    @classmethod
3341
3341
    def _get_branch_formats_to_test(klass):
3342
 
        return [(BranchFormat._default_format, BranchFormat._default_format)]
 
3342
        return [(format_registry.get_default(), format_registry.get_default())]
3343
3343
 
3344
3344
    @classmethod
3345
3345
    def unwrap_format(klass, format):
3346
3346
        if isinstance(format, remote.RemoteBranchFormat):
3347
3347
            format._ensure_real()
3348
3348
            return format._custom_format
3349
 
        return format                                                                                                  
 
3349
        return format
3350
3350
 
3351
3351
    @needs_write_lock
3352
3352
    def copy_content_into(self, revision_id=None):
3368
3368
            self.source.tags.merge_to(self.target.tags)
3369
3369
 
3370
3370
    @needs_write_lock
 
3371
    def fetch(self, stop_revision=None, fetch_spec=None):
 
3372
        if fetch_spec is not None and stop_revision is not None:
 
3373
            raise AssertionError(
 
3374
                "fetch_spec and last_revision are mutually exclusive.")
 
3375
        if self.target.base == self.source.base:
 
3376
            return (0, [])
 
3377
        self.source.lock_read()
 
3378
        try:
 
3379
            if stop_revision is None and fetch_spec is None:
 
3380
                stop_revision = self.source.last_revision()
 
3381
                stop_revision = _mod_revision.ensure_null(stop_revision)
 
3382
            return self.target.repository.fetch(self.source.repository,
 
3383
                revision_id=stop_revision, fetch_spec=fetch_spec)
 
3384
        finally:
 
3385
            self.source.unlock()
 
3386
 
 
3387
    @needs_write_lock
3371
3388
    def update_revisions(self, stop_revision=None, overwrite=False,
3372
 
        graph=None):
 
3389
        graph=None, fetch_tags=True):
3373
3390
        """See InterBranch.update_revisions()."""
3374
3391
        other_revno, other_last_revision = self.source.last_revision_info()
3375
3392
        stop_revno = None # unknown
3387
3404
        # case of having something to pull, and so that the check for
3388
3405
        # already merged can operate on the just fetched graph, which will
3389
3406
        # be cached in memory.
3390
 
        self.target.fetch(self.source, stop_revision)
 
3407
        if fetch_tags:
 
3408
            fetch_spec_factory = fetch.FetchSpecFactory()
 
3409
            fetch_spec_factory.source_branch = self.source
 
3410
            fetch_spec_factory.source_branch_stop_revision_id = stop_revision
 
3411
            fetch_spec_factory.source_repo = self.source.repository
 
3412
            fetch_spec_factory.target_repo = self.target.repository
 
3413
            fetch_spec_factory.target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
 
3414
            fetch_spec = fetch_spec_factory.make_fetch_spec()
 
3415
        else:
 
3416
            fetch_spec = _mod_graph.NotInOtherForRevs(self.target.repository,
 
3417
                self.source.repository, revision_ids=[stop_revision]).execute()
 
3418
        self.target.fetch(self.source, fetch_spec=fetch_spec)
3391
3419
        # Check to see if one is an ancestor of the other
3392
3420
        if not overwrite:
3393
3421
            if graph is None:
3421
3449
        if local and not bound_location:
3422
3450
            raise errors.LocalRequiresBoundBranch()
3423
3451
        master_branch = None
3424
 
        if not local and bound_location and self.source.user_url != bound_location:
 
3452
        source_is_master = (self.source.user_url == bound_location)
 
3453
        if not local and bound_location and not source_is_master:
3425
3454
            # not pulling from master, so we need to update master.
3426
3455
            master_branch = self.target.get_master_branch(possible_transports)
3427
3456
            master_branch.lock_write()
3433
3462
            return self._pull(overwrite,
3434
3463
                stop_revision, _hook_master=master_branch,
3435
3464
                run_hooks=run_hooks,
3436
 
                _override_hook_target=_override_hook_target)
 
3465
                _override_hook_target=_override_hook_target,
 
3466
                merge_tags_to_master=not source_is_master)
3437
3467
        finally:
3438
3468
            if master_branch:
3439
3469
                master_branch.unlock()
3506
3536
 
3507
3537
    def _pull(self, overwrite=False, stop_revision=None,
3508
3538
             possible_transports=None, _hook_master=None, run_hooks=True,
3509
 
             _override_hook_target=None, local=False):
 
3539
             _override_hook_target=None, local=False,
 
3540
             merge_tags_to_master=True):
3510
3541
        """See Branch.pull.
3511
3542
 
3512
3543
        This function is the core worker, used by GenericInterBranch.pull to
3517
3548
        :param run_hooks: Private parameter - if false, this branch
3518
3549
            is being called because it's the master of the primary branch,
3519
3550
            so it should not run its hooks.
 
3551
            is being called because it's the master of the primary branch,
 
3552
            so it should not run its hooks.
3520
3553
        :param _override_hook_target: Private parameter - set the branch to be
3521
3554
            supplied as the target_branch to pull hooks.
3522
3555
        :param local: Only update the local branch, and not the bound branch.
3547
3580
            # so a tags implementation that versions tags can only 
3548
3581
            # pull in the most recent changes. -- JRV20090506
3549
3582
            result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3550
 
                overwrite)
 
3583
                overwrite, ignore_master=not merge_tags_to_master)
3551
3584
            result.new_revno, result.new_revid = self.target.last_revision_info()
3552
3585
            if _hook_master:
3553
3586
                result.master_branch = _hook_master