29
28
from bzrlib.errors import BzrCheckError
30
29
from bzrlib.trace import mutter
32
class TreeEntry(object):
33
"""An entry that implements the minium interface used by commands.
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
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
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__)
50
def kind_character(self):
54
class TreeDirectory(TreeEntry):
55
"""See TreeEntry. This is a directory in a working tree."""
57
def __eq__(self, other):
58
return (isinstance(other, TreeDirectory)
59
and other.__class__ == self.__class__)
61
def kind_character(self):
65
class TreeFile(TreeEntry):
66
"""See TreeEntry. This is a regular file in a working tree."""
68
def __eq__(self, other):
69
return (isinstance(other, TreeFile)
70
and other.__class__ == self.__class__)
72
def kind_character(self):
76
class TreeLink(TreeEntry):
77
"""See TreeEntry. This is a symlink in a working tree."""
79
def __eq__(self, other):
80
return (isinstance(other, TreeLink)
81
and other.__class__ == self.__class__)
83
def kind_character(self):
87
31
class WorkingTree(bzrlib.tree.Tree):
88
32
"""Working copy tree.
139
83
return os.path.join(self.basedir, filename)
141
85
def has_filename(self, filename):
142
return bzrlib.osutils.lexists(self.abspath(filename))
86
return os.path.exists(self.abspath(filename))
144
88
def get_file(self, file_id):
145
89
return self.get_file_byname(self.id2path(file_id))
151
95
## XXX: badly named; this isn't in the store at all
152
96
return self.abspath(self.id2path(file_id))
155
def id2abspath(self, file_id):
156
return self.abspath(self.id2path(file_id))
159
99
def has_id(self, file_id):
160
100
# files that have been deleted are excluded
162
102
if not inv.has_id(file_id):
164
104
path = inv.id2path(file_id)
165
return bzrlib.osutils.lexists(self.abspath(path))
105
return os.path.exists(self.abspath(path))
168
108
__contains__ = has_id
171
111
def get_file_size(self, file_id):
172
return os.path.getsize(self.id2abspath(file_id))
112
# is this still called?
113
raise NotImplementedError()
174
116
def get_file_sha1(self, file_id):
175
117
path = self._inventory.id2path(file_id)
176
118
return self._hashcache.get_sha1(path)
179
def is_executable(self, file_id):
181
return self._inventory[file_id].executable
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)
187
def get_symlink_target(self, file_id):
188
return os.readlink(self.id2abspath(file_id))
190
121
def file_class(self, filename):
191
122
if self.path2id(filename):
241
172
% (fap, f_ie.kind, f_ie.file_id, fk))
243
# make a last minute entry
247
if fk == 'directory':
248
entry = TreeDirectory()
251
elif fk == 'symlink':
256
yield fp, c, fk, (f_ie and f_ie.file_id), entry
174
yield fp, c, fk, (f_ie and f_ie.file_id)
258
176
if fk != 'directory':
275
193
if not self.is_ignored(subp):
278
def iter_conflicts(self):
280
for path in (s[0] for s in self.list_files()):
281
stem = get_conflicted_stem(path)
284
if stem not in conflicted:
288
197
def extras(self):
289
198
"""Yield all unknown files in this WorkingTree.
379
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
380
def get_conflicted_stem(path):
381
for suffix in CONFLICT_SUFFIXES:
382
if path.endswith(suffix):
383
return path[:-len(suffix)]