~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bundle/serializer/v08.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-11 00:23:23 UTC
  • mfrom: (2070 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061011002323-82ba88c293d7caff
[merge] bzr.dev 2070

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# (C) 2005 Canonical Development Ltd
 
1
# Copyright (C) 2005, 2006 by 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
19
19
 
20
20
import os
21
21
 
22
 
from bzrlib.bundle.serializer import (BundleSerializer, 
23
 
                                      BUNDLE_HEADER, 
 
22
from bzrlib import errors
 
23
from bzrlib.bundle.serializer import (BundleSerializer,
 
24
                                      BUNDLE_HEADER,
24
25
                                      format_highres_date,
25
26
                                      unpack_highres_date,
26
27
                                     )
27
28
from bzrlib.bundle.serializer import binary_diff
28
29
from bzrlib.bundle.bundle_data import (RevisionInfo, BundleInfo, BundleTree)
29
 
from bzrlib.delta import compare_trees
30
30
from bzrlib.diff import internal_diff
31
 
import bzrlib.errors as errors
32
31
from bzrlib.osutils import pathjoin
33
32
from bzrlib.progress import DummyProgress
34
33
from bzrlib.revision import NULL_REVISION
95
94
        """
96
95
        return BundleReader(f).info
97
96
 
 
97
    def check_compatible(self):
 
98
        if self.source.supports_rich_root():
 
99
            raise errors.IncompatibleFormat('0.8', repr(self.source))
 
100
 
98
101
    def write(self, source, revision_ids, forced_bases, f):
99
102
        """Write the bundless to the supplied files.
100
103
 
107
110
        self.revision_ids = revision_ids
108
111
        self.forced_bases = forced_bases
109
112
        self.to_file = f
 
113
        self.check_compatible()
110
114
        source.lock_read()
111
115
        try:
112
116
            self._write_main_header()
159
163
            if rev_id == last_rev_id:
160
164
                rev_tree = last_rev_tree
161
165
            else:
162
 
                base_tree = self.source.revision_tree(rev_id)
163
 
            rev_tree = self.source.revision_tree(rev_id)
 
166
                rev_tree = self.source.revision_tree(rev_id)
164
167
            if rev_id in self.forced_bases:
165
168
                explicit_base = True
166
169
                base_id = self.forced_bases[rev_id]
184
187
            last_rev_id = base_id
185
188
            last_rev_tree = base_tree
186
189
 
 
190
    def _testament_sha1(self, revision_id):
 
191
        return StrictTestament.from_revision(self.source, 
 
192
                                             revision_id).as_sha1()
 
193
 
187
194
    def _write_revision(self, rev, rev_tree, base_rev, base_tree, 
188
195
                        explicit_base, force_binary):
189
196
        """Write out the information for a revision."""
198
205
        self._write_delta(rev_tree, base_tree, rev.revision_id, force_binary)
199
206
 
200
207
        w('revision id', rev.revision_id)
201
 
        w('sha1', StrictTestament.from_revision(self.source, 
202
 
                                                rev.revision_id).as_sha1())
 
208
        w('sha1', self._testament_sha1(rev.revision_id))
203
209
        w('inventory sha1', rev.inventory_sha1)
204
210
        if rev.parent_ids:
205
211
            w('parent ids', rev.parent_ids)
269
275
            else:
270
276
                action.write(self.to_file)
271
277
 
272
 
        delta = compare_trees(old_tree, new_tree, want_unchanged=True)
 
278
        delta = new_tree.changes_from(old_tree, want_unchanged=True,
 
279
                                      include_root=True)
273
280
        for path, file_id, kind in delta.removed:
274
281
            action = Action('removed', [kind, path]).write(self.to_file)
275
282
 
318
325
        self.from_file = iter(from_file)
319
326
        self._next_line = None
320
327
        
321
 
        self.info = BundleInfo()
 
328
        self.info = self._get_info()
322
329
        # We put the actual inventory ids in the footer, so that the patch
323
330
        # is easier to read for humans.
324
331
        # Unfortunately, that means we need to read everything before we
326
333
        self._read()
327
334
        self._validate()
328
335
 
 
336
    def _get_info(self):
 
337
        return BundleInfo08()
 
338
 
329
339
    def _read(self):
330
340
        self._next().next()
331
341
        while self._next_line is not None:
367
377
            # which does not start with '#'
368
378
            if line is None or line == '\n':
369
379
                break
 
380
            if not line.startswith('#'):
 
381
                continue
370
382
            found_something = True
371
383
            self._handle_next(line)
372
384
        if not found_something:
378
390
        """Read in a key-value pair
379
391
        """
380
392
        if not line.startswith('#'):
381
 
            raise MalformedHeader('Bzr header did not start with #')
 
393
            raise errors.MalformedHeader('Bzr header did not start with #')
382
394
        line = line[1:-1].decode('utf-8') # Remove the '#' and '\n'
383
395
        if line[:indent] == ' '*indent:
384
396
            line = line[indent:]
395
407
            key = line[:-1]
396
408
            value = self._read_many(indent=indent+2)
397
409
        else:
398
 
            raise MalformedHeader('While looking for key: value pairs,'
 
410
            raise errors.MalformedHeader('While looking for key: value pairs,'
399
411
                    ' did not find the colon %r' % (line))
400
412
 
401
413
        key = key.replace(' ', '_')
411
423
            return
412
424
 
413
425
        revision_info = self.info.revisions[-1]
414
 
        if hasattr(revision_info, key):
 
426
        if key in revision_info.__dict__:
415
427
            if getattr(revision_info, key) is None:
416
428
                setattr(revision_info, key, value)
417
429
            else:
418
 
                raise MalformedHeader('Duplicated Key: %s' % key)
 
430
                raise errors.MalformedHeader('Duplicated Key: %s' % key)
419
431
        else:
420
432
            # What do we do with a key we don't recognize
421
 
            raise MalformedHeader('Unknown Key: "%s"' % key)
 
433
            raise errors.MalformedHeader('Unknown Key: "%s"' % key)
422
434
    
423
435
    def _read_many(self, indent):
424
436
        """If a line ends with no entry, that means that it should be
455
467
        for line in self._next():
456
468
            if first:
457
469
                if not line.startswith('==='):
458
 
                    raise MalformedPatches('The first line of all patches'
 
470
                    raise errors.MalformedPatches('The first line of all patches'
459
471
                        ' should be a bzr meta line "==="'
460
472
                        ': %r' % line)
461
473
                action = line[4:-1].decode('utf-8')
493
505
        """
494
506
        for line in self._next():
495
507
            self._handle_next(line)
 
508
            if self._next_line is None:
 
509
                break
496
510
            if not self._next_line.startswith('#'):
 
511
                # Consume the trailing \n and stop processing
497
512
                self._next().next()
498
513
                break
499
 
            if self._next_line is None:
500
 
                break
 
514
 
 
515
 
 
516
class BundleInfo08(BundleInfo):
 
517
 
 
518
    def _update_tree(self, bundle_tree, revision_id):
 
519
        bundle_tree.note_last_changed('', revision_id)
 
520
        BundleInfo._update_tree(self, bundle_tree, revision_id)
 
521
 
 
522
    def _testament_sha1_from_revision(self, repository, revision_id):
 
523
        testament = StrictTestament.from_revision(repository, revision_id)
 
524
        return testament.as_sha1()
 
525
 
 
526
    def _testament_sha1(self, revision, inventory):
 
527
        return StrictTestament(revision, inventory).as_sha1()