660
662
raise errors.UnsupportedOperation(self.get_reference_info, self)
662
664
@needs_write_lock
663
def fetch(self, from_branch, last_revision=None, pb=None):
665
def fetch(self, from_branch, last_revision=None, pb=None, fetch_spec=None):
664
666
"""Copy revisions from from_branch into this branch.
666
668
:param from_branch: Where to copy from.
667
669
:param last_revision: What revision to stop at (None for at the end
669
671
:param pb: An optional progress bar to use.
672
:param fetch_spec: If specified, a SearchResult or
673
PendingAncestryResult that describes which revisions to copy. This
674
allows copying multiple heads at once. Mutually exclusive with
678
if fetch_spec is not None and last_revision is not None:
679
raise AssertionError(
680
"fetch_spec and last_revision are mutually exclusive.")
672
681
if self.base == from_branch.base:
674
683
if pb is not None:
677
686
% "pb parameter to fetch()")
678
687
from_branch.lock_read()
680
if last_revision is None:
689
if last_revision is None and fetch_spec is None:
681
690
last_revision = from_branch.last_revision()
682
691
last_revision = _mod_revision.ensure_null(last_revision)
683
692
return self.repository.fetch(from_branch.repository,
684
693
revision_id=last_revision,
694
pb=pb, fetch_spec=fetch_spec)
687
696
from_branch.unlock()
1020
1029
return other_history[self_len:stop_revision]
1022
1031
def update_revisions(self, other, stop_revision=None, overwrite=False,
1032
graph=None, fetch_tags=True):
1024
1033
"""Pull in new perfect-fit revisions.
1026
1035
:param other: Another Branch to pull from
1029
1038
to see if it is a proper descendant.
1030
1039
:param graph: A Graph object that can be used to query history
1031
1040
information. This can be None.
1041
:param fetch_tags: Flag that specifies if tags from other should be
1034
1045
return InterBranch.get(other, self).update_revisions(stop_revision,
1046
overwrite, graph, fetch_tags=fetch_tags)
1048
@deprecated_method(deprecated_in((2, 4, 0)))
1037
1049
def import_last_revision_info(self, source_repo, revno, revid):
1038
1050
"""Set the last revision info, importing from another repo if necessary.
1040
This is used by the bound branch code to upload a revision to
1041
the master branch first before updating the tip of the local branch.
1043
1052
:param source_repo: Source repository to optionally fetch from
1044
1053
:param revno: Revision number of the new tip
1045
1054
:param revid: Revision id of the new tip
1048
1057
self.repository.fetch(source_repo, revision_id=revid)
1049
1058
self.set_last_revision_info(revno, revid)
1060
def import_last_revision_info_and_tags(self, source, revno, revid):
1061
"""Set the last revision info, importing from another repo if necessary.
1063
This is used by the bound branch code to upload a revision to
1064
the master branch first before updating the tip of the local branch.
1065
Revisions referenced by source's tags are also transferred.
1067
:param source: Source branch to optionally fetch from
1068
:param revno: Revision number of the new tip
1069
:param revid: Revision id of the new tip
1071
if not self.repository.has_same_location(source.repository):
1073
tags_to_fetch = set(source.tags.get_reverse_tag_dict())
1074
except errors.TagsNotSupported:
1075
tags_to_fetch = set()
1076
fetch_spec = _mod_graph.NotInOtherForRevs(self.repository,
1077
source.repository, [revid],
1078
if_present_ids=tags_to_fetch).execute()
1079
self.repository.fetch(source.repository, fetch_spec=fetch_spec)
1080
self.set_last_revision_info(revno, revid)
1051
1082
def revision_id_to_revno(self, revision_id):
1052
1083
"""Given a revision id, return its revno"""
1053
1084
if _mod_revision.is_null(revision_id):
3354
3385
@needs_write_lock
3355
3386
def update_revisions(self, stop_revision=None, overwrite=False,
3387
graph=None, fetch_tags=True):
3357
3388
"""Pull in new perfect-fit revisions.
3359
3390
:param stop_revision: Updated until the given revision
3361
3392
to see if it is a proper descendant.
3362
3393
:param graph: A Graph object that can be used to query history
3363
3394
information. This can be None.
3395
:param fetch_tags: Flag that specifies if tags from source should be
3366
3399
raise NotImplementedError(self.update_revisions)
3425
3458
@needs_write_lock
3426
3459
def update_revisions(self, stop_revision=None, overwrite=False,
3460
graph=None, fetch_tags=True):
3428
3461
"""See InterBranch.update_revisions()."""
3429
3462
other_revno, other_last_revision = self.source.last_revision_info()
3430
3463
stop_revno = None # unknown
3442
3475
# case of having something to pull, and so that the check for
3443
3476
# already merged can operate on the just fetched graph, which will
3444
3477
# be cached in memory.
3445
self.target.fetch(self.source, stop_revision)
3479
fetch_spec_factory = fetch.FetchSpecFactory()
3480
fetch_spec_factory.source_branch = self.source
3481
fetch_spec_factory.source_branch_stop_revision_id = stop_revision
3482
fetch_spec_factory.source_repo = self.source.repository
3483
fetch_spec_factory.target_repo = self.target.repository
3484
fetch_spec_factory.target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
3485
fetch_spec = fetch_spec_factory.make_fetch_spec()
3487
fetch_spec = _mod_graph.NotInOtherForRevs(self.target.repository,
3488
self.source.repository, revision_ids=[stop_revision]).execute()
3489
self.target.fetch(self.source, fetch_spec=fetch_spec)
3446
3490
# Check to see if one is an ancestor of the other
3447
3491
if not overwrite:
3448
3492
if graph is None: