~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

Merge in format-5 work - release bzr 0.1rc1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
# it's not predictable when it will be written out.
22
22
 
23
23
import os
 
24
import stat
24
25
import fnmatch
25
26
        
26
27
import bzrlib.tree
28
29
from bzrlib.errors import BzrCheckError
29
30
from bzrlib.trace import mutter
30
31
 
 
32
class TreeEntry(object):
 
33
    """An entry that implements the minium interface used by commands.
 
34
 
 
35
    This needs further inspection, it may be better to have 
 
36
    InventoryEntries without ids - though that seems wrong. For now,
 
37
    this is a parallel hierarchy to InventoryEntry, and needs to become
 
38
    one of several things: decorates to that hierarchy, children of, or
 
39
    parents of it.
 
40
    Another note is that these objects are currently only used when there is
 
41
    no InventoryEntry available - i.e. for unversioned objects.
 
42
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
 
43
    """
 
44
 
 
45
    def __eq__(self, other):
 
46
        # yes, this us ugly, TODO: best practice __eq__ style.
 
47
        return (isinstance(other, TreeEntry)
 
48
                and other.__class__ == self.__class__)
 
49
 
 
50
    def kind_character(self):
 
51
        return "???"
 
52
 
 
53
 
 
54
class TreeDirectory(TreeEntry):
 
55
    """See TreeEntry. This is a directory in a working tree."""
 
56
 
 
57
    def __eq__(self, other):
 
58
        return (isinstance(other, TreeDirectory)
 
59
                and other.__class__ == self.__class__)
 
60
 
 
61
    def kind_character(self):
 
62
        return "/"
 
63
 
 
64
 
 
65
class TreeFile(TreeEntry):
 
66
    """See TreeEntry. This is a regular file in a working tree."""
 
67
 
 
68
    def __eq__(self, other):
 
69
        return (isinstance(other, TreeFile)
 
70
                and other.__class__ == self.__class__)
 
71
 
 
72
    def kind_character(self):
 
73
        return ''
 
74
 
 
75
 
 
76
class TreeLink(TreeEntry):
 
77
    """See TreeEntry. This is a symlink in a working tree."""
 
78
 
 
79
    def __eq__(self, other):
 
80
        return (isinstance(other, TreeLink)
 
81
                and other.__class__ == self.__class__)
 
82
 
 
83
    def kind_character(self):
 
84
        return ''
 
85
 
 
86
 
31
87
class WorkingTree(bzrlib.tree.Tree):
32
88
    """Working copy tree.
33
89
 
69
125
        """
70
126
        inv = self._inventory
71
127
        for path, ie in inv.iter_entries():
72
 
            if os.path.exists(self.abspath(path)):
 
128
            if bzrlib.osutils.lexists(self.abspath(path)):
73
129
                yield ie.file_id
74
130
 
75
131
 
83
139
        return os.path.join(self.basedir, filename)
84
140
 
85
141
    def has_filename(self, filename):
86
 
        return os.path.exists(self.abspath(filename))
 
142
        return bzrlib.osutils.lexists(self.abspath(filename))
87
143
 
88
144
    def get_file(self, file_id):
89
145
        return self.get_file_byname(self.id2path(file_id))
95
151
        ## XXX: badly named; this isn't in the store at all
96
152
        return self.abspath(self.id2path(file_id))
97
153
 
 
154
 
 
155
    def id2abspath(self, file_id):
 
156
        return self.abspath(self.id2path(file_id))
 
157
 
98
158
                
99
159
    def has_id(self, file_id):
100
160
        # files that have been deleted are excluded
102
162
        if not inv.has_id(file_id):
103
163
            return False
104
164
        path = inv.id2path(file_id)
105
 
        return os.path.exists(self.abspath(path))
 
165
        return bzrlib.osutils.lexists(self.abspath(path))
106
166
 
107
167
 
108
168
    __contains__ = has_id
109
169
    
110
170
 
111
171
    def get_file_size(self, file_id):
112
 
        # is this still called?
113
 
        raise NotImplementedError()
114
 
 
 
172
        return os.path.getsize(self.id2abspath(file_id))
115
173
 
116
174
    def get_file_sha1(self, file_id):
117
175
        path = self._inventory.id2path(file_id)
118
176
        return self._hashcache.get_sha1(path)
119
177
 
120
178
 
 
179
    def is_executable(self, file_id):
 
180
        if os.name == "nt":
 
181
            return self._inventory[file_id].executable
 
182
        else:
 
183
            path = self._inventory.id2path(file_id)
 
184
            mode = os.lstat(self.abspath(path)).st_mode
 
185
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC&mode)
 
186
 
 
187
    def get_symlink_target(self, file_id):
 
188
        return os.readlink(self.id2path(file_id))
 
189
 
121
190
    def file_class(self, filename):
122
191
        if self.path2id(filename):
123
192
            return 'V'
171
240
                                            "now of kind %r"
172
241
                                            % (fap, f_ie.kind, f_ie.file_id, fk))
173
242
 
174
 
                yield fp, c, fk, (f_ie and f_ie.file_id)
 
243
                # make a last minute entry
 
244
                if f_ie:
 
245
                    entry = f_ie
 
246
                else:
 
247
                    if fk == 'directory':
 
248
                        entry = TreeDirectory()
 
249
                    elif fk == 'file':
 
250
                        entry = TreeFile()
 
251
                    elif fk == 'symlink':
 
252
                        entry = TreeLink()
 
253
                    else:
 
254
                        entry = TreeEntry()
 
255
                
 
256
                yield fp, c, fk, (f_ie and f_ie.file_id), entry
175
257
 
176
258
                if fk != 'directory':
177
259
                    continue