/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 bzrlib/bundle/bundle_data.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
from __future__ import absolute_import
20
20
 
21
21
import base64
 
22
from cStringIO import StringIO
22
23
import os
23
24
import pprint
24
25
 
25
 
from .. import (
26
 
    cache_utf8,
 
26
from bzrlib import (
27
27
    osutils,
28
28
    timestamp,
29
29
    )
30
 
from . import apply_bundle
31
 
from ..errors import (
 
30
from bzrlib.bundle import apply_bundle
 
31
from bzrlib.errors import (
32
32
    TestamentMismatch,
33
33
    BzrError,
34
34
    )
35
 
from ..bzr.inventory import (
 
35
from bzrlib.inventory import (
36
36
    Inventory,
37
37
    InventoryDirectory,
38
38
    InventoryFile,
39
39
    InventoryLink,
40
40
    )
41
 
from ..osutils import sha_string, pathjoin
42
 
from ..revision import Revision, NULL_REVISION
43
 
from ..sixish import (
44
 
    BytesIO,
45
 
    viewitems,
46
 
    )
47
 
from ..testament import StrictTestament
48
 
from ..trace import mutter, warning
49
 
from ..tree import Tree
50
 
from ..bzr.xml5 import serializer_v5
 
41
from bzrlib.osutils import sha_string, pathjoin
 
42
from bzrlib.revision import Revision, NULL_REVISION
 
43
from bzrlib.testament import StrictTestament
 
44
from bzrlib.trace import mutter, warning
 
45
from bzrlib.tree import Tree
 
46
from bzrlib.xml5 import serializer_v5
51
47
 
52
48
 
53
49
class RevisionInfo(object):
107
103
        revision_info.timestamp = revision.timestamp
108
104
        revision_info.message = revision.message.split('\n')
109
105
        revision_info.properties = [': '.join(p) for p in
110
 
                                    viewitems(revision.properties)]
 
106
                                    revision.properties.iteritems()]
111
107
        return revision_info
112
108
 
113
109
 
144
140
        split up, based on the assumptions that can be made
145
141
        when information is missing.
146
142
        """
147
 
        from breezy.timestamp import unpack_highres_date
 
143
        from bzrlib.timestamp import unpack_highres_date
148
144
        # Put in all of the guessable information.
149
145
        if not self.timestamp and self.date:
150
146
            self.timestamp, self.timezone = unpack_highres_date(self.date)
253
249
 
254
250
        count = 0
255
251
        missing = {}
256
 
        for revision_id, sha1 in viewitems(rev_to_sha):
 
252
        for revision_id, sha1 in rev_to_sha.iteritems():
257
253
            if repository.has_revision(revision_id):
258
254
                testament = StrictTestament.from_revision(repository,
259
255
                                                          revision_id)
286
282
        if rev.revision_id != revision_id:
287
283
            raise AssertionError()
288
284
        if sha1 != rev.inventory_sha1:
289
 
            with open(',,bogus-inv', 'wb') as f:
 
285
            f = open(',,bogus-inv', 'wb')
 
286
            try:
290
287
                f.write(s)
 
288
            finally:
 
289
                f.close()
291
290
            warning('Inventory sha hash mismatch for revision %s. %s'
292
291
                    ' != %s' % (revision_id, sha1, rev.inventory_sha1))
293
292
 
322
321
            if last_changed is not None:
323
322
                # last_changed will be a Unicode string because of how it was
324
323
                # read. Convert it back to utf8.
325
 
                changed_revision_id = cache_utf8.encode(last_changed)
 
324
                changed_revision_id = osutils.safe_revision_id(last_changed,
 
325
                                                               warn=False)
326
326
            else:
327
327
                changed_revision_id = revision_id
328
328
            bundle_tree.note_last_changed(path, changed_revision_id)
397
397
                        ': %r' % extra)
398
398
            # This will be Unicode because of how the stream is read. Turn it
399
399
            # back into a utf8 file_id
400
 
            file_id = cache_utf8.encode(info[1][8:])
 
400
            file_id = osutils.safe_file_id(info[1][8:], warn=False)
401
401
 
402
402
            bundle_tree.note_id(file_id, path, kind)
403
403
            # this will be overridden in extra_info if executable is specified.
473
473
        self._renamed_r = {} # new_path => old_path
474
474
        self._new_id = {} # new_path => new_id
475
475
        self._new_id_r = {} # new_id => new_path
476
 
        self._kinds = {} # new_path => kind
 
476
        self._kinds = {} # new_id => kind
477
477
        self._last_changed = {} # new_id => revision_id
478
478
        self._executable = {} # new_id => executable value
479
479
        self.patches = {}
499
499
        """Files that don't exist in base need a new id."""
500
500
        self._new_id[new_path] = new_id
501
501
        self._new_id_r[new_id] = new_path
502
 
        self._kinds[new_path] = kind
 
502
        self._kinds[new_id] = kind
503
503
 
504
504
    def note_last_changed(self, file_id, revision_id):
505
505
        if (file_id in self._last_changed
532
532
        old_path = self._renamed.get(new_path)
533
533
        if old_path is not None:
534
534
            return old_path
535
 
        dirname, basename = os.path.split(new_path)
 
535
        dirname,basename = os.path.split(new_path)
536
536
        # dirname is not '' doesn't work, because
537
537
        # dirname may be a unicode entry, and is
538
538
        # requires the objects to be identical
561
561
            return new_path
562
562
        if new_path in self._renamed:
563
563
            return None
564
 
        dirname, basename = os.path.split(old_path)
 
564
        dirname,basename = os.path.split(old_path)
565
565
        if dirname != '':
566
566
            new_dir = self.new_path(dirname)
567
567
            if new_dir is None:
615
615
        new_path = self.id2path(file_id)
616
616
        return self.base_tree.path2id(new_path)
617
617
 
618
 
    def get_file(self, path, file_id=None):
 
618
    def get_file(self, file_id):
619
619
        """Return a file-like object containing the new contents of the
620
620
        file given by file_id.
621
621
 
623
623
                in the text-store, so that the file contents would
624
624
                then be cached.
625
625
        """
626
 
        if file_id is None:
627
 
            file_id = self.path2id(path)
628
626
        base_id = self.old_contents_id(file_id)
629
627
        if (base_id is not None and
630
628
            base_id != self.base_tree.get_root_id()):
631
 
            old_path = self.old_path(path)
632
 
            patch_original = self.base_tree.get_file(
633
 
                    old_path, base_id)
 
629
            patch_original = self.base_tree.get_file(base_id)
634
630
        else:
635
631
            patch_original = None
636
 
        file_patch = self.patches.get(path)
 
632
        file_patch = self.patches.get(self.id2path(file_id))
637
633
        if file_patch is None:
638
634
            if (patch_original is None and
639
 
                self.kind(path, file_id) == 'directory'):
640
 
                return BytesIO()
 
635
                self.kind(file_id) == 'directory'):
 
636
                return StringIO()
641
637
            if patch_original is None:
642
638
                raise AssertionError("None: %s" % file_id)
643
639
            return patch_original
647
643
                'Malformed patch for %s, %r' % (file_id, file_patch))
648
644
        return patched_file(file_patch, patch_original)
649
645
 
650
 
    def get_symlink_target(self, path, file_id=None):
 
646
    def get_symlink_target(self, file_id, path=None):
 
647
        if path is None:
 
648
            path = self.id2path(file_id)
651
649
        try:
652
650
            return self._targets[path]
653
651
        except KeyError:
654
 
            old_path = self.old_path(path)
655
 
            return self.base_tree.get_symlink_target(old_path, file_id)
656
 
 
657
 
    def kind(self, path, file_id=None):
658
 
        try:
659
 
            return self._kinds[path]
660
 
        except KeyError:
661
 
            old_path = self.old_path(path)
662
 
            return self.base_tree.kind(old_path, file_id)
663
 
 
664
 
    def get_file_revision(self, path, file_id=None):
 
652
            return self.base_tree.get_symlink_target(file_id)
 
653
 
 
654
    def kind(self, file_id):
 
655
        if file_id in self._kinds:
 
656
            return self._kinds[file_id]
 
657
        return self.base_tree.kind(file_id)
 
658
 
 
659
    def get_file_revision(self, file_id):
 
660
        path = self.id2path(file_id)
665
661
        if path in self._last_changed:
666
662
            return self._last_changed[path]
667
663
        else:
668
 
            old_path = self.old_path(path)
669
 
            return self.base_tree.get_file_revision(old_path, file_id)
 
664
            return self.base_tree.get_file_revision(file_id)
670
665
 
671
 
    def is_executable(self, path, file_id=None):
 
666
    def is_executable(self, file_id):
 
667
        path = self.id2path(file_id)
672
668
        if path in self._executable:
673
669
            return self._executable[path]
674
670
        else:
675
 
            old_path = self.old_path(path)
676
 
            return self.base_tree.is_executable(old_path, file_id)
 
671
            return self.base_tree.is_executable(file_id)
677
672
 
678
 
    def get_last_changed(self, path, file_id=None):
 
673
    def get_last_changed(self, file_id):
 
674
        path = self.id2path(file_id)
679
675
        if path in self._last_changed:
680
676
            return self._last_changed[path]
681
 
        old_path = self.old_path(path)
682
 
        return self.base_tree.get_file_revision(old_path, file_id)
 
677
        return self.base_tree.get_file_revision(file_id)
683
678
 
684
 
    def get_size_and_sha1(self, new_path, file_id=None):
 
679
    def get_size_and_sha1(self, file_id):
685
680
        """Return the size and sha1 hash of the given file id.
686
681
        If the file was not locally modified, this is extracted
687
682
        from the base_tree. Rather than re-reading the file.
688
683
        """
 
684
        new_path = self.id2path(file_id)
689
685
        if new_path is None:
690
686
            return None, None
691
687
        if new_path not in self.patches:
692
688
            # If the entry does not have a patch, then the
693
689
            # contents must be the same as in the base_tree
694
 
            base_path = self.old_path(new_path)
695
 
            text_size = self.base_tree.get_file_size(base_path, file_id)
696
 
            text_sha1 = self.base_tree.get_file_sha1(base_path, file_id)
 
690
            text_size = self.base_tree.get_file_size(file_id)
 
691
            text_sha1 = self.base_tree.get_file_sha1(file_id)
697
692
            return text_size, text_sha1
698
 
        fileobj = self.get_file(new_path, file_id)
 
693
        fileobj = self.get_file(file_id)
699
694
        content = fileobj.read()
700
695
        return len(content), sha_string(content)
701
696
 
707
702
        from os.path import dirname, basename
708
703
        inv = Inventory(None, self.revision_id)
709
704
 
710
 
        def add_entry(path, file_id):
 
705
        def add_entry(file_id):
 
706
            path = self.id2path(file_id)
 
707
            if path is None:
 
708
                return
711
709
            if path == '':
712
710
                parent_id = None
713
711
            else:
714
712
                parent_path = dirname(path)
715
713
                parent_id = self.path2id(parent_path)
716
714
 
717
 
            kind = self.kind(path, file_id)
718
 
            revision_id = self.get_last_changed(path, file_id)
 
715
            kind = self.kind(file_id)
 
716
            revision_id = self.get_last_changed(file_id)
719
717
 
720
718
            name = basename(path)
721
719
            if kind == 'directory':
722
720
                ie = InventoryDirectory(file_id, name, parent_id)
723
721
            elif kind == 'file':
724
722
                ie = InventoryFile(file_id, name, parent_id)
725
 
                ie.executable = self.is_executable(path, file_id)
 
723
                ie.executable = self.is_executable(file_id)
726
724
            elif kind == 'symlink':
727
725
                ie = InventoryLink(file_id, name, parent_id)
728
 
                ie.symlink_target = self.get_symlink_target(path, file_id)
 
726
                ie.symlink_target = self.get_symlink_target(file_id, path)
729
727
            ie.revision = revision_id
730
728
 
731
729
            if kind == 'file':
732
 
                ie.text_size, ie.text_sha1 = self.get_size_and_sha1(
733
 
                        path, file_id)
 
730
                ie.text_size, ie.text_sha1 = self.get_size_and_sha1(file_id)
734
731
                if ie.text_size is None:
735
732
                    raise BzrError(
736
733
                        'Got a text_size of None for file_id %r' % file_id)
738
735
 
739
736
        sorted_entries = self.sorted_path_id()
740
737
        for path, file_id in sorted_entries:
741
 
            add_entry(path, file_id)
 
738
            add_entry(file_id)
742
739
 
743
740
        return inv
744
741
 
752
749
    root_inventory = property(_get_inventory)
753
750
 
754
751
    def all_file_ids(self):
755
 
        return {entry.file_id for path, entry in self.inventory.iter_entries()}
756
 
 
757
 
    def all_versioned_paths(self):
758
 
        return {path for path, entry in self.inventory.iter_entries()}
 
752
        return set(
 
753
            [entry.file_id for path, entry in self.inventory.iter_entries()])
759
754
 
760
755
    def list_files(self, include_root=False, from_dir=None, recursive=True):
761
756
        # The only files returned by this are those from the version
770
765
        entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
771
766
        if inv.root is not None and not include_root and from_dir is None:
772
767
            # skip the root for compatability with the current apis.
773
 
            next(entries)
 
768
            entries.next()
774
769
        for path, entry in entries:
775
770
            yield path, 'V', entry.kind, entry.file_id, entry
776
771
 
777
772
    def sorted_path_id(self):
778
773
        paths = []
779
 
        for result in viewitems(self._new_id):
 
774
        for result in self._new_id.iteritems():
780
775
            paths.append(result)
781
776
        for id in self.base_tree.all_file_ids():
782
777
            path = self.id2path(id)
789
784
 
790
785
def patched_file(file_patch, original):
791
786
    """Produce a file-like object with the patched version of a text"""
792
 
    from breezy.patches import iter_patched
793
 
    from breezy.iterablefile import IterableFile
 
787
    from bzrlib.patches import iter_patched
 
788
    from bzrlib.iterablefile import IterableFile
794
789
    if file_patch == "":
795
790
        return IterableFile(())
796
791
    # string.splitlines(True) also splits on '\r', but the iter_patched code
797
792
    # only expects to iterate over '\n' style lines
798
793
    return IterableFile(iter_patched(original,
799
 
                BytesIO(file_patch).readlines()))
 
794
                StringIO(file_patch).readlines()))