143
143
return False, False
145
@deprecated_method(symbol_versioning.one_zero)
146
def diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,
147
output_to, reverse=False):
148
"""Perform a diff from this to to_entry.
150
text_diff will be used for textual difference calculation.
151
This is a template method, override _diff in child classes.
153
self._read_tree_state(tree.id2path(self.file_id), tree)
155
# cannot diff from one kind to another - you must do a removal
156
# and an addif they do not match.
157
assert self.kind == to_entry.kind
158
to_entry._read_tree_state(to_tree.id2path(to_entry.file_id),
160
self._diff(text_diff, from_label, tree, to_label, to_entry, to_tree,
163
145
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,
164
146
output_to, reverse=False):
165
147
"""Perform a diff between two entries of the same kind."""
198
180
candidates[ie.revision] = ie
199
181
return candidates
201
@deprecated_method(symbol_versioning.zero_ninetyone)
202
def find_previous_heads(self, previous_inventories,
203
versioned_file_store,
206
"""Return the revisions and entries that directly precede this.
208
Returned as a map from revision to inventory entry.
210
This is a map containing the file revisions in all parents
211
for which the file exists, and its revision is not a parent of
212
any other. If the file is new, the set will be empty.
214
:param versioned_file_store: A store where ancestry data on this
215
file id can be queried.
216
:param transaction: The transaction that queries to the versioned
217
file store should be completed under.
218
:param entry_vf: The entry versioned file, if its already available.
220
candidates = self.parent_candidates(previous_inventories)
222
# revision:ie mapping with one revision for each head.
224
# common case optimisation
225
if len(candidates) == 1:
226
# if there is only one candidate revision found
227
# then we can avoid opening the versioned file to access ancestry:
228
# there cannot be any ancestors to eliminate when there is
229
# only one revision available.
232
# --- what follows is now encapsulated in repository.get_graph.heads(),
233
# but that is not accessible from here as we have no repository
234
# pointer. Note that the repository.get_graph.heads() call can return
235
# different results *at the moment* because of the kind-changing check
236
# we have in parent_candidates().
238
# eliminate ancestors amongst the available candidates:
239
# heads are those that are not an ancestor of any other candidate
240
# - this provides convergence at a per-file level.
241
def get_ancestors(weave, entry):
242
return set(weave.get_ancestry(entry.revision, topo_sorted=False))
243
# revision: ancestor list for each head
245
for ie in candidates.values():
246
# may be an ancestor of a known head:
247
already_present = 0 != len(
248
[head for head in heads
249
if ie.revision in head_ancestors[head]])
251
# an ancestor of an analyzed candidate.
253
# not an ancestor of a known head:
254
# load the versioned file for this file id if needed
256
entry_vf = versioned_file_store.get_weave_or_empty(
257
self.file_id, transaction)
258
ancestors = get_ancestors(entry_vf, ie)
259
# may knock something else out:
260
check_heads = list(heads.keys())
261
for head in check_heads:
262
if head in ancestors:
263
# this previously discovered 'head' is not
264
# really a head - its an ancestor of the newly
267
head_ancestors[ie.revision] = ancestors
268
heads[ie.revision] = ie
271
183
def get_tar_item(self, root, dp, now, tree):
272
184
"""Get a tarfile item and a file stream for its content."""
273
185
item = tarfile.TarInfo(osutils.pathjoin(root, dp).encode('utf8'))