~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

 * bzr add now lists how many files were ignored per glob.  add --verbose
   lists the specific files.  (Aaron Bentley)

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
import bzrlib
38
38
from bzrlib.osutils import (pumpfile, quotefn, splitpath, joinpath,
39
 
                            pathjoin, sha_strings)
 
39
                            appendpath, sha_strings)
40
40
from bzrlib.trace import mutter
41
41
from bzrlib.errors import (NotVersionedError, InvalidEntryName,
42
42
                           BzrError, BzrCheckError)
79
79
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT')
80
80
    >>> i.add(InventoryFile('2323', 'hello.c', parent_id='123'))
81
81
    InventoryFile('2323', 'hello.c', parent_id='123')
82
 
    >>> shouldbe = {0: 'src', 1: pathjoin('src','hello.c')}
 
82
    >>> shouldbe = {0: 'src', 1: os.path.join('src','hello.c')}
83
83
    >>> for ix, j in enumerate(i.iter_entries()):
84
84
    ...   print (j[0] == shouldbe[ix], j[1])
85
85
    ... 
102
102
    >>> i['2326']
103
103
    InventoryFile('2326', 'wibble.c', parent_id='2325')
104
104
    >>> for path, entry in i.iter_entries():
105
 
    ...     print path
 
105
    ...     print path.replace('\\\\', '/')     # for win32 os.sep
106
106
    ...     assert i.path2id(path)
107
107
    ... 
108
108
    src
110
110
    src/hello.c
111
111
    src/wibble
112
112
    src/wibble/wibble.c
113
 
    >>> i.id2path('2326')
 
113
    >>> i.id2path('2326').replace('\\\\', '/')
114
114
    'src/wibble/wibble.c'
115
115
    """
116
116
    
202
202
 
203
203
    def get_tar_item(self, root, dp, now, tree):
204
204
        """Get a tarfile item and a file stream for its content."""
205
 
        item = tarfile.TarInfo(pathjoin(root, dp))
 
205
        item = tarfile.TarInfo(os.path.join(root, dp))
206
206
        # TODO: would be cool to actually set it to the timestamp of the
207
207
        # revision it was last changed
208
208
        item.mtime = now
267
267
        
268
268
        This is a template method - implement _put_on_disk in subclasses.
269
269
        """
270
 
        fullpath = pathjoin(dest, dp)
 
270
        fullpath = appendpath(dest, dp)
271
271
        self._put_on_disk(fullpath, tree)
272
272
        mutter("  export {%s} kind %s to %s", self.file_id,
273
273
                self.kind, fullpath)
407
407
        # first requested, or preload them if they're already known
408
408
        pass            # nothing to do by default
409
409
 
410
 
    def _forget_tree_state(self):
411
 
        pass
412
 
 
413
410
 
414
411
class RootEntry(InventoryEntry):
415
412
 
485
482
            else:
486
483
                checker.repeated_text_cnt += 1
487
484
                return
488
 
 
489
 
        if self.file_id not in checker.checked_weaves:
490
 
            mutter('check weave {%s}', self.file_id)
491
 
            w = tree.get_weave(self.file_id)
492
 
            # Not passing a progress bar, because it creates a new
493
 
            # progress, which overwrites the current progress,
494
 
            # and doesn't look nice
495
 
            w.check()
496
 
            checker.checked_weaves[self.file_id] = True
497
 
        else:
498
 
            w = tree.get_weave_prelude(self.file_id)
499
 
 
500
485
        mutter('check version {%s} of {%s}', rev_id, self.file_id)
 
486
        file_lines = tree.get_file_lines(self.file_id)
501
487
        checker.checked_text_cnt += 1 
502
 
        # We can't check the length, because Weave doesn't store that
503
 
        # information, and the whole point of looking at the weave's
504
 
        # sha1sum is that we don't have to extract the text.
505
 
        if self.text_sha1 != w.get_sha1(self.revision):
506
 
            raise BzrCheckError('text {%s} version {%s} wrong sha1' 
507
 
                                % (self.file_id, self.revision))
 
488
        if self.text_size != sum(map(len, file_lines)):
 
489
            raise BzrCheckError('text {%s} wrong size' % self.text_id)
 
490
        if self.text_sha1 != sha_strings(file_lines):
 
491
            raise BzrCheckError('text {%s} wrong sha1' % self.text_id)
508
492
        checker.checked_texts[t] = self.text_sha1
509
493
 
510
494
    def copy(self):
573
557
        self.text_sha1 = work_tree.get_file_sha1(self.file_id)
574
558
        self.executable = work_tree.is_executable(self.file_id)
575
559
 
576
 
    def _forget_tree_state(self):
577
 
        self.text_sha1 = None
578
 
        self.executable = None
579
 
 
580
560
    def _snapshot_text(self, file_parents, work_tree, weave_store, transaction):
581
561
        """See InventoryEntry._snapshot_text."""
