1599
1598
@needs_read_lock
1600
def search_missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
1599
def search_missing_revision_ids(self, other,
1600
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
1601
find_ghosts=True, revision_ids=None, if_present_ids=None):
1601
1602
"""Return the revision ids that other has that this does not.
1603
1604
These are returned in topological order.
1605
1606
revision_id: only return revision ids included by revision_id.
1608
if symbol_versioning.deprecated_passed(revision_id):
1609
symbol_versioning.warn(
1610
'search_missing_revision_ids(revision_id=...) was '
1611
'deprecated in 2.3. Use revision_ids=[...] instead.',
1612
DeprecationWarning, stacklevel=3)
1613
if revision_ids is not None:
1614
raise AssertionError(
1615
'revision_ids is mutually exclusive with revision_id')
1616
if revision_id is not None:
1617
revision_ids = [revision_id]
1607
1618
return InterRepository.get(other, self).search_missing_revision_ids(
1608
revision_id, find_ghosts)
1619
find_ghosts=find_ghosts, revision_ids=revision_ids,
1620
if_present_ids=if_present_ids)
1611
1623
def open(base):
3489
3505
return searcher.get_result()
3491
3507
@needs_read_lock
3492
def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
3508
def search_missing_revision_ids(self,
3509
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
3510
find_ghosts=True, revision_ids=None, if_present_ids=None):
3493
3511
"""Return the revision ids that source has that target does not.
3495
3513
:param revision_id: only return revision ids included by this
3515
:param revision_ids: return revision ids included by these
3516
revision_ids. NoSuchRevision will be raised if any of these
3517
revisions are not present.
3518
:param if_present_ids: like revision_ids, but will not cause
3519
NoSuchRevision if any of these are absent, instead they will simply
3520
not be in the result. This is useful for e.g. finding revisions
3521
to fetch for tags, which may reference absent revisions.
3497
3522
:param find_ghosts: If True find missing revisions in deep history
3498
3523
rather than just finding the surface difference.
3499
3524
:return: A bzrlib.graph.SearchResult.
3526
if symbol_versioning.deprecated_passed(revision_id):
3527
symbol_versioning.warn(
3528
'search_missing_revision_ids(revision_id=...) was '
3529
'deprecated in 2.3. Use revision_ids=[...] instead.',
3530
DeprecationWarning, stacklevel=2)
3531
if revision_ids is not None:
3532
raise AssertionError(
3533
'revision_ids is mutually exclusive with revision_id')
3534
if revision_id is not None:
3535
revision_ids = [revision_id]
3501
3537
# stop searching at found target revisions.
3502
if not find_ghosts and revision_id is not None:
3503
return self._walk_to_common_revisions([revision_id])
3538
if not find_ghosts and (revision_ids is not None or if_present_ids is
3540
return self._walk_to_common_revisions(revision_ids,
3541
if_present_ids=if_present_ids)
3504
3542
# generic, possibly worst case, slow code path.
3505
3543
target_ids = set(self.target.all_revision_ids())
3506
if revision_id is not None:
3507
source_ids = self.source.get_ancestry(revision_id)
3508
if source_ids[0] is not None:
3509
raise AssertionError()
3512
source_ids = self.source.all_revision_ids()
3544
source_ids = self._present_source_revisions_for(
3545
revision_ids, if_present_ids)
3513
3546
result_set = set(source_ids).difference(target_ids)
3514
3547
return self.source.revision_ids_to_search_result(result_set)
3549
def _present_source_revisions_for(self, revision_ids, if_present_ids=None):
3550
"""Returns set of all revisions in ancestry of revision_ids present in
3553
:param revision_ids: if None, all revisions in source are returned.
3554
:param if_present_ids: like revision_ids, but if any/all of these are
3555
absent no error is raised.
3557
if revision_ids is not None or if_present_ids is not None:
3558
# First, ensure all specified revisions exist. Callers expect
3559
# NoSuchRevision when they pass absent revision_ids here.
3560
if revision_ids is None:
3561
revision_ids = set()
3562
if if_present_ids is None:
3563
if_present_ids = set()
3564
revision_ids = set(revision_ids)
3565
if_present_ids = set(if_present_ids)
3566
all_wanted_ids = revision_ids.union(if_present_ids)
3567
graph = self.source.get_graph()
3568
present_revs = set(graph.get_parent_map(all_wanted_ids))
3569
missing = revision_ids.difference(present_revs)
3571
raise errors.NoSuchRevision(self.source, missing.pop())
3572
found_ids = all_wanted_ids.intersection(present_revs)
3573
source_ids = [rev_id for (rev_id, parents) in
3574
graph.iter_ancestry(found_ids)
3575
if rev_id != _mod_revision.NULL_REVISION
3576
and parents is not None]
3578
source_ids = self.source.all_revision_ids()
3579
return set(source_ids)
3517
3582
def _same_model(source, target):
3518
3583
"""True if source and target have the same data representation.