13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Deprecated weave-based repository formats.
19
Weave based formats scaled linearly with history size and could not represent
25
from cStringIO import StringIO
28
from bzrlib.lazy_import import lazy_import
29
lazy_import(globals(), """
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""Old weave-based repository formats"""
20
from StringIO import StringIO
52
30
from bzrlib.decorators import needs_read_lock, needs_write_lock
53
31
from bzrlib.repository import (
33
MetaDirRepositoryFormat,
57
37
from bzrlib.store.text import TextStore
58
from bzrlib.versionedfile import (
60
FulltextContentFactory,
63
from bzrlib.vf_repository import (
64
InterSameDataRepository,
65
VersionedFileCommitBuilder,
66
VersionedFileRepository,
67
VersionedFileRepositoryFormat,
68
MetaDirVersionedFileRepository,
69
MetaDirVersionedFileRepositoryFormat,
72
from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
75
class AllInOneRepository(VersionedFileRepository):
38
from bzrlib.trace import mutter
41
class AllInOneRepository(Repository):
76
42
"""Legacy support - the repository behaviour for all-in-one branches."""
79
def _serializer(self):
80
return xml5.serializer_v5
82
def _escape(self, file_or_path):
83
if not isinstance(file_or_path, basestring):
84
file_or_path = '/'.join(file_or_path)
85
if file_or_path == '':
87
return urlutils.escape(osutils.safe_unicode(file_or_path))
89
def __init__(self, _format, a_bzrdir):
44
_serializer = xml5.serializer_v5
46
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
90
47
# we reuse one control files instance.
91
dir_mode = a_bzrdir._get_dir_mode()
92
file_mode = a_bzrdir._get_file_mode()
48
dir_mode = a_bzrdir._control_files._dir_mode
49
file_mode = a_bzrdir._control_files._file_mode
94
51
def get_store(name, compressed=True, prefixed=False):
95
52
# FIXME: This approach of assuming stores are all entirely compressed
96
# or entirely uncompressed is tidy, but breaks upgrade from
97
# some existing branches where there's a mixture; we probably
53
# or entirely uncompressed is tidy, but breaks upgrade from
54
# some existing branches where there's a mixture; we probably
98
55
# still want the option to look for both.
99
relpath = self._escape(name)
100
store = TextStore(a_bzrdir.transport.clone(relpath),
56
relpath = a_bzrdir._control_files._escape(name)
57
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
101
58
prefixed=prefixed, compressed=compressed,
102
59
dir_mode=dir_mode,
103
60
file_mode=file_mode)
61
#if self._transport.should_cache():
62
# cache_path = os.path.join(self.cache_root, name)
63
# os.mkdir(cache_path)
64
# store = bzrlib.store.CachedStore(store, cache_path)
106
67
# not broken out yet because the controlweaves|inventory_store
107
# and texts bits are still different.
68
# and text_store | weave_store bits are still different.
108
69
if isinstance(_format, RepositoryFormat4):
109
# cannot remove these - there is still no consistent api
70
# cannot remove these - there is still no consistent api
110
71
# which allows access to this old info.
111
72
self.inventory_store = get_store('inventory-store')
112
self._text_store = get_store('text-store')
113
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
116
def _all_possible_ids(self):
117
"""Return all the possible revisions that we could find."""
118
if 'evil' in debug.debug_flags:
119
trace.mutter_callsite(
120
3, "_all_possible_ids scales with size of history.")
121
return [key[-1] for key in self.inventories.keys()]
124
def _all_revision_ids(self):
125
"""Returns a list of all the revision ids in the repository.
127
These are in as much topological order as the underlying store can
128
present: for weaves ghosts may lead to a lack of correctness until
129
the reweave updates the parents list.
131
return [key[-1] for key in self.revisions.keys()]
133
def _activate_new_inventory(self):
134
"""Put a replacement inventory.new into use as inventories."""
135
# Copy the content across
136
t = self.bzrdir._control_files._transport
137
t.copy('inventory.new.weave', 'inventory.weave')
138
# delete the temp inventory
139
t.delete('inventory.new.weave')
140
# Check we can parse the new weave properly as a sanity check
141
self.inventories.keys()
143
def _backup_inventory(self):
144
t = self.bzrdir._control_files._transport
145
t.copy('inventory.weave', 'inventory.backup.weave')
147
def _temp_inventories(self):
148
t = self.bzrdir._control_files._transport
149
return self._format._get_inventories(t, self, 'inventory.new')
73
text_store = get_store('text-store')
74
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
151
76
def get_commit_builder(self, branch, parents, config, timestamp=None,
152
77
timezone=None, committer=None, revprops=None,
153
revision_id=None, lossy=False):
154
79
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
155
result = VersionedFileCommitBuilder(self, parents, config, timestamp,
156
timezone, committer, revprops, revision_id, lossy=lossy)
157
self.start_write_group()
80
return Repository.get_commit_builder(self, branch, parents, config,
81
timestamp, timezone, committer, revprops, revision_id)
161
def get_revisions(self, revision_ids):
162
revs = self._get_revisions(revision_ids)
165
def _inventory_add_lines(self, revision_id, parents, lines,
167
"""Store lines in inv_vf and return the sha1 of the inventory."""
168
present_parents = self.get_graph().get_parent_map(parents)
170
for parent in parents:
171
if parent in present_parents:
172
final_parents.append((parent,))
173
return self.inventories.add_lines((revision_id,), final_parents, lines,
174
check_content=check_content)[0]
176
84
def is_shared(self):
177
85
"""AllInOne repositories cannot be shared."""
187
95
:param new_value: True to restore the default, False to disable making
190
raise errors.RepositoryUpgradeRequired(self.user_url)
98
raise NotImplementedError(self.set_make_working_trees)
192
100
def make_working_trees(self):
193
101
"""Returns the policy for making working trees on new branches."""
197
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
105
class WeaveMetaDirRepository(MetaDirRepository):
198
106
"""A subclass of MetaDirRepository to set weave specific policy."""
200
def __init__(self, _format, a_bzrdir, control_files):
201
super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
202
self._serializer = _format._serializer
205
def _all_possible_ids(self):
206
"""Return all the possible revisions that we could find."""
207
if 'evil' in debug.debug_flags:
208
trace.mutter_callsite(
209
3, "_all_possible_ids scales with size of history.")
210
return [key[-1] for key in self.inventories.keys()]
213
def _all_revision_ids(self):
214
"""Returns a list of all the revision ids in the repository.
216
These are in as much topological order as the underlying store can
217
present: for weaves ghosts may lead to a lack of correctness until
218
the reweave updates the parents list.
220
return [key[-1] for key in self.revisions.keys()]
222
def _activate_new_inventory(self):
223
"""Put a replacement inventory.new into use as inventories."""
224
# Copy the content across
226
t.copy('inventory.new.weave', 'inventory.weave')
227
# delete the temp inventory
228
t.delete('inventory.new.weave')
229
# Check we can parse the new weave properly as a sanity check
230
self.inventories.keys()
232
def _backup_inventory(self):
234
t.copy('inventory.weave', 'inventory.backup.weave')
236
def _temp_inventories(self):
238
return self._format._get_inventories(t, self, 'inventory.new')
108
_serializer = xml5.serializer_v5
240
110
def get_commit_builder(self, branch, parents, config, timestamp=None,
241
111
timezone=None, committer=None, revprops=None,
242
revision_id=None, lossy=False):
243
113
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
244
result = VersionedFileCommitBuilder(self, parents, config, timestamp,
245
timezone, committer, revprops, revision_id, lossy=lossy)
246
self.start_write_group()
250
def get_revision(self, revision_id):
251
"""Return the Revision object for a named revision"""
252
r = self.get_revision_reconcile(revision_id)
255
def _inventory_add_lines(self, revision_id, parents, lines,
257
"""Store lines in inv_vf and return the sha1 of the inventory."""
258
present_parents = self.get_graph().get_parent_map(parents)
260
for parent in parents:
261
if parent in present_parents:
262
final_parents.append((parent,))
263
return self.inventories.add_lines((revision_id,), final_parents, lines,
264
check_content=check_content)[0]
267
class PreSplitOutRepositoryFormat(VersionedFileRepositoryFormat):
114
return MetaDirRepository.get_commit_builder(self, branch, parents,
115
config, timestamp, timezone, committer, revprops, revision_id)
118
class PreSplitOutRepositoryFormat(RepositoryFormat):
268
119
"""Base class for the pre split out repository formats."""
270
121
rich_root_data = False
271
122
supports_tree_reference = False
272
supports_ghosts = False
273
supports_external_lookups = False
274
supports_chks = False
275
_fetch_order = 'topological'
276
_fetch_reconcile = True
278
supports_leaving_lock = False
279
# XXX: This is an old format that we don't support full checking on, so
280
# just claim that checking for this inconsistency is not required.
281
revision_graph_can_have_wrong_parents = False
283
124
def initialize(self, a_bzrdir, shared=False, _internal=False):
284
"""Create a weave repository."""
125
"""Create a weave repository.
127
TODO: when creating split out bzr branch formats, move this to a common
128
base for Format5, Format6. or something like that.
286
131
raise errors.IncompatibleFormat(self, a_bzrdir._format)
288
133
if not _internal:
289
134
# always initialized when the bzrdir is.
290
135
return self.open(a_bzrdir, _found=True)
292
137
# Create an empty weave
294
139
weavefile.write_weave_v5(weave.Weave(), sio)
295
140
empty_weave = sio.getvalue()
297
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
142
mutter('creating repository in %s.', a_bzrdir.transport.base)
143
dirs = ['revision-store', 'weaves']
144
files = [('inventory.weave', StringIO(empty_weave)),
299
147
# FIXME: RBC 20060125 don't peek under the covers
300
148
# NB: no need to escape relative paths that are url safe.
301
149
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
302
'branch-lock', lockable_files.TransportLock)
150
'branch-lock', lockable_files.TransportLock)
303
151
control_files.create_lock()
304
152
control_files.lock_write()
305
transport = a_bzrdir.transport
153
control_files._transport.mkdir_multi(dirs,
154
mode=control_files._dir_mode)
307
transport.mkdir_multi(['revision-store', 'weaves'],
308
mode=a_bzrdir._get_dir_mode())
309
transport.put_bytes_non_atomic('inventory.weave', empty_weave,
310
mode=a_bzrdir._get_file_mode())
156
for file, content in files:
157
control_files.put(file, content)
312
159
control_files.unlock()
313
repository = self.open(a_bzrdir, _found=True)
314
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
160
return self.open(a_bzrdir, _found=True)
162
def _get_control_store(self, repo_transport, control_files):
163
"""Return the control store for this repository."""
164
return self._get_versioned_file_store('',
169
def _get_text_store(self, transport, control_files):
170
"""Get a store for file texts for this format."""
171
raise NotImplementedError(self._get_text_store)
317
173
def open(self, a_bzrdir, _found=False):
318
174
"""See RepositoryFormat.open()."""
398
256
_versionedfile_class = weave.WeaveFile
399
_matchingbzrdir = weave_bzrdir.BzrDirFormat5()
400
supports_funky_characters = False
257
_matchingbzrdir = bzrdir.BzrDirFormat5()
403
def _serializer(self):
404
return xml5.serializer_v5
260
super(RepositoryFormat5, self).__init__()
406
262
def get_format_description(self):
407
263
"""See RepositoryFormat.get_format_description()."""
408
264
return "Weave repository format 5"
410
def network_name(self):
411
"""The network name for this format is the control dirs disk label."""
412
return self._matchingbzrdir.get_format_string()
414
def _get_inventories(self, repo_transport, repo, name='inventory'):
415
mapper = versionedfile.ConstantMapper(name)
416
return versionedfile.ThunkedVersionedFiles(repo_transport,
417
weave.WeaveFile, mapper, repo.is_locked)
419
def _get_revisions(self, repo_transport, repo):
420
return RevisionTextStore(repo_transport.clone('revision-store'),
421
xml5.serializer_v5, False, versionedfile.PrefixMapper(),
422
repo.is_locked, repo.is_write_locked)
424
def _get_signatures(self, repo_transport, repo):
425
return SignatureTextStore(repo_transport.clone('revision-store'),
426
False, versionedfile.PrefixMapper(),
427
repo.is_locked, repo.is_write_locked)
429
def _get_texts(self, repo_transport, repo):
430
mapper = versionedfile.PrefixMapper()
431
base_transport = repo_transport.clone('weaves')
432
return versionedfile.ThunkedVersionedFiles(base_transport,
433
weave.WeaveFile, mapper, repo.is_locked)
266
def _get_revision_store(self, repo_transport, control_files):
267
"""See RepositoryFormat._get_revision_store()."""
268
"""Return the revision store object for this a_bzrdir."""
269
return self._get_text_rev_store(repo_transport,
274
def _get_text_store(self, transport, control_files):
275
"""See RepositoryFormat._get_text_store()."""
276
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
436
279
class RepositoryFormat6(PreSplitOutRepositoryFormat):
445
288
_versionedfile_class = weave.WeaveFile
446
_matchingbzrdir = weave_bzrdir.BzrDirFormat6()
447
supports_funky_characters = False
449
def _serializer(self):
450
return xml5.serializer_v5
289
_matchingbzrdir = bzrdir.BzrDirFormat6()
292
super(RepositoryFormat6, self).__init__()
452
294
def get_format_description(self):
453
295
"""See RepositoryFormat.get_format_description()."""
454
296
return "Weave repository format 6"
456
def network_name(self):
457
"""The network name for this format is the control dirs disk label."""
458
return self._matchingbzrdir.get_format_string()
460
def _get_inventories(self, repo_transport, repo, name='inventory'):
461
mapper = versionedfile.ConstantMapper(name)
462
return versionedfile.ThunkedVersionedFiles(repo_transport,
463
weave.WeaveFile, mapper, repo.is_locked)
465
def _get_revisions(self, repo_transport, repo):
466
return RevisionTextStore(repo_transport.clone('revision-store'),
467
xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
468
repo.is_locked, repo.is_write_locked)
470
def _get_signatures(self, repo_transport, repo):
471
return SignatureTextStore(repo_transport.clone('revision-store'),
472
False, versionedfile.HashPrefixMapper(),
473
repo.is_locked, repo.is_write_locked)
475
def _get_texts(self, repo_transport, repo):
476
mapper = versionedfile.HashPrefixMapper()
477
base_transport = repo_transport.clone('weaves')
478
return versionedfile.ThunkedVersionedFiles(base_transport,
479
weave.WeaveFile, mapper, repo.is_locked)
482
class RepositoryFormat7(MetaDirVersionedFileRepositoryFormat):
298
def _get_revision_store(self, repo_transport, control_files):
299
"""See RepositoryFormat._get_revision_store()."""
300
return self._get_text_rev_store(repo_transport,
306
def _get_text_store(self, transport, control_files):
307
"""See RepositoryFormat._get_text_store()."""
308
return self._get_versioned_file_store('weaves', transport, control_files)
311
class RepositoryFormat7(MetaDirRepositoryFormat):
483
312
"""Bzr repository 7.
485
314
This repository format has:
544
366
weavefile.write_weave_v5(weave.Weave(), sio)
545
367
empty_weave = sio.getvalue()
547
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
369
mutter('creating repository in %s.', a_bzrdir.transport.base)
548
370
dirs = ['revision-store', 'weaves']
549
files = [('inventory.weave', StringIO(empty_weave)),
371
files = [('inventory.weave', StringIO(empty_weave)),
551
373
utf8_files = [('format', self.get_format_string())]
553
375
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
554
376
return self.open(a_bzrdir=a_bzrdir, _found=True)
556
378
def open(self, a_bzrdir, _found=False, _override_transport=None):
557
379
"""See RepositoryFormat.open().
559
381
:param _override_transport: INTERNAL USE ONLY. Allows opening the
560
382
repository at a slightly different url
561
383
than normal. I.e. during 'upgrade'.
564
386
format = RepositoryFormat.find_format(a_bzrdir)
387
assert format.__class__ == self.__class__
565
388
if _override_transport is not None:
566
389
repo_transport = _override_transport
568
391
repo_transport = a_bzrdir.get_repository_transport(None)
569
392
control_files = lockable_files.LockableFiles(repo_transport,
570
393
'lock', lockdir.LockDir)
571
result = WeaveMetaDirRepository(_format=self, a_bzrdir=a_bzrdir,
572
control_files=control_files)
573
result.revisions = self._get_revisions(repo_transport, result)
574
result.signatures = self._get_signatures(repo_transport, result)
575
result.inventories = self._get_inventories(repo_transport, result)
576
result.texts = self._get_texts(repo_transport, result)
577
result.chk_bytes = None
578
result._transport = repo_transport
581
def is_deprecated(self):
585
class TextVersionedFiles(VersionedFiles):
586
"""Just-a-bunch-of-files based VersionedFile stores."""
588
def __init__(self, transport, compressed, mapper, is_locked, can_write):
589
self._compressed = compressed
590
self._transport = transport
591
self._mapper = mapper
596
self._is_locked = is_locked
597
self._can_write = can_write
599
def add_lines(self, key, parents, lines):
600
"""Add a revision to the store."""
601
if not self._is_locked():
602
raise errors.ObjectNotLocked(self)
603
if not self._can_write():
604
raise errors.ReadOnlyError(self)
606
raise ValueError('bad idea to put / in %r' % (key,))
607
text = ''.join(lines)
609
text = tuned_gzip.bytes_to_gzip(text)
610
path = self._map(key)
611
self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
613
def insert_record_stream(self, stream):
615
for record in stream:
616
# Raise an error when a record is missing.
617
if record.storage_kind == 'absent':
618
raise errors.RevisionNotPresent([record.key[0]], self)
619
# adapt to non-tuple interface
620
if record.storage_kind == 'fulltext':
621
self.add_lines(record.key, None,
622
osutils.split_lines(record.get_bytes_as('fulltext')))
624
adapter_key = record.storage_kind, 'fulltext'
626
adapter = adapters[adapter_key]
628
adapter_factory = adapter_registry.get(adapter_key)
629
adapter = adapter_factory(self)
630
adapters[adapter_key] = adapter
631
lines = osutils.split_lines(adapter.get_bytes(
632
record, record.get_bytes_as(record.storage_kind)))
634
self.add_lines(record.key, None, lines)
635
except errors.RevisionAlreadyPresent:
638
def _load_text(self, key):
639
if not self._is_locked():
640
raise errors.ObjectNotLocked(self)
641
path = self._map(key)
643
text = self._transport.get_bytes(path)
644
compressed = self._compressed
645
except errors.NoSuchFile:
647
# try without the .gz
650
text = self._transport.get_bytes(path)
652
except errors.NoSuchFile:
657
text = gzip.GzipFile(mode='rb', fileobj=StringIO(text)).read()
661
return self._mapper.map(key) + self._ext
664
class RevisionTextStore(TextVersionedFiles):
665
"""Legacy thunk for format 4 repositories."""
667
def __init__(self, transport, serializer, compressed, mapper, is_locked,
669
"""Create a RevisionTextStore at transport with serializer."""
670
TextVersionedFiles.__init__(self, transport, compressed, mapper,
671
is_locked, can_write)
672
self._serializer = serializer
674
def _load_text_parents(self, key):
675
text = self._load_text(key)
678
parents = self._serializer.read_revision_from_string(text).parent_ids
679
return text, tuple((parent,) for parent in parents)
681
def get_parent_map(self, keys):
684
parents = self._load_text_parents(key)[1]
687
result[key] = parents
690
def get_known_graph_ancestry(self, keys):
691
"""Get a KnownGraph instance with the ancestry of keys."""
693
parent_map = self.get_parent_map(keys)
694
kg = _mod_graph.KnownGraph(parent_map)
697
def get_record_stream(self, keys, sort_order, include_delta_closure):
699
text, parents = self._load_text_parents(key)
701
yield AbsentContentFactory(key)
703
yield FulltextContentFactory(key, parents, None, text)
706
if not self._is_locked():
707
raise errors.ObjectNotLocked(self)
709
for quoted_relpath in self._transport.iter_files_recursive():
710
relpath = urllib.unquote(quoted_relpath)
711
path, ext = os.path.splitext(relpath)
714
if not relpath.endswith('.sig'):
715
relpaths.add(relpath)
716
paths = list(relpaths)
717
return set([self._mapper.unmap(path) for path in paths])
720
class SignatureTextStore(TextVersionedFiles):
721
"""Legacy thunk for format 4-7 repositories."""
723
def __init__(self, transport, compressed, mapper, is_locked, can_write):
724
TextVersionedFiles.__init__(self, transport, compressed, mapper,
725
is_locked, can_write)
726
self._ext = '.sig' + self._ext
728
def get_parent_map(self, keys):
731
text = self._load_text(key)
737
def get_record_stream(self, keys, sort_order, include_delta_closure):
739
text = self._load_text(key)
741
yield AbsentContentFactory(key)
743
yield FulltextContentFactory(key, None, None, text)
746
if not self._is_locked():
747
raise errors.ObjectNotLocked(self)
749
for quoted_relpath in self._transport.iter_files_recursive():
750
relpath = urllib.unquote(quoted_relpath)
751
path, ext = os.path.splitext(relpath)
754
if not relpath.endswith('.sig'):
756
relpaths.add(relpath[:-4])
757
paths = list(relpaths)
758
return set([self._mapper.unmap(path) for path in paths])
761
class InterWeaveRepo(InterSameDataRepository):
762
"""Optimised code paths between Weave based repositories.
766
def _get_repo_format_to_test(self):
767
return RepositoryFormat7()
770
def is_compatible(source, target):
771
"""Be compatible with known Weave formats.
773
We don't test for the stores being of specific types because that
774
could lead to confusing results, and there is no need to be
778
return (isinstance(source._format, (RepositoryFormat5,
780
RepositoryFormat7)) and
781
isinstance(target._format, (RepositoryFormat5,
784
except AttributeError:
788
def copy_content(self, revision_id=None):
789
"""See InterRepository.copy_content()."""
790
# weave specific optimised path:
792
self.target.set_make_working_trees(self.source.make_working_trees())
793
except (errors.RepositoryUpgradeRequired, NotImplemented):
796
if self.source._transport.listable():
797
pb = ui.ui_factory.nested_progress_bar()
799
self.target.texts.insert_record_stream(
800
self.source.texts.get_record_stream(
801
self.source.texts.keys(), 'topological', False))
802
pb.update('Copying inventory', 0, 1)
803
self.target.inventories.insert_record_stream(
804
self.source.inventories.get_record_stream(
805
self.source.inventories.keys(), 'topological', False))
806
self.target.signatures.insert_record_stream(
807
self.source.signatures.get_record_stream(
808
self.source.signatures.keys(),
810
self.target.revisions.insert_record_stream(
811
self.source.revisions.get_record_stream(
812
self.source.revisions.keys(),
813
'topological', True))
817
self.target.fetch(self.source, revision_id=revision_id)
820
def search_missing_revision_ids(self,
821
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
822
find_ghosts=True, revision_ids=None, if_present_ids=None,
824
"""See InterRepository.search_missing_revision_ids()."""
825
# we want all revisions to satisfy revision_id in source.
826
# but we don't want to stat every file here and there.
827
# we want then, all revisions other needs to satisfy revision_id
828
# checked, but not those that we have locally.
829
# so the first thing is to get a subset of the revisions to
830
# satisfy revision_id in source, and then eliminate those that
831
# we do already have.
832
# this is slow on high latency connection to self, but as this
833
# disk format scales terribly for push anyway due to rewriting
834
# inventory.weave, this is considered acceptable.
836
if symbol_versioning.deprecated_passed(revision_id):
837
symbol_versioning.warn(
838
'search_missing_revision_ids(revision_id=...) was '
839
'deprecated in 2.4. Use revision_ids=[...] instead.',
840
DeprecationWarning, stacklevel=2)
841
if revision_ids is not None:
842
raise AssertionError(
843
'revision_ids is mutually exclusive with revision_id')
844
if revision_id is not None:
845
revision_ids = [revision_id]
847
source_ids_set = self._present_source_revisions_for(
848
revision_ids, if_present_ids)
849
# source_ids is the worst possible case we may need to pull.
850
# now we want to filter source_ids against what we actually
851
# have in target, but don't try to check for existence where we know
852
# we do not have a revision as that would be pointless.
853
target_ids = set(self.target._all_possible_ids())
854
possibly_present_revisions = target_ids.intersection(source_ids_set)
855
actually_present_revisions = set(
856
self.target._eliminate_revisions_not_present(possibly_present_revisions))
857
required_revisions = source_ids_set.difference(actually_present_revisions)
858
if revision_ids is not None:
859
# we used get_ancestry to determine source_ids then we are assured all
860
# revisions referenced are present as they are installed in topological order.
861
# and the tip revision was validated by get_ancestry.
862
result_set = required_revisions
864
# if we just grabbed the possibly available ids, then
865
# we only have an estimate of whats available and need to validate
866
# that against the revision records.
868
self.source._eliminate_revisions_not_present(required_revisions))
869
if limit is not None:
870
topo_ordered = self.get_graph().iter_topo_order(result_set)
871
result_set = set(itertools.islice(topo_ordered, limit))
872
return self.source.revision_ids_to_search_result(result_set)
875
InterRepository.register_optimiser(InterWeaveRepo)
878
def get_extra_interrepo_test_combinations():
879
from bzrlib.repofmt import knitrepo
880
return [(InterRepository, RepositoryFormat5(),
881
knitrepo.RepositoryFormatKnit3())]
394
text_store = self._get_text_store(repo_transport, control_files)
395
control_store = self._get_control_store(repo_transport, control_files)
396
_revision_store = self._get_revision_store(repo_transport, control_files)
397
return WeaveMetaDirRepository(_format=self,
399
control_files=control_files,
400
_revision_store=_revision_store,
401
control_store=control_store,
402
text_store=text_store)
405
_legacy_formats = [RepositoryFormat4(),