43
44
from bzrlib.config import BranchConfig, TransportConfig
44
from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5RichRoot
45
45
from bzrlib.tag import (
51
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
52
from bzrlib.hooks import HookPoint, Hooks
54
from bzrlib.decorators import (
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
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)
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)
649
669
raise errors.UnsupportedOperation(self.get_reference_info, self)
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.
655
675
:param from_branch: Where to copy from.
656
676
:param last_revision: What revision to stop at (None for at the end
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
661
if self.base == from_branch.base:
664
symbol_versioning.warn(
665
symbol_versioning.deprecated_in((1, 14, 0))
666
% "pb parameter to fetch()")
667
from_branch.lock_read()
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,
684
return InterBranch.get(from_branch, self).fetch(last_revision,
678
687
def get_bound_location(self):
679
688
"""Return the URL of the branch we are bound to.
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.
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(),
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)
870
881
old_repository.unlock()
877
888
:seealso: Branch._get_tags_bytes.
879
return _run_with_write_locked_target(self, self._transport.put_bytes,
890
return _run_with_write_locked_target(self, self._set_tags_bytes_locked,
893
def _set_tags_bytes_locked(self, bytes):
894
self._tags_bytes = bytes
895
return self._transport.put_bytes('tags', bytes)
882
897
def _cache_revision_history(self, rev_history):
883
898
"""Set the cached revision history to rev_history.
980
997
return (0, _mod_revision.NULL_REVISION)
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.
986
If self and other have not diverged, return a list of the revisions
987
present in other, but missing from self.
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)
998
if stop_revision is None:
999
stop_revision = other_len
1001
if stop_revision > other_len:
1002
raise errors.NoSuchRevision(self, stop_revision)
1003
return other_history[self_len:stop_revision]
1005
999
def update_revisions(self, other, stop_revision=None, overwrite=False,
1000
graph=None, fetch_tags=True):
1007
1001
"""Pull in new perfect-fit revisions.
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
1017
1013
return InterBranch.get(other, self).update_revisions(stop_revision,
1014
overwrite, graph, fetch_tags=fetch_tags)
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.
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.
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)
1028
def import_last_revision_info_and_tags(self, source, revno, revid):
1029
"""Set the last revision info, importing from another repo if necessary.
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.
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
1039
if not self.repository.has_same_location(source.repository):
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)
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):
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.
1365
if isinstance(self.bzrdir, bzrdir.BzrDirPreSplitOut):
1366
from bzrlib.repofmt import weaverepo
1367
format = bzrdir.BzrDirMetaFormat1()
1368
format.repository_format = weaverepo.RepositoryFormat7()
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)
1374
1386
def create_clone_on_transport(self, to_transport, revision_id=None,
1515
1527
raise AssertionError("invalid heads: %r" % (heads,))
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.
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.
1538
# For bzr native formats must_fetch is just the tip, and if_present_fetch
1540
must_fetch = set([self.last_revision()])
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
1550
class BranchFormat(controldir.ControlComponentFormat):
1519
1551
"""An encapsulation of the initialization and open routines for a format.
1521
1553
Formats provide three things:
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):
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')
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()
1595
@deprecated_method(deprecated_in((2, 4, 0)))
1571
1596
def get_formats(klass):
1572
1597
"""Get all the known formats.
1574
1599
Warning: This triggers a load of all lazy registered formats: do not
1575
1600
use except when that is desireed.
1578
for fmt in klass._formats.values():
1579
if isinstance(fmt, MetaDirBranchFormatFactory):
1602
return format_registry._get_all()
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:
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
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
1638
:return: a branch in this format
1640
mutter('creating branch %r in %s', self, a_bzrdir.user_url)
1641
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1643
'metadir': ('lock', lockdir.LockDir),
1644
'branch4': ('branch-lock', lockable_files.TransportLock),
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()
1651
control_files.lock_write()
1652
except errors.LockContention:
1653
if lock_type != 'branch4':
1659
utf8_files += [('format', self.get_format_string())]
1661
for (filename, content) in utf8_files:
1662
branch_transport.put_bytes(
1664
mode=a_bzrdir._get_file_mode())
1667
control_files.unlock()
1668
branch = self.open(a_bzrdir, name, _found=True)
1669
self._run_post_branch_init_hooks(a_bzrdir, name, branch)
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.
1675
1650
:param name: Name of the colocated branch to create.
1710
1685
raise NotImplementedError(self.network_name)
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
1715
1691
:param a_bzrdir: A BzrDir that contains a branch.
1722
1698
raise NotImplementedError(self.open)
1701
@deprecated_method(deprecated_in((2, 4, 0)))
1725
1702
def register_format(klass, format):
1726
1703
"""Register a metadir format.
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.
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)
1737
network_format_registry.register(format.get_format_string(),
1708
format_registry.register(format)
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)
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."""
1723
def supports_leaving_lock(self):
1724
"""True if this format supports leaving locks in place."""
1725
return False # by default
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)
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
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',
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.",
1872
self.create_hook(HookPoint('post_branch_init',
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))
1997
1973
self.revision_id)
2000
class BzrBranchFormat4(BranchFormat):
2001
"""Bzr branch format 4.
2004
- a revision-history file.
2005
- a branch-lock lock file [ to be shared with the bzrdir ]
2008
def get_format_description(self):
2009
"""See BranchFormat.get_format_description()."""
2010
return "Branch format 4"
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', ''),
2017
return self._initialize_helper(a_bzrdir, utf8_files, name=name,
2018
lock_type='branch4', set_format=False)
2021
super(BzrBranchFormat4, self).__init__()
2022
self._matchingbzrdir = bzrdir.BzrDirFormat6()
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()
2028
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
2029
"""See BranchFormat.open()."""
2031
# we are being called directly and must probe.
2032
raise NotImplementedError
2033
return BzrBranch(_format=self,
2034
_control_files=a_bzrdir._control_files,
2037
_repository=a_bzrdir.open_repository())
2040
return "Bazaar-NG branch format 4"
2043
1976
class BranchFormatMetadir(BranchFormat):
2044
1977
"""Common logic for meta-dir based branch formats."""
2047
1980
"""What class to instantiate on open calls."""
2048
1981
raise NotImplementedError(self._branch_class)
1983
def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1985
"""Initialize a branch in a bzrdir, with specified files
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
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()
2000
utf8_files += [('format', self.get_format_string())]
2001
for (filename, content) in utf8_files:
2002
branch_transport.put_bytes(
2004
mode=a_bzrdir._get_file_mode())
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)
2050
2012
def network_name(self):
2051
2013
"""A simple byte string uniquely identifying this format for RPC calls.
2055
2017
return self.get_format_string()
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()."""
2060
2023
format = BranchFormat.find_format(a_bzrdir, name=name)
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,
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)
2107
2075
"""See BranchFormat.get_format_description()."""
2108
2076
return "Branch format 5"
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', ''),
2115
return self._initialize_helper(a_bzrdir, utf8_files, name)
2083
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2117
2085
def supports_tags(self):
2140
2108
"""See BranchFormat.get_format_description()."""
2141
2109
return "Branch format 6"
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', ''),
2149
return self._initialize_helper(a_bzrdir, utf8_files, name)
2117
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
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"
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', ''),
2178
2146
('references', '')
2180
return self._initialize_helper(a_bzrdir, utf8_files, name)
2183
super(BzrBranchFormat8, self).__init__()
2184
self._matchingbzrdir.repository_format = \
2185
RepositoryFormatKnitPack5RichRoot()
2148
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2187
2150
def make_tags(self, branch):
2188
2151
"""See bzrlib.branch.BranchFormat.make_tags()."""
2206
2169
This format was introduced in bzr 1.6.
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', ''),
2215
return self._initialize_helper(a_bzrdir, utf8_files, name)
2178
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2217
2180
def _branch_class(self):
2218
2181
return BzrBranch7
2260
2230
transport = a_bzrdir.get_branch_transport(None, name=name)
2261
2231
location = transport.put_bytes('location', to_branch.base)
2263
def initialize(self, a_bzrdir, name=None, target_branch=None):
2233
def initialize(self, a_bzrdir, name=None, target_branch=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
2306
class BranchFormatRegistry(controldir.ControlComponentFormatRegistry):
2307
"""Branch format registry."""
2309
def __init__(self, other_registry=None):
2310
super(BranchFormatRegistry, self).__init__(other_registry)
2311
self._default_format = None
2313
def set_default(self, format):
2314
self._default_format = format
2316
def get_default(self):
2317
return self._default_format
2334
2320
network_format_registry = registry.FormatRegistry()
2335
2321
"""Registry of formats indexed by their network name.
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(),
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)
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
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,
2631
result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
2649
2632
result.new_revno, result.new_revid = target.last_revision_info()
2683
2666
"""Return the branch we are bound to.
2685
2668
:return: Either a Branch, or None
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.
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
2675
def _get_master_branch(self, possible_transports):
2692
2676
bound_loc = self.get_bound_location()
2693
2677
if not bound_loc:
3045
3031
index = self._partial_revision_history_cache.index(revision_id)
3046
3032
except ValueError:
3047
self._extend_partial_history(stop_revision=revision_id)
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)
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())]
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
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)
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:
3377
self.source.lock_read()
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)
3385
self.source.unlock()
3371
3388
def update_revisions(self, stop_revision=None, overwrite=False,
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)
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()
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:
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.
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.