632
632
# because we can't connect to the remote location.
633
633
# How do we distinguish this from a remote branch
634
634
# which has been deleted?
635
rev_history = self._update_remote_location(bound_loc,
635
rev_history = self._update_remote_location(bound_loc, rev_history)
637
636
self.put_controlfile('revision-history', '\n'.join(rev_history))
639
638
def has_revision(self, revision_id):
792
def missing_revisions(self, other, stop_revision=None, diverged_ok=False):
791
def missing_revisions(self, other, stop_revision=None, other_history=None):
793
792
"""Return a list of new revisions that would perfectly fit.
795
794
If self and other have not diverged, return a list of the revisions
820
819
self_history = self.revision_history()
821
820
self_len = len(self_history)
822
other_history = other.revision_history()
821
if other_history is None:
822
other_history = other.revision_history()
823
823
other_len = len(other_history)
824
824
common_index = min(self_len, other_len) -1
825
825
if common_index >= 0 and \
834
834
raise bzrlib.errors.NoSuchRevision(self, stop_revision)
835
835
return other_history[self_len:stop_revision]
837
def update_revisions(self, other, stop_revision=None):
838
"""Pull in new perfect-fit revisions."""
837
def update_revisions(self, other, stop_revision=None, other_history=None):
838
"""Pull in new perfect-fit revisions.
840
:param other: Another Branch to pull from
841
:param stop_revision: Updated until the given revision
842
:param other_history: Alternative history to other.revision_history()
839
845
from bzrlib.fetch import greedy_fetch
840
846
if stop_revision is None:
841
stop_revision = other.last_revision()
847
if other_history is not None:
848
stop_revision = other_history[-1]
850
stop_revision = other.last_revision()
842
851
### Should this be checking is_ancestor instead of revision_history?
843
852
if (stop_revision is not None and
844
853
stop_revision in self.revision_history()):
846
855
greedy_fetch(to_branch=self, from_branch=other,
847
856
revision=stop_revision)
848
pullable_revs = self.pullable_revisions(other, stop_revision)
857
pullable_revs = self.pullable_revisions(other, stop_revision,
858
other_history=other_history)
849
859
if len(pullable_revs) > 0:
850
860
self.append_revision(*pullable_revs)
852
def pullable_revisions(self, other, stop_revision):
862
def pullable_revisions(self, other, stop_revision, other_history=None):
863
if other_history is not None:
865
other_revno = other_history.index(stop_revision) + 1
867
raise errors.NoSuchRevision(self, stop_revision)
854
869
other_revno = other.revision_id_to_revno(stop_revision)
855
return self.missing_revisions(other, other_revno)
856
except (DivergedBranches, errors.NoSuchRevision), e:
871
return self.missing_revisions(other, other_revno,
872
other_history=other_history)
873
except DivergedBranches, e:
858
875
pullable_revs = get_intervening_revisions(self.last_revision(),
859
876
stop_revision, self)
1168
1185
@needs_read_lock
1169
def _update_remote_location(self, other_loc, revision):
1186
def _update_remote_location(self, other_loc, revision_history):
1170
1187
"""Make sure the remote location has the local changes.
1172
1189
:param other_loc: Path to the other location
1173
:param revision: Revision which needs to inserted
1174
into the remote tree. (plus ancestry)
1190
:param revision_history: Total history to be updated
1175
1191
:return: The remote revision_history
1177
TODO: update_revisions is too expensive when we know
1178
what the real history should be most of the time,
1179
as it has to trace ancestry.
1181
1193
from bzrlib.fetch import greedy_fetch
1182
mutter('_update_remote_location: %r, %r', other_loc, revision)
1194
mutter('_update_remote_location: %r, %r', other_loc, revision_history)
1183
1195
other = Branch.open(other_loc)
1184
1196
bound_loc = other.get_bound_location()
1185
1197
if bound_loc is not None: