~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: John Arbash Meinel
  • Date: 2008-09-09 15:09:12 UTC
  • mto: This revision was merged to the branch mainline in revision 3699.
  • Revision ID: john@arbash-meinel.com-20080909150912-wyttm8he1zsls2ck
Use the right timing function on win32

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Deprecated weave-based repository formats.
18
18
 
20
20
ghosts.
21
21
"""
22
22
 
23
 
import gzip
24
23
import os
25
24
from cStringIO import StringIO
26
25
import urllib
27
26
 
28
 
from bzrlib.lazy_import import lazy_import
29
 
lazy_import(globals(), """
30
 
import itertools
31
 
 
32
 
from bzrlib import (
33
 
    xml5,
34
 
    graph as _mod_graph,
35
 
    ui,
36
 
    )
37
 
""")
38
 
from bzrlib import (
 
27
from bzrlib import (
 
28
    bzrdir,
39
29
    debug,
40
30
    errors,
41
31
    lockable_files,
42
32
    lockdir,
43
33
    osutils,
44
 
    symbol_versioning,
45
 
    trace,
46
 
    tuned_gzip,
47
 
    urlutils,
 
34
    revision as _mod_revision,
48
35
    versionedfile,
49
36
    weave,
50
37
    weavefile,
 
38
    xml5,
51
39
    )
52
40
from bzrlib.decorators import needs_read_lock, needs_write_lock
53
41
from bzrlib.repository import (
54
 
    InterRepository,
 
42
    CommitBuilder,
 
43
    MetaDirVersionedFileRepository,
 
44
    MetaDirRepositoryFormat,
 
45
    Repository,
55
46
    RepositoryFormat,
56
47
    )
57
48
from bzrlib.store.text import TextStore
 
49
from bzrlib.trace import mutter
 
50
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
58
51
from bzrlib.versionedfile import (
59
52
    AbsentContentFactory,
60
53
    FulltextContentFactory,
61
54
    VersionedFiles,
62
55
    )
63
 
from bzrlib.vf_repository import (
64
 
    InterSameDataRepository,
65
 
    VersionedFileCommitBuilder,
66
 
    VersionedFileRepository,
67
 
    VersionedFileRepositoryFormat,
68
 
    MetaDirVersionedFileRepository,
69
 
    MetaDirVersionedFileRepositoryFormat,
70
 
    )
71
 
 
72
 
from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
73
 
 
74
 
 
75
 
class AllInOneRepository(VersionedFileRepository):
 
56
 
 
57
 
 
58
class AllInOneRepository(Repository):
76
59
    """Legacy support - the repository behaviour for all-in-one branches."""
77
60
 
78
 
    @property
79
 
    def _serializer(self):
80
 
        return xml5.serializer_v5
81
 
 
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 == '':
86
 
            return u''
87
 
        return urlutils.escape(osutils.safe_unicode(file_or_path))
 
61
    _serializer = xml5.serializer_v5
88
62
 
89
63
    def __init__(self, _format, a_bzrdir):
90
64
        # we reuse one control files instance.
93
67
 
94
68
        def get_store(name, compressed=True, prefixed=False):
95
69
            # 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
 
70
            # or entirely uncompressed is tidy, but breaks upgrade from 
 
71
            # some existing branches where there's a mixture; we probably 
98
72
            # still want the option to look for both.
99
 
            relpath = self._escape(name)
 
73
            relpath = a_bzrdir._control_files._escape(name)
100
74
            store = TextStore(a_bzrdir.transport.clone(relpath),
101
75
                              prefixed=prefixed, compressed=compressed,
102
76
                              dir_mode=dir_mode,
106
80
        # not broken out yet because the controlweaves|inventory_store
107
81
        # and texts bits are still different.
108
82
        if isinstance(_format, RepositoryFormat4):
109
 
            # cannot remove these - there is still no consistent api
 
83
            # cannot remove these - there is still no consistent api 
110
84
            # which allows access to this old info.
111
85
            self.inventory_store = get_store('inventory-store')
112
86
            self._text_store = get_store('text-store')
113
87
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
 
88
        self._fetch_order = 'topological'
 
89
        self._fetch_reconcile = True
114
90
 
115
91
    @needs_read_lock
116
92
    def _all_possible_ids(self):
117
93
        """Return all the possible revisions that we could find."""
118
94
        if 'evil' in debug.debug_flags:
119
 
            trace.mutter_callsite(
120
 
                3, "_all_possible_ids scales with size of history.")
 
95
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
121
96
        return [key[-1] for key in self.inventories.keys()]
122
97
 
123
98
    @needs_read_lock
124
99
    def _all_revision_ids(self):
125
 
        """Returns a list of all the revision ids in the repository.
 
100
        """Returns a list of all the revision ids in the repository. 
126
101
 
127
 
        These are in as much topological order as the underlying store can
 
102
        These are in as much topological order as the underlying store can 
128
103
        present: for weaves ghosts may lead to a lack of correctness until
129
104
        the reweave updates the parents list.
130
105
        """
150
125
 
151
126
    def get_commit_builder(self, branch, parents, config, timestamp=None,
152
127
                           timezone=None, committer=None, revprops=None,
153
 
                           revision_id=None, lossy=False):
 
128
                           revision_id=None):
154
129
        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)
 
130
        result = CommitBuilder(self, parents, config, timestamp, timezone,
 
131
                              committer, revprops, revision_id)
157
132
        self.start_write_group()
158
133
        return result
159
134
 
187
162
        :param new_value: True to restore the default, False to disable making
188
163
                          working trees.
189
164
        """
190
 
        raise errors.RepositoryUpgradeRequired(self.user_url)
 
165
        raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
191
166
 
192
167
    def make_working_trees(self):
193
168
        """Returns the policy for making working trees on new branches."""
194
169
        return True
195
170
 
 
171
    def revision_graph_can_have_wrong_parents(self):
 
172
        # XXX: This is an old format that we don't support full checking on, so
 
173
        # just claim that checking for this inconsistency is not required.
 
174
        return False
 
175
 
196
176
 
197
177
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
198
178
    """A subclass of MetaDirRepository to set weave specific policy."""
199
179
 
 
180
    _serializer = xml5.serializer_v5
 
181
 
200
182
    def __init__(self, _format, a_bzrdir, control_files):
201
183
        super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
202
 
        self._serializer = _format._serializer
 
184
        self._fetch_order = 'topological'
 
185
        self._fetch_reconcile = True
203
186
 
204
187
    @needs_read_lock
205
188
    def _all_possible_ids(self):
206
189
        """Return all the possible revisions that we could find."""
207
190
        if 'evil' in debug.debug_flags:
208
 
            trace.mutter_callsite(
209
 
                3, "_all_possible_ids scales with size of history.")
 
191
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
210
192
        return [key[-1] for key in self.inventories.keys()]
211
193
 
212
194
    @needs_read_lock
213
195
    def _all_revision_ids(self):
214
 
        """Returns a list of all the revision ids in the repository.
 
196
        """Returns a list of all the revision ids in the repository. 
215
197
 
216
 
        These are in as much topological order as the underlying store can
 
198
        These are in as much topological order as the underlying store can 
217
199
        present: for weaves ghosts may lead to a lack of correctness until
218
200
        the reweave updates the parents list.
219
201
        """
239
221
 
240
222
    def get_commit_builder(self, branch, parents, config, timestamp=None,
241
223
                           timezone=None, committer=None, revprops=None,
242
 
                           revision_id=None, lossy=False):
 
224
                           revision_id=None):
243
225
        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)
 
226
        result = CommitBuilder(self, parents, config, timestamp, timezone,
 
227
                              committer, revprops, revision_id)
246
228
        self.start_write_group()
247
229
        return result
248
230
 
263
245
        return self.inventories.add_lines((revision_id,), final_parents, lines,
264
246
            check_content=check_content)[0]
265
247
 
266
 
 
267
 
class PreSplitOutRepositoryFormat(VersionedFileRepositoryFormat):
 
248
    def revision_graph_can_have_wrong_parents(self):
 
249
        return False
 
250
 
 
251
 
 
252
class PreSplitOutRepositoryFormat(RepositoryFormat):
268
253
    """Base class for the pre split out repository formats."""
269
254
 
270
255
    rich_root_data = False
271
256
    supports_tree_reference = False
272
257
    supports_ghosts = False
273
258
    supports_external_lookups = False
274
 
    supports_chks = False
275
 
    supports_nesting_repositories = True
276
 
    _fetch_order = 'topological'
277
 
    _fetch_reconcile = True
278
 
    fast_deltas = False
279
 
    supports_leaving_lock = False
280
 
    # XXX: This is an old format that we don't support full checking on, so
281
 
    # just claim that checking for this inconsistency is not required.
282
 
    revision_graph_can_have_wrong_parents = False
283
259
 
284
260
    def initialize(self, a_bzrdir, shared=False, _internal=False):
285
261
        """Create a weave repository."""
289
265
        if not _internal:
290
266
            # always initialized when the bzrdir is.
291
267
            return self.open(a_bzrdir, _found=True)
292
 
 
 
268
        
293
269
        # Create an empty weave
294
270
        sio = StringIO()
295
271
        weavefile.write_weave_v5(weave.Weave(), sio)
296
272
        empty_weave = sio.getvalue()
297
273
 
298
 
        trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
299
 
 
 
274
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
275
        
300
276
        # FIXME: RBC 20060125 don't peek under the covers
301
277
        # NB: no need to escape relative paths that are url safe.
302
278
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
307
283
        try:
308
284
            transport.mkdir_multi(['revision-store', 'weaves'],
309
285
                mode=a_bzrdir._get_dir_mode())
310
 
            transport.put_bytes_non_atomic('inventory.weave', empty_weave,
311
 
                mode=a_bzrdir._get_file_mode())
 
286
            transport.put_bytes_non_atomic('inventory.weave', empty_weave)
312
287
        finally:
313
288
            control_files.unlock()
314
 
        repository = self.open(a_bzrdir, _found=True)
315
 
        self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
316
 
        return repository
 
289
        return self.open(a_bzrdir, _found=True)
317
290
 
318
291
    def open(self, a_bzrdir, _found=False):
319
292
        """See RepositoryFormat.open()."""
328
301
        result.signatures = self._get_signatures(repo_transport, result)
329
302
        result.inventories = self._get_inventories(repo_transport, result)
330
303
        result.texts = self._get_texts(repo_transport, result)
331
 
        result.chk_bytes = None
332
304
        return result
333
305
 
334
 
    def is_deprecated(self):
335
 
        return True
 
306
    def check_conversion_target(self, target_format):
 
307
        pass
336
308
 
337
309
 
338
310
class RepositoryFormat4(PreSplitOutRepositoryFormat):
347
319
    has been removed.
348
320
    """
349
321
 
350
 
    supports_funky_characters = False
 
322
    _matchingbzrdir = bzrdir.BzrDirFormat4()
351
323
 
352
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat4()
 
324
    def __init__(self):
 
325
        super(RepositoryFormat4, self).__init__()
 
326
        self._fetch_order = 'topological'
 
327
        self._fetch_reconcile = True
353
328
 
354
329
    def get_format_description(self):
355
330
        """See RepositoryFormat.get_format_description()."""
363
338
        """Format 4 is not supported.
364
339
 
365
340
        It is not supported because the model changed from 4 to 5 and the
366
 
        conversion logic is expensive - so doing it on the fly was not
 
341
        conversion logic is expensive - so doing it on the fly was not 
367
342
        feasible.
368
343
        """
369
344
        return False
373
348
        return None
374
349
 
375
350
    def _get_revisions(self, repo_transport, repo):
376
 
        from bzrlib.plugins.weave_fmt.xml4 import serializer_v4
 
351
        from bzrlib.xml4 import serializer_v4
377
352
        return RevisionTextStore(repo_transport.clone('revision-store'),
378
353
            serializer_v4, True, versionedfile.PrefixMapper(),
379
354
            repo.is_locked, repo.is_write_locked)
397
372
    """
398
373
 
399
374
    _versionedfile_class = weave.WeaveFile
400
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat5()
401
 
    supports_funky_characters = False
 
375
    _matchingbzrdir = bzrdir.BzrDirFormat5()
402
376
 
403
 
    @property
404
 
    def _serializer(self):
405
 
        return xml5.serializer_v5
 
377
    def __init__(self):
 
378
        super(RepositoryFormat5, self).__init__()
 
379
        self._fetch_order = 'topological'
 
380
        self._fetch_reconcile = True
406
381
 
407
382
    def get_format_description(self):
408
383
        """See RepositoryFormat.get_format_description()."""
409
384
        return "Weave repository format 5"
410
385
 
411
 
    def network_name(self):
412
 
        """The network name for this format is the control dirs disk label."""
413
 
        return self._matchingbzrdir.get_format_string()
414
 
 
415
386
    def _get_inventories(self, repo_transport, repo, name='inventory'):
416
387
        mapper = versionedfile.ConstantMapper(name)
417
388
        return versionedfile.ThunkedVersionedFiles(repo_transport,
418
389
            weave.WeaveFile, mapper, repo.is_locked)
419
390
 
420
391
    def _get_revisions(self, repo_transport, repo):
 
392
        from bzrlib.xml5 import serializer_v5
421
393
        return RevisionTextStore(repo_transport.clone('revision-store'),
422
 
            xml5.serializer_v5, False, versionedfile.PrefixMapper(),
 
394
            serializer_v5, False, versionedfile.PrefixMapper(),
423
395
            repo.is_locked, repo.is_write_locked)
424
396
 
425
397
    def _get_signatures(self, repo_transport, repo):
444
416
    """
445
417
 
446
418
    _versionedfile_class = weave.WeaveFile
447
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat6()
448
 
    supports_funky_characters = False
449
 
    @property
450
 
    def _serializer(self):
451
 
        return xml5.serializer_v5
 
419
    _matchingbzrdir = bzrdir.BzrDirFormat6()
 
420
 
 
421
    def __init__(self):
 
422
        super(RepositoryFormat6, self).__init__()
 
423
        self._fetch_order = 'topological'
 
424
        self._fetch_reconcile = True
452
425
 
453
426
    def get_format_description(self):
454
427
        """See RepositoryFormat.get_format_description()."""
455
428
        return "Weave repository format 6"
456
429
 
457
 
    def network_name(self):
458
 
        """The network name for this format is the control dirs disk label."""
459
 
        return self._matchingbzrdir.get_format_string()
460
 
 
461
430
    def _get_inventories(self, repo_transport, repo, name='inventory'):
462
431
        mapper = versionedfile.ConstantMapper(name)
463
432
        return versionedfile.ThunkedVersionedFiles(repo_transport,
464
433
            weave.WeaveFile, mapper, repo.is_locked)
465
434
 
466
435
    def _get_revisions(self, repo_transport, repo):
 
436
        from bzrlib.xml5 import serializer_v5
467
437
        return RevisionTextStore(repo_transport.clone('revision-store'),
468
 
            xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
 
438
            serializer_v5, False, versionedfile.HashPrefixMapper(),
469
439
            repo.is_locked, repo.is_write_locked)
470
440
 
471
441
    def _get_signatures(self, repo_transport, repo):
480
450
            weave.WeaveFile, mapper, repo.is_locked)
481
451
 
482
452
 
483
 
class RepositoryFormat7(MetaDirVersionedFileRepositoryFormat):
 
453
class RepositoryFormat7(MetaDirRepositoryFormat):
484
454
    """Bzr repository 7.
485
455
 
486
456
    This repository format has:
494
464
 
495
465
    _versionedfile_class = weave.WeaveFile
496
466
    supports_ghosts = False
497
 
    supports_chks = False
498
 
    supports_funky_characters = False
499
 
    revision_graph_can_have_wrong_parents = False
500
 
 
501
 
    _fetch_order = 'topological'
502
 
    _fetch_reconcile = True
503
 
    fast_deltas = False
504
 
    @property
505
 
    def _serializer(self):
506
 
        return xml5.serializer_v5
507
467
 
508
468
    def get_format_string(self):
509
469
        """See RepositoryFormat.get_format_string()."""
513
473
        """See RepositoryFormat.get_format_description()."""
514
474
        return "Weave repository format 7"
515
475
 
 
476
    def check_conversion_target(self, target_format):
 
477
        pass
 
478
 
516
479
    def _get_inventories(self, repo_transport, repo, name='inventory'):
517
480
        mapper = versionedfile.ConstantMapper(name)
518
481
        return versionedfile.ThunkedVersionedFiles(repo_transport,
519
482
            weave.WeaveFile, mapper, repo.is_locked)
520
483
 
521
484
    def _get_revisions(self, repo_transport, repo):
 
485
        from bzrlib.xml5 import serializer_v5
522
486
        return RevisionTextStore(repo_transport.clone('revision-store'),
523
 
            xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
 
487
            serializer_v5, True, versionedfile.HashPrefixMapper(),
524
488
            repo.is_locked, repo.is_write_locked)
525
489
 
526
490
    def _get_signatures(self, repo_transport, repo):
545
509
        weavefile.write_weave_v5(weave.Weave(), sio)
546
510
        empty_weave = sio.getvalue()
547
511
 
548
 
        trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
 
512
        mutter('creating repository in %s.', a_bzrdir.transport.base)
549
513
        dirs = ['revision-store', 'weaves']
