794
794
(format, data_list, StringIO(knit_bytes).read))
797
def missing_revision_ids(self, other, revision_id=None):
797
def missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
798
798
"""Return the revision ids that other has that this does not.
800
800
These are returned in topological order.
802
802
revision_id: only return revision ids included by revision_id.
804
return InterRepository.get(other, self).missing_revision_ids(revision_id)
804
return InterRepository.get(other, self).missing_revision_ids(
805
revision_id, find_ghosts)
1053
1054
@needs_write_lock
1054
1055
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
1055
1056
signature = gpg_strategy.sign(plaintext)
1057
self.add_signature_text(revision_id, signature)
1060
def add_signature_text(self, revision_id, signature):
1056
1061
self._revision_store.add_revision_signature_text(revision_id,
1058
1063
self.get_transaction())
1091
1095
not part of the line_iterator's output then False will be given -
1092
1096
even though it may actually refer to that key.
1094
assert self._serializer.support_altered_by_hack, \
1095
("_find_text_key_references_from_xml_inventory_lines only "
1096
"supported for branches which store inventory as unnested xml, "
1098
if not self._serializer.support_altered_by_hack:
1099
raise AssertionError(
1100
"_find_text_key_references_from_xml_inventory_lines only "
1101
"supported for branches which store inventory as unnested xml"
1102
", not on %r" % self)
1100
1105
# this code needs to read every new line in every inventory for the
1140
1145
unescape_revid_cache[revision_id] = unescaped
1141
1146
revision_id = unescaped
1143
# Note that unescaping always means that on a fulltext cached
1144
# inventory we deserialised every fileid, which for general 'pull'
1145
# is not great, but we don't really want to have some many
1146
# fulltexts that this matters anyway. RBC 20071114.
1148
# Note that unconditionally unescaping means that we deserialise
1149
# every fileid, which for general 'pull' is not great, but we don't
1150
# really want to have some many fulltexts that this matters anyway.
1148
1153
file_id = unescape_fileid_cache[file_id]
1149
1154
except KeyError:
1785
1790
def install_revision(repository, rev, revision_tree):
1786
1791
"""Install all revision data into a repository."""
1792
install_revisions(repository, [(rev, revision_tree, None)])
1795
def install_revisions(repository, iterable):
1796
"""Install all revision data into a repository.
1798
Accepts an iterable of revision, tree, signature tuples. The signature
1787
1801
repository.start_write_group()
1789
_install_revision(repository, rev, revision_tree)
1803
for revision, revision_tree, signature in iterable:
1804
_install_revision(repository, revision, revision_tree, signature)
1791
1806
repository.abort_write_group()
1794
1809
repository.commit_write_group()
1797
def _install_revision(repository, rev, revision_tree):
1812
def _install_revision(repository, rev, revision_tree, signature):
1798
1813
"""Install all revision data into a repository."""
1799
1814
present_parents = []
1800
1815
parent_trees = {}
1839
1854
repository.add_inventory(rev.revision_id, inv, present_parents)
1840
1855
except errors.RevisionAlreadyPresent:
1857
if signature is not None:
1858
repository.add_signature_text(rev.revision_id, signature)
1842
1859
repository.add_revision(rev.revision_id, rev, inv)
2139
2156
'RepositoryFormatKnit3',
2159
format_registry.register_lazy(
2160
'Bazaar Knit Repository Format 4 (bzr 1.0)\n',
2161
'bzrlib.repofmt.knitrepo',
2162
'RepositoryFormatKnit4',
2142
2165
# Pack-based formats. There is one format for pre-subtrees, and one for
2143
2166
# post-subtrees to allow ease of testing.
2144
2167
# NOTE: These are experimental in 0.92.
2188
2211
raise NotImplementedError(self.fetch)
2190
2213
@needs_read_lock
2191
def missing_revision_ids(self, revision_id=None):
2214
def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2192
2215
"""Return the revision ids that source has that target does not.
2194
2217
These are returned in topological order.
2355
2378
return f.count_copied, f.failed_revisions
2357
2380
@needs_read_lock
2358
def missing_revision_ids(self, revision_id=None):
2381
def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2359
2382
"""See InterRepository.missing_revision_ids()."""
2360
2383
# we want all revisions to satisfy revision_id in source.
2361
2384
# but we don't want to stat every file here and there.
2433
2456
return f.count_copied, f.failed_revisions
2435
2458
@needs_read_lock
2436
def missing_revision_ids(self, revision_id=None):
2459
def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2437
2460
"""See InterRepository.missing_revision_ids()."""
2438
2461
if revision_id is not None:
2439
2462
source_ids = self.source.get_ancestry(revision_id)
2526
2549
# a pack creation, but for now it is simpler to think about as
2527
2550
# 'upload data, then repack if needed'.
2528
2551
self.target._pack_collection.autopack()
2529
return pack.get_revision_count()
2552
return (pack.get_revision_count(), [])
2533
2556
@needs_read_lock
2534
2557
def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2555
2578
target_index.iter_entries(target_keys))
2556
2579
missing_revs.update(next_revs - have_revs)
2557
2580
searcher.stop_searching_any(have_revs)
2581
if next_revs - have_revs == set([revision_id]):
2582
# we saw the start rev itself, but no parents from it (or
2583
# next_revs would have been updated to e.g. set(). We remove
2584
# have_revs because if we found revision_id locally we
2585
# stop_searching at the first time around.
2586
raise errors.NoSuchRevision(self.source, revision_id)
2558
2587
return missing_revs
2559
2588
elif revision_id is not None:
2560
2589
source_ids = self.source.get_ancestry(revision_id)
2651
2680
return f.count_copied, f.failed_revisions
2683
class InterDifferingSerializer(InterKnitRepo):
2686
def _get_repo_format_to_test(self):
2690
def is_compatible(source, target):
2691
"""Be compatible with Knit2 source and Knit3 target"""
2692
if source.supports_rich_root() != target.supports_rich_root():
2694
# Ideally, we'd support fetching if the source had no tree references
2695
# even if it supported them...
2696
if (getattr(source, '_format.supports_tree_reference', False) and
2697
not getattr(target, '_format.supports_tree_reference', False)):
2702
def fetch(self, revision_id=None, pb=None, find_ghosts=False):
2703
"""See InterRepository.fetch()."""
2704
revision_ids = self.target.missing_revision_ids(self.source,
2706
def revisions_iterator():
2707
for current_revision_id in revision_ids:
2708
revision = self.source.get_revision(current_revision_id)
2709
tree = self.source.revision_tree(current_revision_id)
2711
signature = self.source.get_signature_text(
2712
current_revision_id)
2713
except errors.NoSuchRevision:
2715
yield revision, tree, signature
2716
install_revisions(self.target, revisions_iterator())
2717
return len(revision_ids), 0
2654
2720
class InterRemoteToOther(InterRepository):
2656
2722
def __init__(self, source, target):
2789
InterRepository.register_optimiser(InterDifferingSerializer)
2723
2790
InterRepository.register_optimiser(InterSameDataRepository)
2724
2791
InterRepository.register_optimiser(InterWeaveRepo)
2725
2792
InterRepository.register_optimiser(InterKnitRepo)