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