704
705
information. This can be None.
709
other_revno, other_last_revision = other.last_revision_info()
710
stop_revno = None # unknown
711
if stop_revision is None:
712
stop_revision = other_last_revision
713
if _mod_revision.is_null(stop_revision):
714
# if there are no commits, we're done.
716
stop_revno = other_revno
718
# what's the current last revision, before we fetch [and change it
720
last_rev = _mod_revision.ensure_null(self.last_revision())
721
# we fetch here so that we don't process data twice in the common
722
# case of having something to pull, and so that the check for
723
# already merged can operate on the just fetched graph, which will
724
# be cached in memory.
725
self.fetch(other, stop_revision)
726
# Check to see if one is an ancestor of the other
729
graph = self.repository.get_graph()
730
if self._check_if_descendant_or_diverged(
731
stop_revision, last_rev, graph, other):
732
# stop_revision is a descendant of last_rev, but we aren't
733
# overwriting, so we're done.
735
if stop_revno is None:
737
graph = self.repository.get_graph()
738
this_revno, this_last_revision = self.last_revision_info()
739
stop_revno = graph.find_distance_to_null(stop_revision,
740
[(other_last_revision, other_revno),
741
(this_last_revision, this_revno)])
742
self.set_last_revision_info(stop_revno, stop_revision)
708
return InterBranch.get(other, self).update_revisions(stop_revision,
746
711
def revision_id_to_revno(self, revision_id):
747
712
"""Given a revision id, return its revno"""
2745
2710
target.unlock()
2714
class InterBranch(InterObject):
2715
"""This class represents operations taking place between two branches.
2717
Its instances have methods like pull() and push() and contain
2718
references to the source and target repositories these operations
2719
can be carried out on.
2723
"""The available optimised InterBranch types."""
2726
def _get_branch_formats_to_test():
2727
"""Return a tuple with the Branch formats to use when testing."""
2728
raise NotImplementedError(self._get_branch_formats_to_test)
2730
def update_revisions(self, stop_revision=None, overwrite=False,
2732
"""Pull in new perfect-fit revisions.
2734
:param stop_revision: Updated until the given revision
2735
:param overwrite: Always set the branch pointer, rather than checking
2736
to see if it is a proper descendant.
2737
:param graph: A Graph object that can be used to query history
2738
information. This can be None.
2741
raise NotImplementedError(self.update_revisions)
2744
class GenericInterBranch(InterBranch):
2745
"""InterBranch implementation that uses public Branch functions.
2749
def _get_branch_formats_to_test():
2750
return BranchFormat._default_format, BranchFormat._default_format
2752
def update_revisions(self, stop_revision=None, overwrite=False,
2754
"""See InterBranch.update_revisions()."""
2755
self.source.lock_read()
2757
other_revno, other_last_revision = self.source.last_revision_info()
2758
stop_revno = None # unknown
2759
if stop_revision is None:
2760
stop_revision = other_last_revision
2761
if _mod_revision.is_null(stop_revision):
2762
# if there are no commits, we're done.
2764
stop_revno = other_revno
2766
# what's the current last revision, before we fetch [and change it
2768
last_rev = _mod_revision.ensure_null(self.target.last_revision())
2769
# we fetch here so that we don't process data twice in the common
2770
# case of having something to pull, and so that the check for
2771
# already merged can operate on the just fetched graph, which will
2772
# be cached in memory.
2773
self.target.fetch(self.source, stop_revision)
2774
# Check to see if one is an ancestor of the other
2777
graph = self.target.repository.get_graph()
2778
if self.target._check_if_descendant_or_diverged(
2779
stop_revision, last_rev, graph, self.source):
2780
# stop_revision is a descendant of last_rev, but we aren't
2781
# overwriting, so we're done.
2783
if stop_revno is None:
2785
graph = self.target.repository.get_graph()
2786
this_revno, this_last_revision = \
2787
self.target.last_revision_info()
2788
stop_revno = graph.find_distance_to_null(stop_revision,
2789
[(other_last_revision, other_revno),
2790
(this_last_revision, this_revno)])
2791
self.target.set_last_revision_info(stop_revno, stop_revision)
2793
self.source.unlock()
2796
def is_compatible(self, source, target):
2797
# GenericBranch uses the public API, so always compatible
2801
InterBranch.register_optimiser(GenericInterBranch)