550
 
        files = [('inventory.weave', StringIO(empty_weave)),
 
514
        files = [('inventory.weave', StringIO(empty_weave)), 
551
515
                 ]
552
516
        utf8_files = [('format', self.get_format_string())]
553
 
 
 
517
 
554
518
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
555
519
        return self.open(a_bzrdir=a_bzrdir, _found=True)
556
520
 
557
521
    def open(self, a_bzrdir, _found=False, _override_transport=None):
558
522
        """See RepositoryFormat.open().
559
 
 
 
523
        
560
524
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
561
525
                                    repository at a slightly different url
562
526
                                    than normal. I.e. during 'upgrade'.
575
539
        result.signatures = self._get_signatures(repo_transport, result)
576
540
        result.inventories = self._get_inventories(repo_transport, result)
577
541
        result.texts = self._get_texts(repo_transport, result)
578
 
        result.chk_bytes = None
579
542
        result._transport = repo_transport
580
543
        return result
581
544
 
582
 
    def is_deprecated(self):
583
 
        return True
584
 
 
585
545
 
586
546
class TextVersionedFiles(VersionedFiles):
587
547
    """Just-a-bunch-of-files based VersionedFile stores."""
607
567
            raise ValueError('bad idea to put / in %r' % (key,))
608
568
        text = ''.join(lines)
609
569
        if self._compressed:
610
 
            text = tuned_gzip.bytes_to_gzip(text)
 
570
            text = bytes_to_gzip(text)
611
571
        path = self._map(key)
612
572
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
613
573
 
633
593
                    record, record.get_bytes_as(record.storage_kind)))
634
594
                try:
635
595
                    self.add_lines(record.key, None, lines)
636
 
                except errors.RevisionAlreadyPresent:
 
596
                except RevisionAlreadyPresent:
637
597
                    pass
638
598
 
639
599
    def _load_text(self, key):
655
615
            else:
656
616
                return None
657
617
        if compressed:
658
 
            text = gzip.GzipFile(mode='rb', fileobj=StringIO(text)).read()
 
618
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
659
619
        return text
660
620
 
661
621
    def _map(self, key):
687
647
                continue
688
648
            result[key] = parents
689
649
        return result
690
 
 
691
 
    def get_known_graph_ancestry(self, keys):
692
 
        """Get a KnownGraph instance with the ancestry of keys."""
693
 
        keys = self.keys()
694
 
        parent_map = self.get_parent_map(keys)
695
 
        kg = _mod_graph.KnownGraph(parent_map)
696
 
        return kg
697
 
 
 
650
    
698
651
    def get_record_stream(self, keys, sort_order, include_delta_closure):
699
652
        for key in keys:
700
653
            text, parents = self._load_text_parents(key)
712
665
            path, ext = os.path.splitext(relpath)
713
666
            if ext == '.gz':
714
667
                relpath = path
715
 
            if not relpath.endswith('.sig'):
 
668
            if '.sig' not in relpath:
716
669
                relpaths.add(relpath)
717
670
        paths = list(relpaths)
718
671
        return set([self._mapper.unmap(path) for path in paths])
734
687
                continue
735
688
            result[key] = None
736
689
        return result
737
 
 
 
690
    
738
691
    def get_record_stream(self, keys, sort_order, include_delta_closure):
739
692
        for key in keys:
740
693
            text = self._load_text(key)
758
711
        paths = list(relpaths)
759
712
        return set([self._mapper.unmap(path) for path in paths])
760
713
 
761
 
 
762
 
class InterWeaveRepo(InterSameDataRepository):
763
 
    """Optimised code paths between Weave based repositories.
764
 
    """
765
 
 
766
 
    @classmethod
767
 
    def _get_repo_format_to_test(self):
768
 
        return RepositoryFormat7()
769
 
 
770
 
    @staticmethod
771
 
    def is_compatible(source, target):
772
 
        """Be compatible with known Weave formats.
773
 
 
774
 
        We don't test for the stores being of specific types because that
775
 
        could lead to confusing results, and there is no need to be
776
 
        overly general.
777
 
        """
778
 
        try:
779
 
            return (isinstance(source._format, (RepositoryFormat5,
780
 
                                                RepositoryFormat6,
781
 
                                                RepositoryFormat7)) and
782
 
                    isinstance(target._format, (RepositoryFormat5,
783
 
                                                RepositoryFormat6,
784
 
                                                RepositoryFormat7)))
785
 
        except AttributeError:
786
 
            return False
787
 
 
788
 
    @needs_write_lock
789
 
    def copy_content(self, revision_id=None):
790
 
        """See InterRepository.copy_content()."""
791
 
        # weave specific optimised path:
792
 
        try:
793
 
            self.target.set_make_working_trees(self.source.make_working_trees())
794
 
        except (errors.RepositoryUpgradeRequired, NotImplemented):
795
 
            pass
796
 
        # FIXME do not peek!
797
 
        if self.source._transport.listable():
798
 
            pb = ui.ui_factory.nested_progress_bar()
799
 
            try:
800
 
                self.target.texts.insert_record_stream(
801
 
                    self.source.texts.get_record_stream(
802
 
                        self.source.texts.keys(), 'topological', False))
803
 
                pb.update('Copying inventory', 0, 1)
804
 
                self.target.inventories.insert_record_stream(
805
 
                    self.source.inventories.get_record_stream(
806
 
                        self.source.inventories.keys(), 'topological', False))
807
 
                self.target.signatures.insert_record_stream(
808
 
                    self.source.signatures.get_record_stream(
809
 
                        self.source.signatures.keys(),
810
 
                        'unordered', True))
811
 
                self.target.revisions.insert_record_stream(
812
 
                    self.source.revisions.get_record_stream(
813
 
                        self.source.revisions.keys(),
814
 
                        'topological', True))
815
 
            finally:
816
 
                pb.finished()
817
 
        else:
818
 
            self.target.fetch(self.source, revision_id=revision_id)
819
 
 
820
 
    @needs_read_lock
821
 
    def search_missing_revision_ids(self,
822
 
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
823
 
            find_ghosts=True, revision_ids=None, if_present_ids=None,
824
 
            limit=None):
825
 
        """See InterRepository.search_missing_revision_ids()."""
826
 
        # we want all revisions to satisfy revision_id in source.
827
 
        # but we don't want to stat every file here and there.
828
 
        # we want then, all revisions other needs to satisfy revision_id
829
 
        # checked, but not those that we have locally.
830
 
        # so the first thing is to get a subset of the revisions to
831
 
        # satisfy revision_id in source, and then eliminate those that
832
 
        # we do already have.
833
 
        # this is slow on high latency connection to self, but as this
834
 
        # disk format scales terribly for push anyway due to rewriting
835
 
        # inventory.weave, this is considered acceptable.
836
 
        # - RBC 20060209
837
 
        if symbol_versioning.deprecated_passed(revision_id):
838
 
            symbol_versioning.warn(
839
 
                'search_missing_revision_ids(revision_id=...) was '
840
 
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
841
 
                DeprecationWarning, stacklevel=2)
842
 
            if revision_ids is not None:
843
 
                raise AssertionError(
844
 
                    'revision_ids is mutually exclusive with revision_id')
845
 
            if revision_id is not None:
846
 
                revision_ids = [revision_id]
847
 
        del revision_id
848
 
        source_ids_set = self._present_source_revisions_for(
849
 
            revision_ids, if_present_ids)
850
 
        # source_ids is the worst possible case we may need to pull.
851
 
        # now we want to filter source_ids against what we actually
852
 
        # have in target, but don't try to check for existence where we know
853
 
        # we do not have a revision as that would be pointless.
854
 
        target_ids = set(self.target._all_possible_ids())
855
 
        possibly_present_revisions = target_ids.intersection(source_ids_set)
856
 
        actually_present_revisions = set(
857
 
            self.target._eliminate_revisions_not_present(possibly_present_revisions))
858
 
        required_revisions = source_ids_set.difference(actually_present_revisions)
859
 
        if revision_ids is not None:
860
 
            # we used get_ancestry to determine source_ids then we are assured all
861
 
            # revisions referenced are present as they are installed in topological order.
862
 
            # and the tip revision was validated by get_ancestry.
863
 
            result_set = required_revisions
864
 
        else:
865
 
            # if we just grabbed the possibly available ids, then
866
 
            # we only have an estimate of whats available and need to validate
867
 
            # that against the revision records.
868
 
            result_set = set(
869
 
                self.source._eliminate_revisions_not_present(required_revisions))
870
 
        if limit is not None:
871
 
            topo_ordered = self.get_graph().iter_topo_order(result_set)
872
 
            result_set = set(itertools.islice(topo_ordered, limit))
873
 
        return self.source.revision_ids_to_search_result(result_set)
874
 
 
875
 
 
876
 
InterRepository.register_optimiser(InterWeaveRepo)
877
 
 
878
 
 
879
 
def get_extra_interrepo_test_combinations():
880
 
    from bzrlib.repofmt import knitrepo
881
 
    return [(InterRepository, RepositoryFormat5(),
882
 
        knitrepo.RepositoryFormatKnit3())]
 
714
_legacy_formats = [RepositoryFormat4(),
 
715
                   RepositoryFormat5(),
 
716
                   RepositoryFormat6()]