~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-07-20 08:10:24 UTC
  • mfrom: (2637.1.1 ianc-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20070720081024-5xhlp7r8ufwxt6nf
(Kent Gibson) Update update's help

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
from bzrlib.lazy_import import lazy_import
23
23
lazy_import(globals(), """
24
 
from copy import deepcopy
25
 
import unittest
26
24
 
27
25
from bzrlib import (
28
26
    errors,
29
27
    osutils,
 
28
    multiparent,
30
29
    tsort,
31
30
    revision,
32
31
    ui,
34
33
from bzrlib.transport.memory import MemoryTransport
35
34
""")
36
35
 
 
36
from cStringIO import StringIO
 
37
 
37
38
from bzrlib.inter import InterObject
38
39
from bzrlib.textmerge import TextMerge
39
40
from bzrlib.symbol_versioning import (deprecated_function,
266
267
            result[version_id] = self.get_delta(version_id)
267
268
        return result
268
269
 
 
270
    def make_mpdiffs(self, version_ids):
 
271
        """Create multiparent diffs for specified versions"""
 
272
        knit_versions = set()
 
273
        for version_id in version_ids:
 
274
            knit_versions.add(version_id)
 
275
            knit_versions.update(self.get_parents(version_id))
 
276
        lines = dict(zip(knit_versions,
 
277
            self._get_lf_split_line_list(knit_versions)))
 
278
        diffs = []
 
279
        for version_id in version_ids:
 
280
            target = lines[version_id]
 
281
            parents = [lines[p] for p in self.get_parents(version_id)]
 
282
            if len(parents) > 0:
 
283
                left_parent_blocks = self._extract_blocks(version_id,
 
284
                                                          parents[0], target)
 
285
            else:
 
286
                left_parent_blocks = None
 
287
            diffs.append(multiparent.MultiParent.from_lines(target, parents,
 
288
                         left_parent_blocks))
 
289
        return diffs
 
290
 
 
291
    def _extract_blocks(self, version_id, source, target):
 
292
        return None
 
293
 
 
294
    def add_mpdiffs(self, records):
 
295
        """Add mpdiffs to this versionedfile
 
296
 
 
297
        Records should be iterables of version, parents, expected_sha1,
 
298
        mpdiff.  mpdiff should be a MultiParent instance.
 
299
        """
 
300
        vf_parents = {}
 
301
        for version, parents, expected_sha1, mpdiff in records:
 
302
            mpvf = multiparent.MultiMemoryVersionedFile()
 
303
            needed_parents = [p for p in parents if not mpvf.has_version(p)]
 
304
            parent_lines = self._get_lf_split_line_list(needed_parents)
 
305
            for parent_id, lines in zip(needed_parents, parent_lines):
 
306
                mpvf.add_version(lines, parent_id, [])
 
307
            mpvf.add_diff(mpdiff, version, parents)
 
308
            lines = mpvf.get_line_list([version])[0]
 
309
            version_text = self.add_lines(version, parents, lines, vf_parents)
 
310
            vf_parents[version] = version_text
 
311
            if expected_sha1 != self.get_sha1(version):
 
312
                raise errors.VersionedFileInvalidChecksum(version)
 
313
 
269
314
    def get_sha1(self, version_id):
270
315
        """Get the stored sha1 sum for the given revision.
271
316
        
273
318
        """
274
319
        raise NotImplementedError(self.get_sha1)
275
320
 
 
321
    def get_sha1s(self, version_ids):
 
322
        """Get the stored sha1 sums for the given revisions.
 
323
 
 
324
        :param version_ids: The names of the versions to lookup
 
325
        :return: a list of sha1s in order according to the version_ids
 
326
        """
 
327
        raise NotImplementedError(self.get_sha1)
 
328
 
276
329
    def get_suffixes(self):
277
330
        """Return the file suffixes associated with this versioned file."""
278
331
        raise NotImplementedError(self.get_suffixes)
302
355
        """
303
356
        raise NotImplementedError(self.get_lines)
304
357
 
305
 
    def get_ancestry(self, version_ids):
 
358
    def _get_lf_split_line_list(self, version_ids):
 
359
        return [StringIO(t).readlines() for t in self.get_texts(version_ids)]
 
360
 
 
361
    def get_ancestry(self, version_ids, topo_sorted=True):
306
362
        """Return a list of all ancestors of given version(s). This
307
363
        will not include the null revision.
308
364
 
 
365
        This list will not be topologically sorted if topo_sorted=False is
 
366
        passed.
 
367
 
309
368
        Must raise RevisionNotPresent if any of the given versions are
310
369
        not present in file history."""
311
370
        if isinstance(version_ids, basestring):
681
740
                    else:
682
741
                        new_version_ids.add(version)
683
742
                return new_version_ids
684
 
 
685
 
 
686
 
class InterVersionedFileTestProviderAdapter(object):
687
 
    """A tool to generate a suite testing multiple inter versioned-file classes.
688
 
 
689
 
    This is done by copying the test once for each InterVersionedFile provider
690
 
    and injecting the transport_server, transport_readonly_server,
691
 
    versionedfile_factory and versionedfile_factory_to classes into each copy.
692
 
    Each copy is also given a new id() to make it easy to identify.
693
 
    """
694
 
 
695
 
    def __init__(self, transport_server, transport_readonly_server, formats):
696
 
        self._transport_server = transport_server
697
 
        self._transport_readonly_server = transport_readonly_server
698
 
        self._formats = formats
699
 
    
700
 
    def adapt(self, test):
701
 
        result = unittest.TestSuite()
702
 
        for (interversionedfile_class,
703
 
             versionedfile_factory,
704
 
             versionedfile_factory_to) in self._formats:
705
 
            new_test = deepcopy(test)
706
 
            new_test.transport_server = self._transport_server
707
 
            new_test.transport_readonly_server = self._transport_readonly_server
708
 
            new_test.interversionedfile_class = interversionedfile_class
709
 
            new_test.versionedfile_factory = versionedfile_factory
710
 
            new_test.versionedfile_factory_to = versionedfile_factory_to
711
 
            def make_new_test_id():
712
 
                new_id = "%s(%s)" % (new_test.id(), interversionedfile_class.__name__)
713
 
                return lambda: new_id
714
 
            new_test.id = make_new_test_id()
715
 
            result.addTest(new_test)
716
 
        return result
717
 
 
718
 
    @staticmethod
719
 
    def default_test_list():
720
 
        """Generate the default list of interversionedfile permutations to test."""
721
 
        from bzrlib.weave import WeaveFile
722
 
        from bzrlib.knit import KnitVersionedFile
723
 
        result = []
724
 
        # test the fallback InterVersionedFile from annotated knits to weave
725
 
        result.append((InterVersionedFile, 
726
 
                       KnitVersionedFile,
727
 
                       WeaveFile))
728
 
        for optimiser in InterVersionedFile._optimisers:
729
 
            result.append((optimiser,
730
 
                           optimiser._matching_file_from_factory,
731
 
                           optimiser._matching_file_to_factory
732
 
                           ))
733
 
        # if there are specific combinations we want to use, we can add them 
734
 
        # here.
735
 
        return result