582
562
        mutter('storing file {%s} in revision {%s}',
686
666
        """See InventoryEntry._read_tree_state."""
687
667
        self.symlink_target = work_tree.get_symlink_target(self.file_id)
688
668
 
689
 
    def _forget_tree_state(self):
690
 
        self.symlink_target = None
691
 
 
692
669
    def _unchanged(self, previous_ie):
693
670
        """See InventoryEntry._unchanged."""
694
671
        compatible = super(InventoryLink, self)._unchanged(previous_ie)
745
722
        The inventory is created with a default root directory, with
746
723
        an id of None.
747
724
        """
748
 
        # We are letting Branch.create() create a unique inventory
 
725
        # We are letting Branch.initialize() create a unique inventory
749
726
        # root id. Rather than generating a random one here.
750
727
        #if root_id is None:
751
728
        #    root_id = bzrlib.branch.gen_file_id('TREE_ROOT')
787
764
            yield name, ie
788
765
            if ie.kind == 'directory':
789
766
                for cn, cie in self.iter_entries(from_dir=ie.file_id):
790
 
                    yield pathjoin(name, cn), cie
 
767
                    yield os.path.join(name, cn), cie
791
768
 
792
769
 
793
770
    def entries(self):
800
777
            kids = dir_ie.children.items()
801
778
            kids.sort()
802
779
            for name, ie in kids:
803
 
                child_path = pathjoin(dir_path, name)
 
780
                child_path = os.path.join(dir_path, name)
804
781
                accum.append((child_path, ie))
805
782
                if ie.kind == 'directory':
806
783
                    descend(ie, child_path)
820
797
            kids.sort()
821
798
 
822
799
            for name, child_ie in kids:
823
 
                child_path = pathjoin(parent_path, name)
 
800
                child_path = os.path.join(parent_path, name)
824
801
                descend(child_ie, child_path)
825
802
        descend(self.root, u'')
826
803
        return accum
887
864
 
888
865
        if parent.children.has_key(entry.name):
889
866
            raise BzrError("%s is already versioned" %
890
 
                    pathjoin(self.id2path(parent.file_id), entry.name))
 
867
                    appendpath(self.id2path(parent.file_id), entry.name))
891
868
 
892
869
        self._byid[entry.file_id] = entry
893
870
        parent.children[entry.name] = entry
903
880
        from bzrlib.workingtree import gen_file_id
904
881
        
905
882
        parts = bzrlib.osutils.splitpath(relpath)
 
883
        if len(parts) == 0:
 
884
            raise BzrError("cannot re-add root of inventory")
906
885
 
907
886
        if file_id == None:
908
887
            file_id = gen_file_id(relpath)
909
888
 
910
 
        if len(parts) == 0:
911
 
            self.root = RootEntry(file_id)
912
 
            self._byid = {self.root.file_id: self.root}
913
 
            return
914
 
        else:
915
 
            parent_path = parts[:-1]
916
 
            parent_id = self.path2id(parent_path)
917
 
            if parent_id == None:
918
 
                raise NotVersionedError(path=parent_path)
 
889
        parent_path = parts[:-1]
 
890
        parent_id = self.path2id(parent_path)
 
891
        if parent_id == None:
 
892
            raise NotVersionedError(path=parent_path)
919
893
        if kind == 'directory':
920
894
            ie = InventoryDirectory(file_id, parts[-1], parent_id)
921
895
        elif kind == 'file':
941
915
        """
942
916
        ie = self[file_id]
943
917
 
944
 
        assert ie.parent_id is None or \
945
 
            self[ie.parent_id].children[ie.name] == ie
 
918
        assert self[ie.parent_id].children[ie.name] == ie
946
919
        
 
920
        # TODO: Test deleting all children; maybe hoist to a separate
 
921
        # deltree method?
 
922
        if ie.kind == 'directory':
 
923
            for cie in ie.children.values():
 
924
                del self[cie.file_id]
 
925
            del ie.children
 
926
 
947
927
        del self._byid[file_id]
948
 
        if ie.parent_id is not None:
949
 
            del self[ie.parent_id].children[ie.name]
 
928
        del self[ie.parent_id].children[ie.name]
950
929
 
951
930
 
952
931
    def __eq__(self, other):
1008
987
        >>> i = Inventory()
1009
988
        >>> e = i.add(InventoryDirectory('src-id', 'src', ROOT_ID))
1010
989
        >>> e = i.add(InventoryFile('foo-id', 'foo.c', parent_id='src-id'))
1011
 
        >>> print i.id2path('foo-id')
 
990
        >>> print i.id2path('foo-id').replace(os.sep, '/')
1012
991
        src/foo.c
1013
992
        """
1014
993
        # get all names, skipping root
1015
994
        p = [self._byid[fid].name for fid in self.get_idpath(file_id)[1:]]
1016
 
        if p:
1017
 
            return pathjoin(*p)
1018
 
        else:
1019
 
            return ''
 
995
        return os.sep.join(p)
1020
996
            
1021
997
 
1022
998