135
137
def open_containing(url, possible_transports=None):
136
138
"""Open an existing branch which contains url.
138
140
This probes for a branch at url, and searches upwards from there.
140
142
Basically we keep looking up until we find the control directory or
141
143
run into the root. If there isn't one, raises NotBranchError.
142
If there is one and it is either an unrecognised format or an unsupported
144
If there is one and it is either an unrecognised format or an unsupported
143
145
format, UnknownFormatError or UnsupportedFormatError are raised.
144
146
If there is one, it is returned, along with the unused portion of url.
491
499
def get_old_bound_location(self):
492
500
"""Return the URL of the branch we used to be bound to
494
502
raise errors.UpgradeRequired(self.base)
496
def get_commit_builder(self, parents, config=None, timestamp=None,
497
timezone=None, committer=None, revprops=None,
504
def get_commit_builder(self, parents, config=None, timestamp=None,
505
timezone=None, committer=None, revprops=None,
498
506
revision_id=None):
499
507
"""Obtain a CommitBuilder for this branch.
501
509
:param parents: Revision ids of the parents of the new revision.
502
510
:param config: Optional configuration to use.
503
511
:param timestamp: Optional timestamp recorded for commit.
510
518
if config is None:
511
519
config = self.get_config()
513
521
return self.repository.get_commit_builder(self, parents, config,
514
522
timestamp, timezone, committer, revprops, revision_id)
516
524
def get_master_branch(self, possible_transports=None):
517
525
"""Return the branch we are bound to.
519
527
:return: Either a Branch, or None
593
601
def _gen_revision_history(self):
594
602
"""Return sequence of revision hashes on to this branch.
596
604
Unlike revision_history, this method always regenerates or rereads the
597
605
revision history, i.e. it does not cache the result, so repeated calls
598
606
may be expensive.
600
608
Concrete subclasses should override this instead of revision_history so
601
609
that subclasses do not need to deal with caching logic.
603
611
This API is semi-public; it only for use by subclasses, all other code
604
612
should consider it to be private.
695
703
information. This can be None.
700
other_revno, other_last_revision = other.last_revision_info()
701
stop_revno = None # unknown
702
if stop_revision is None:
703
stop_revision = other_last_revision
704
if _mod_revision.is_null(stop_revision):
705
# if there are no commits, we're done.
707
stop_revno = other_revno
709
# what's the current last revision, before we fetch [and change it
711
last_rev = _mod_revision.ensure_null(self.last_revision())
712
# we fetch here so that we don't process data twice in the common
713
# case of having something to pull, and so that the check for
714
# already merged can operate on the just fetched graph, which will
715
# be cached in memory.
716
self.fetch(other, stop_revision)
717
# Check to see if one is an ancestor of the other
720
graph = self.repository.get_graph()
721
if self._check_if_descendant_or_diverged(
722
stop_revision, last_rev, graph, other):
723
# stop_revision is a descendant of last_rev, but we aren't
724
# overwriting, so we're done.
726
if stop_revno is None:
728
graph = self.repository.get_graph()
729
this_revno, this_last_revision = self.last_revision_info()
730
stop_revno = graph.find_distance_to_null(stop_revision,
731
[(other_last_revision, other_revno),
732
(this_last_revision, this_revno)])
733
self.set_last_revision_info(stop_revno, stop_revision)
706
return InterBranch.get(other, self).update_revisions(stop_revision,
737
709
def revision_id_to_revno(self, revision_id):
738
710
"""Given a revision id, return its revno"""
904
876
raise errors.InvalidRevisionNumber(revno)
907
def clone(self, to_bzrdir, revision_id=None):
879
def clone(self, to_bzrdir, revision_id=None, repository_policy=None):
908
880
"""Clone this branch into to_bzrdir preserving all semantic values.
882
Most API users will want 'create_clone_on_transport', which creates a
883
new bzrdir and branch on the fly.
910
885
revision_id: if not None, the revision history in the new branch will
911
886
be truncated to end with revision_id.
913
888
result = to_bzrdir.create_branch()
889
if repository_policy is not None:
890
repository_policy.configure_branch(result)
914
891
self.copy_content_into(result, revision_id=revision_id)
974
951
destination.set_parent(parent)
975
self.tags.merge_to(destination.tags)
952
if self._push_should_merge_tags():
953
self.tags.merge_to(destination.tags)
979
957
"""Check consistency of the branch.
981
959
In particular this checks that revisions given in the revision-history
982
do actually match up in the revision graph, and that they're all
960
do actually match up in the revision graph, and that they're all
983
961
present in the repository.
985
963
Callers will typically also want to check the repository.
987
965
:return: A BranchCheckResult.
1026
1004
format.set_branch_format(self._format)
1007
def create_clone_on_transport(self, to_transport, revision_id=None,
1009
"""Create a clone of this branch and its bzrdir.
1011
:param to_transport: The transport to clone onto.
1012
:param revision_id: The revision id to use as tip in the new branch.
1013
If None the tip is obtained from this branch.
1014
:param stacked_on: An optional URL to stack the clone on.
1016
# XXX: Fix the bzrdir API to allow getting the branch back from the
1017
# clone call. Or something. 20090224 RBC/spiv.
1018
dir_to = self.bzrdir.clone_on_transport(to_transport,
1019
revision_id=revision_id, stacked_on=stacked_on)
1020
return dir_to.open_branch()
1029
1022
def create_checkout(self, to_location, revision_id=None,
1030
1023
lightweight=False, accelerator_tree=None,
1031
1024
hardlink=False):
1032
1025
"""Create a checkout of a branch.
1034
1027
:param to_location: The url to produce the checkout at
1035
1028
:param revision_id: The revision to check out
1036
1029
:param lightweight: If True, produce a lightweight checkout, otherwise,
1139
1132
* a format string,
1140
1133
* an open routine.
1142
Formats are placed in an dict by their format string for reference
1135
Formats are placed in an dict by their format string for reference
1143
1136
during branch opening. Its not required that these be instances, they
1144
can be classes themselves with class methods - it simply depends on
1137
can be classes themselves with class methods - it simply depends on
1145
1138
whether state is needed for a given format or not.
1147
1140
Once a format is deprecated, just deprecate the initialize and open
1148
methods on the format class. Do not deprecate the object, as the
1141
methods on the format class. Do not deprecate the object, as the
1149
1142
object will be created every time regardless.
1253
1246
"""Is this format supported?
1255
1248
Supported formats can be initialized and opened.
1256
Unsupported formats may not support initialization or committing or
1249
Unsupported formats may not support initialization or committing or
1257
1250
some other features depending on the reason for not being supported.
1254
def network_name(self):
1255
"""A simple byte string uniquely identifying this format for RPC calls.
1257
MetaDir branch formats use their disk format string to identify the
1258
repository over the wire. All in one formats such as bzr < 0.8, and
1259
foreign formats like svn/git and hg should use some marker which is
1260
unique and immutable.
1262
raise NotImplementedError(self.network_name)
1261
1264
def open(self, a_bzrdir, _found=False):
1262
1265
"""Return the branch object for a_bzrdir
1317
1323
# (push_result)
1318
1324
# containing the members
1319
1325
# (source, local, master, old_revno, old_revid, new_revno, new_revid)
1320
# where local is the local target branch or None, master is the target
1326
# where local is the local target branch or None, master is the target
1321
1327
# master branch, and the rest should be self explanatory. The source
1322
1328
# is read locked and the target branches write locked. Source will
1323
1329
# be the local low-latency branch.
1327
1333
# (pull_result)
1328
1334
# containing the members
1329
1335
# (source, local, master, old_revno, old_revid, new_revno, new_revid)
1330
# where local is the local branch or None, master is the target
1336
# where local is the local branch or None, master is the target
1331
1337
# master branch, and the rest should be self explanatory. The source
1332
1338
# is read locked and the target branches write locked. The local
1333
1339
# branch is the low-latency branch.
1708
1738
really matter if it's on an nfs/smb/afs/coda/... share, as long as
1709
1739
it's writable, and can be accessed via the normal filesystem API.
1711
:ivar _transport: Transport for file operations on this branch's
1741
:ivar _transport: Transport for file operations on this branch's
1712
1742
control files, typically pointing to the .bzr/branch directory.
1713
1743
:ivar repository: Repository for this branch.
1714
:ivar base: The url of the base directory for this branch; the one
1744
:ivar base: The url of the base directory for this branch; the one
1715
1745
containing the .bzr directory.
1718
1748
def __init__(self, _format=None,
1719
1749
_control_files=None, a_bzrdir=None, _repository=None):
1720
1750
"""Create new branch object at a particular location."""
1958
1988
This is the basic concrete implementation of push()
1960
1990
:param _override_hook_source_branch: If specified, run
1961
the hooks passing this Branch as the source, rather than self.
1991
the hooks passing this Branch as the source, rather than self.
1962
1992
This is for use of RemoteBranch, where push is delegated to the
1963
underlying vfs-based Branch.
1993
underlying vfs-based Branch.
1965
1995
# TODO: Public option to disable running hooks - should be trivial but
2689
2711
target.unlock()
2715
class InterBranch(InterObject):
2716
"""This class represents operations taking place between two branches.
2718
Its instances have methods like pull() and push() and contain
2719
references to the source and target repositories these operations
2720
can be carried out on.
2724
"""The available optimised InterBranch types."""
2727
def _get_branch_formats_to_test():
2728
"""Return a tuple with the Branch formats to use when testing."""
2729
raise NotImplementedError(self._get_branch_formats_to_test)
2731
def update_revisions(self, stop_revision=None, overwrite=False,
2733
"""Pull in new perfect-fit revisions.
2735
:param stop_revision: Updated until the given revision
2736
:param overwrite: Always set the branch pointer, rather than checking
2737
to see if it is a proper descendant.
2738
:param graph: A Graph object that can be used to query history
2739
information. This can be None.
2742
raise NotImplementedError(self.update_revisions)
2745
class GenericInterBranch(InterBranch):
2746
"""InterBranch implementation that uses public Branch functions.
2750
def _get_branch_formats_to_test():
2751
return BranchFormat._default_format, BranchFormat._default_format
2753
def update_revisions(self, stop_revision=None, overwrite=False,
2755
"""See InterBranch.update_revisions()."""
2756
self.source.lock_read()
2758
other_revno, other_last_revision = self.source.last_revision_info()
2759
stop_revno = None # unknown
2760
if stop_revision is None:
2761
stop_revision = other_last_revision
2762
if _mod_revision.is_null(stop_revision):
2763
# if there are no commits, we're done.
2765
stop_revno = other_revno
2767
# what's the current last revision, before we fetch [and change it
2769
last_rev = _mod_revision.ensure_null(self.target.last_revision())
2770
# we fetch here so that we don't process data twice in the common
2771
# case of having something to pull, and so that the check for
2772
# already merged can operate on the just fetched graph, which will
2773
# be cached in memory.
2774
self.target.fetch(self.source, stop_revision)
2775
# Check to see if one is an ancestor of the other
2778
graph = self.target.repository.get_graph()
2779
if self.target._check_if_descendant_or_diverged(
2780
stop_revision, last_rev, graph, self.source):
2781
# stop_revision is a descendant of last_rev, but we aren't
2782
# overwriting, so we're done.
2784
if stop_revno is None:
2786
graph = self.target.repository.get_graph()
2787
this_revno, this_last_revision = \
2788
self.target.last_revision_info()
2789
stop_revno = graph.find_distance_to_null(stop_revision,
2790
[(other_last_revision, other_revno),
2791
(this_last_revision, this_revno)])
2792
self.target.set_last_revision_info(stop_revno, stop_revision)
2794
self.source.unlock()
2797
def is_compatible(self, source, target):
2798
# GenericBranch uses the public API, so always compatible
2802
InterBranch.register_optimiser(GenericInterBranch)