36
38
self._revision_id = revision_id
37
39
self._rules_searcher = None
41
def has_versioned_directories(self):
42
"""See `Tree.has_versioned_directories`."""
43
return self._repository._format.supports_versioned_directories
39
45
def supports_tree_reference(self):
40
46
return getattr(self._repository._format, "supports_tree_reference",
61
67
raise NotImplementedError(self.get_file_revision)
63
69
def get_file_text(self, file_id, path=None):
64
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
65
return ''.join(content)
70
for (identifier, content) in self.iter_files_bytes([(file_id, None)]):
71
ret = "".join(content)
67
74
def get_file(self, file_id, path=None):
68
75
return StringIO(self.get_file_text(file_id))
96
103
self._inventory = inv
98
105
def get_file_mtime(self, file_id, path=None):
99
ie = self._inventory[file_id]
106
inv, inv_file_id = self._unpack_file_id(file_id)
107
ie = inv[inv_file_id]
101
109
revision = self._repository.get_revision(ie.revision)
102
110
except errors.NoSuchRevision:
104
112
return revision.timestamp
106
114
def get_file_size(self, file_id):
107
return self._inventory[file_id].text_size
115
inv, inv_file_id = self._unpack_file_id(file_id)
116
return inv[inv_file_id].text_size
109
118
def get_file_sha1(self, file_id, path=None, stat_value=None):
110
ie = self._inventory[file_id]
119
inv, inv_file_id = self._unpack_file_id(file_id)
120
ie = inv[inv_file_id]
111
121
if ie.kind == "file":
112
122
return ie.text_sha1
115
125
def get_file_revision(self, file_id, path=None):
116
ie = self._inventory[file_id]
126
inv, inv_file_id = self._unpack_file_id(file_id)
127
ie = inv[inv_file_id]
117
128
return ie.revision
119
130
def is_executable(self, file_id, path=None):
120
ie = self._inventory[file_id]
131
inv, inv_file_id = self._unpack_file_id(file_id)
132
ie = inv[inv_file_id]
121
133
if ie.kind != "file":
123
135
return ie.executable
125
137
def has_filename(self, filename):
126
return bool(self.inventory.path2id(filename))
138
return bool(self.path2id(filename))
128
140
def list_files(self, include_root=False, from_dir=None, recursive=True):
129
141
# The only files returned by this are those from the version
131
142
if from_dir is None:
132
143
from_dir_id = None
144
inv = self.root_inventory
134
from_dir_id = inv.path2id(from_dir)
146
inv, from_dir_id = self._path2inv_file_id(from_dir)
135
147
if from_dir_id is None:
136
148
# Directory not versioned
143
155
yield path, 'V', entry.kind, entry.file_id, entry
145
157
def get_symlink_target(self, file_id, path=None):
146
ie = self._inventory[file_id]
158
inv, inv_file_id = self._unpack_file_id(file_id)
159
ie = inv[inv_file_id]
147
160
# Inventories store symlink targets in unicode
148
161
return ie.symlink_target
150
163
def get_reference_revision(self, file_id, path=None):
151
return self.inventory[file_id].reference_revision
164
inv, inv_file_id = self._unpack_file_id(file_id)
165
return inv[inv_file_id].reference_revision
153
167
def get_root_id(self):
154
if self.inventory.root:
155
return self.inventory.root.file_id
168
if self.root_inventory.root:
169
return self.root_inventory.root.file_id
157
171
def kind(self, file_id):
158
return self._inventory[file_id].kind
172
inv, inv_file_id = self._unpack_file_id(file_id)
173
return inv[inv_file_id].kind
160
175
def path_content_summary(self, path):
161
176
"""See Tree.path_content_summary."""
162
id = self.inventory.path2id(path)
177
inv, file_id = self._path2inv_file_id(path)
164
179
return ('missing', None, None, None)
165
entry = self._inventory[id]
166
181
kind = entry.kind
167
182
if kind == 'file':
168
183
return (kind, entry.text_size, entry.executable, entry.text_sha1)
211
225
def iter_files_bytes(self, desired_files):
212
226
"""See Tree.iter_files_bytes.
214
This version is implemented on top of Repository.extract_files_bytes"""
228
This version is implemented on top of Repository.iter_files_bytes"""
215
229
repo_desired_files = [(f, self.get_file_revision(f), i)
216
230
for f, i in desired_files]
218
232
for result in self._repository.iter_files_bytes(repo_desired_files):
220
234
except errors.RevisionNotPresent, e:
221
raise errors.NoSuchFile(e.revision_id)
235
raise errors.NoSuchFile(e.file_id)
223
237
def annotate_iter(self, file_id,
224
238
default_revision=revision.CURRENT_REVISION):
228
242
annotations = annotator.annotate_flat(text_key)
229
243
return [(key[-1], line) for key, line in annotations]
245
def __eq__(self, other):
248
if isinstance(other, InventoryRevisionTree):
249
return (self.root_inventory == other.root_inventory)
252
def __ne__(self, other):
253
return not (self == other)
256
raise ValueError('not hashable')
232
259
class InterCHKRevisionTree(tree.InterTree):
233
260
"""Fast path optimiser for RevisionTrees with CHK inventories."""
238
265
and isinstance(target, RevisionTree)):
240
267
# Only CHK inventories have id_to_entry attribute
241
source.inventory.id_to_entry
242
target.inventory.id_to_entry
268
source.root_inventory.id_to_entry
269
target.root_inventory.id_to_entry
244
271
except AttributeError:
263
290
# to CHKInventory.iter_changes and do a better job there -- vila
265
292
changed_file_ids = set()
266
for result in self.target.inventory.iter_changes(self.source.inventory):
293
# FIXME: nested tree support
294
for result in self.target.root_inventory.iter_changes(
295
self.source.root_inventory):
267
296
if specific_file_ids is not None:
268
297
file_id = result[0]
269
298
if file_id not in specific_file_ids:
286
315
# Now walk the whole inventory, excluding the already yielded
317
# FIXME: Support nested trees
288
318
changed_file_ids = set(changed_file_ids)
289
for relpath, entry in self.target.inventory.iter_entries():
319
for relpath, entry in self.target.root_inventory.iter_entries():
290
320
if (specific_file_ids is not None
291
321
and not entry.file_id in specific_file_ids):