~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

Update to bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
# record content length ?
61
61
                  
62
62
 
63
 
from copy import copy
64
63
from cStringIO import StringIO
65
64
from itertools import izip, chain
66
65
import operator
294
293
 
295
294
 
296
295
class KnitContent(object):
297
 
    """Content of a knit version to which deltas can be applied."""
 
296
    """Content of a knit version to which deltas can be applied.
 
297
    
 
298
    This is always stored in memory as a list of lines with \n at the end,
 
299
    plus a flag saying if the final ending is really there or not, because that 
 
300
    corresponds to the on-disk knit representation.
 
301
    """
298
302
 
299
303
    def __init__(self):
300
304
        self._should_strip_eol = False
303
307
        """Apply delta to this object to become new_version_id."""
304
308
        raise NotImplementedError(self.apply_delta)
305
309
 
306
 
    def cleanup_eol(self, copy_on_mutate=True):
307
 
        if self._should_strip_eol:
308
 
            if copy_on_mutate:
309
 
                self._lines = self._lines[:]
310
 
            self.strip_last_line_newline()
311
 
 
312
310
    def line_delta_iter(self, new_lines):
313
311
        """Generate line-based delta from this content to new_lines."""
314
312
        new_texts = new_lines.text()
359
357
 
360
358
    def annotate(self):
361
359
        """Return a list of (origin, text) for each content line."""
362
 
        return list(self._lines)
 
360
        lines = self._lines[:]
 
361
        if self._should_strip_eol:
 
362
            origin, last_line = lines[-1]
 
363
            lines[-1] = (origin, last_line.rstrip('\n'))
 
364
        return lines
363
365
 
364
366
    def apply_delta(self, delta, new_version_id):
365
367
        """Apply delta to this object to become new_version_id."""
369
371
            lines[offset+start:offset+end] = delta_lines
370
372
            offset = offset + (start - end) + count
371
373
 
372
 
    def strip_last_line_newline(self):
373
 
        line = self._lines[-1][1].rstrip('\n')
374
 
        self._lines[-1] = (self._lines[-1][0], line)
375
 
        self._should_strip_eol = False
376
 
 
377
374
    def text(self):
378
375
        try:
379
376
            lines = [text for origin, text in self._lines]
384
381
            raise KnitCorrupt(self,
385
382
                "line in annotated knit missing annotation information: %s"
386
383
                % (e,))
387
 
 
388
384
        if self._should_strip_eol:
389
385
            lines[-1] = lines[-1].rstrip('\n')
390
386
        return lines
422
418
    def copy(self):
423
419
        return PlainKnitContent(self._lines[:], self._version_id)
424
420
 
425
 
    def strip_last_line_newline(self):
426
 
        self._lines[-1] = self._lines[-1].rstrip('\n')
427
 
        self._should_strip_eol = False
428
 
 
429
421
    def text(self):
430
422
        lines = self._lines
431
423
        if self._should_strip_eol:
1003
995
                    if multiple_versions:
1004
996
                        content_map[component_id] = content
1005
997
 
1006
 
            content.cleanup_eol(copy_on_mutate=multiple_versions)
1007
998
            final_content[key] = content
1008
999
 
1009
1000
            # digest here is the digest from the last applied component.
1338
1329
                for i, j, n in seq.get_matching_blocks():
1339
1330
                    if n == 0:
1340
1331
                        continue
1341
 
                    # this appears to copy (origin, text) pairs across to the
1342
 
                    # new content for any line that matches the last-checked
 
1332
                    # this copies (origin, text) pairs across to the new
 
1333
                    # content for any line that matches the last-checked
1343
1334
                    # parent.
1344
1335
                    content._lines[j:j+n] = merge_content._lines[i:i+n]
1345
1336
            if content._lines and content._lines[-1][1][-1] != '\n':