264
267
result[version_id] = self.get_delta(version_id)
270
def make_mpdiffs(self, version_ids):
271
"""Create multiparent diffs for specified versions"""
272
knit_versions = set()
273
for version_id in version_ids:
274
knit_versions.add(version_id)
275
knit_versions.update(self.get_parents(version_id))
276
lines = dict(zip(knit_versions,
277
self._get_lf_split_line_list(knit_versions)))
279
for version_id in version_ids:
280
target = lines[version_id]
281
parents = [lines[p] for p in self.get_parents(version_id)]
283
left_parent_blocks = self._extract_blocks(version_id,
286
left_parent_blocks = None
287
diffs.append(multiparent.MultiParent.from_lines(target, parents,
291
def _extract_blocks(self, version_id, source, target):
294
def add_mpdiffs(self, records):
295
"""Add mpdiffs to this versionedfile
297
Records should be iterables of version, parents, expected_sha1,
298
mpdiff. mpdiff should be a MultiParent instance.
301
for version, parents, expected_sha1, mpdiff in records:
302
mpvf = multiparent.MultiMemoryVersionedFile()
303
needed_parents = [p for p in parents if not mpvf.has_version(p)]
304
parent_lines = self._get_lf_split_line_list(needed_parents)
305
for parent_id, lines in zip(needed_parents, parent_lines):
306
mpvf.add_version(lines, parent_id, [])
307
mpvf.add_diff(mpdiff, version, parents)
308
lines = mpvf.get_line_list([version])[0]
309
version_text = self.add_lines(version, parents, lines, vf_parents)
310
vf_parents[version] = version_text
311
if expected_sha1 != self.get_sha1(version):
312
raise errors.VersionedFileInvalidChecksum(version)
267
314
def get_sha1(self, version_id):
268
315
"""Get the stored sha1 sum for the given revision.
272
319
raise NotImplementedError(self.get_sha1)
321
def get_sha1s(self, version_ids):
322
"""Get the stored sha1 sums for the given revisions.
324
:param version_ids: The names of the versions to lookup
325
:return: a list of sha1s in order according to the version_ids
327
raise NotImplementedError(self.get_sha1)
274
329
def get_suffixes(self):
275
330
"""Return the file suffixes associated with this versioned file."""
276
331
raise NotImplementedError(self.get_suffixes)
301
356
raise NotImplementedError(self.get_lines)
358
def _get_lf_split_line_list(self, version_ids):
359
return [StringIO(t).readlines() for t in self.get_texts(version_ids)]
303
361
def get_ancestry(self, version_ids, topo_sorted=True):
304
362
"""Return a list of all ancestors of given version(s). This
305
363
will not include the null revision.
332
390
:param version_ids: Versions to select.
333
391
None means retrieve all versions.
393
if version_ids is None:
394
return dict(self.iter_parents(self.versions()))
336
if version_ids is None:
337
for version in self.versions():
338
result[version] = self.get_parents(version)
340
pending = set(osutils.safe_revision_id(v) for v in version_ids)
342
version = pending.pop()
343
if version in result:
345
parents = self.get_parents(version)
346
for parent in parents:
396
pending = set(osutils.safe_revision_id(v) for v in version_ids)
398
this_iteration = pending
400
for version, parents in self.iter_parents(this_iteration):
350
401
result[version] = parents
402
pending.update(parents)
403
pending.difference_update(result)
353
406
def get_graph_with_ghosts(self):
444
497
raise NotImplementedError(self.iter_lines_added_or_present_in_versions)
499
def iter_parents(self, version_ids):
500
"""Iterate through the parents for many version ids.
502
:param version_ids: An iterable yielding version_ids.
503
:return: An iterator that yields (version_id, parents). Requested
504
version_ids not present in the versioned file are simply skipped.
505
The order is undefined, allowing for different optimisations in
506
the underlying implementation.
508
for version_id in version_ids:
510
yield version_id, tuple(self.get_parents(version_id))
511
except errors.RevisionNotPresent:
446
514
def transaction_finished(self):
447
515
"""The transaction that this file was opened in has finished.