/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bundle/serializer/v4.py

  • Committer: Jelmer Vernooij
  • Date: 2017-11-21 20:14:44 UTC
  • mfrom: (6821.1.1 ignore-warnings)
  • Revision ID: jelmer@jelmer.uk-20171121201444-dvb7yjku3zwjev83
Merge lp:~jelmer/brz/ignore-warnings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2007-2010 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
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from cStringIO import StringIO
 
17
from __future__ import absolute_import
 
18
 
18
19
import bz2
19
20
import re
20
21
 
21
 
from bzrlib import (
22
 
    diff,
 
22
from ... import (
 
23
    bencode,
23
24
    errors,
24
25
    iterablefile,
25
26
    lru_cache,
26
27
    multiparent,
27
28
    osutils,
28
 
    pack,
29
29
    revision as _mod_revision,
30
 
    serializer,
31
30
    trace,
32
31
    ui,
33
32
    )
34
 
from bzrlib.bundle import bundle_data, serializer as bundle_serializer
35
 
from bzrlib import bencode
 
33
from ...bzr import (
 
34
    pack,
 
35
    serializer,
 
36
    versionedfile as _mod_versionedfile,
 
37
    )
 
38
from ...bundle import bundle_data, serializer as bundle_serializer
 
39
from ...i18n import ngettext
 
40
from ...sixish import (
 
41
    BytesIO,
 
42
    viewitems,
 
43
    )
 
44
 
 
45
 
 
46
class _MPDiffInventoryGenerator(_mod_versionedfile._MPDiffGenerator):
 
47
    """Generate Inventory diffs serialized inventories."""
 
48
 
 
49
    def __init__(self, repo, inventory_keys):
 
50
        super(_MPDiffInventoryGenerator, self).__init__(repo.inventories,
 
51
            inventory_keys)
 
52
        self.repo = repo
 
53
        self.sha1s = {}
 
54
 
 
55
    def iter_diffs(self):
 
56
        """Compute the diffs one at a time."""
 
57
        # This is instead of compute_diffs() since we guarantee our ordering of
 
58
        # inventories, we don't have to do any buffering
 
59
        self._find_needed_keys()
 
60
        # We actually use a slightly different ordering. We grab all of the
 
61
        # parents first, and then grab the ordered requests.
 
62
        needed_ids = [k[-1] for k in self.present_parents]
 
63
        needed_ids.extend([k[-1] for k in self.ordered_keys])
 
64
        inv_to_str = self.repo._serializer.write_inventory_to_string
 
65
        for inv in self.repo.iter_inventories(needed_ids):
 
66
            revision_id = inv.revision_id
 
67
            key = (revision_id,)
 
68
            if key in self.present_parents:
 
69
                # Not a key we will transmit, which is a shame, since because
 
70
                # of that bundles don't work with stacked branches
 
71
                parent_ids = None
 
72
            else:
 
73
                parent_ids = [k[-1] for k in self.parent_map[key]]
 
74
            as_bytes = inv_to_str(inv)
 
75
            self._process_one_record(key, (as_bytes,))
 
76
            if parent_ids is None:
 
77
                continue
 
78
            diff = self.diffs.pop(key)
 
79
            sha1 = osutils.sha_string(as_bytes)
 
80
            yield revision_id, parent_ids, sha1, diff
36
81
 
37
82
 
38
83
class BundleWriter(object):
164
209
        if stream_input:
165
210
            source_file = iterablefile.IterableFile(self.iter_decode(fileobj))
166
211
        else:
167
 
            source_file = StringIO(bz2.decompress(fileobj.read()))
 
212
            source_file = BytesIO(bz2.decompress(fileobj.read()))
168
213
        self._container_file = source_file
169
214
 
170
215
    @staticmethod
216
261
            if metadata['storage_kind'] == 'header':
217
262
                bytes = None
218
263
            else:
219
 
                _unused, bytes = iterator.next()
 
264
                _unused, bytes = next(iterator)
220
265
            yield (bytes, metadata) + self.decode_name(names[0][0])
221
266
 
222
267
 
280
325
            # Strip ghosts
281
326
            parents = graph.get_parent_map(revision_ids)
282
327
            self.revision_ids = [r for r in revision_ids if r in parents]
283
 
        self.revision_keys = set([(revid,) for revid in self.revision_ids])
 
328
        self.revision_keys = {(revid,) for revid in self.revision_ids}
284
329
 
285
330
    def do_write(self):
286
331
        """Write all data to the bundle"""
287
 
        trace.note('Bundling %d revision(s).', len(self.revision_ids))
288
 
        self.repository.lock_read()
289
 
        try:
 
332
        trace.note(ngettext('Bundling %d revision.', 'Bundling %d revisions.',
 
333
                            len(self.revision_ids)), len(self.revision_ids))
 
334
        with self.repository.lock_read():
290
335
            self.bundle.begin()
291
336
            self.write_info()
292
337
            self.write_files()
293
338
            self.write_revisions()
294
339
            self.bundle.end()
295
 
        finally:
296
 
            self.repository.unlock()
297
340
        return self.revision_ids
298
341
 
299
342
    def write_info(self):
309
352
        text_keys = []
310
353
        altered_fileids = self.repository.fileids_altered_by_revision_ids(
311
354
                self.revision_ids)
312
 
        for file_id, revision_ids in altered_fileids.iteritems():
 
355
        for file_id, revision_ids in viewitems(altered_fileids):
313
356
            for revision_id in revision_ids:
314
357
                text_keys.append((file_id, revision_id))
315
358
        self._add_mp_records_keys('file', self.repository.texts, text_keys)
348
391
        the other side.
349
392
        """
350
393
        inventory_key_order = [(r,) for r in revision_order]
351
 
        parent_map = self.repository.inventories.get_parent_map(
352
 
                            inventory_key_order)
353
 
        missing_keys = set(inventory_key_order).difference(parent_map)
354
 
        if missing_keys:
355
 
            raise errors.RevisionNotPresent(list(missing_keys)[0],
356
 
                                            self.repository.inventories)
357
 
        inv_to_str = self.repository._serializer.write_inventory_to_string
358
 
        # Make sure that we grab the parent texts first
359
 
        just_parents = set()
360
 
        map(just_parents.update, parent_map.itervalues())
361
 
        just_parents.difference_update(parent_map)
362
 
        # Ignore ghost parents
363
 
        present_parents = self.repository.inventories.get_parent_map(
364
 
                            just_parents)
365
 
        ghost_keys = just_parents.difference(present_parents)
366
 
        needed_inventories = list(present_parents) + inventory_key_order
367
 
        needed_inventories = [k[-1] for k in needed_inventories]
368
 
        all_lines = {}
369
 
        for inv in self.repository.iter_inventories(needed_inventories):
370
 
            revision_id = inv.revision_id
371
 
            key = (revision_id,)
372
 
            as_bytes = inv_to_str(inv)
373
 
            # The sha1 is validated as the xml/textual form, not as the
374
 
            # form-in-the-repository
375
 
            sha1 = osutils.sha_string(as_bytes)
376
 
            as_lines = osutils.split_lines(as_bytes)
377
 
            del as_bytes
378
 
            all_lines[key] = as_lines
379
 
            if key in just_parents:
380
 
                # We don't transmit those entries
381
 
                continue
382
 
            # Create an mpdiff for this text, and add it to the output
383
 
            parent_keys = parent_map[key]
384
 
            # See the comment in VF.make_mpdiffs about how this effects
385
 
            # ordering when there are ghosts present. I think we have a latent
386
 
            # bug
387
 
            parent_lines = [all_lines[p_key] for p_key in parent_keys
388
 
                            if p_key not in ghost_keys]
389
 
            diff = multiparent.MultiParent.from_lines(
390
 
                as_lines, parent_lines)
 
394
        generator = _MPDiffInventoryGenerator(self.repository,
 
395
                                              inventory_key_order)
 
396
        for revision_id, parent_ids, sha1, diff in generator.iter_diffs():
391
397
            text = ''.join(diff.to_patch())
392
 
            parent_ids = [k[-1] for k in parent_keys]
393
398
            self.bundle.add_multiparent_record(text, sha1, parent_ids,
394
399
                                               'inventory', revision_id, None)
395
400