176
176
candidates[ie.revision] = ie
177
177
return candidates
179
@deprecated_method(symbol_versioning.zero_ninetyone)
180
def find_previous_heads(self, previous_inventories,
181
versioned_file_store,
184
"""Return the revisions and entries that directly precede this.
186
Returned as a map from revision to inventory entry.
188
This is a map containing the file revisions in all parents
189
for which the file exists, and its revision is not a parent of
190
any other. If the file is new, the set will be empty.
192
:param versioned_file_store: A store where ancestry data on this
193
file id can be queried.
194
:param transaction: The transaction that queries to the versioned
195
file store should be completed under.
196
:param entry_vf: The entry versioned file, if its already available.
198
candidates = self.parent_candidates(previous_inventories)
200
# revision:ie mapping with one revision for each head.
202
# common case optimisation
203
if len(candidates) == 1:
204
# if there is only one candidate revision found
205
# then we can avoid opening the versioned file to access ancestry:
206
# there cannot be any ancestors to eliminate when there is
207
# only one revision available.
210
# --- what follows is now encapsulated in repository.get_graph.heads(),
211
# but that is not accessible from here as we have no repository
212
# pointer. Note that the repository.get_graph.heads() call can return
213
# different results *at the moment* because of the kind-changing check
214
# we have in parent_candidates().
216
# eliminate ancestors amongst the available candidates:
217
# heads are those that are not an ancestor of any other candidate
218
# - this provides convergence at a per-file level.
219
def get_ancestors(weave, entry):
220
return set(weave.get_ancestry(entry.revision, topo_sorted=False))
221
# revision: ancestor list for each head
223
for ie in candidates.values():
224
# may be an ancestor of a known head:
225
already_present = 0 != len(
226
[head for head in heads
227
if ie.revision in head_ancestors[head]])
229
# an ancestor of an analyzed candidate.
231
# not an ancestor of a known head:
232
# load the versioned file for this file id if needed
234
entry_vf = versioned_file_store.get_weave_or_empty(
235
self.file_id, transaction)
236
ancestors = get_ancestors(entry_vf, ie)
237
# may knock something else out:
238
check_heads = list(heads.keys())
239
for head in check_heads:
240
if head in ancestors:
241
# this previously discovered 'head' is not
242
# really a head - its an ancestor of the newly
245
head_ancestors[ie.revision] = ancestors
246
heads[ie.revision] = ie
249
179
def get_tar_item(self, root, dp, now, tree):
250
180
"""Get a tarfile item and a file stream for its content."""
251
181
item = tarfile.TarInfo(osutils.pathjoin(root, dp).encode('utf8'))