398
402
return self._parents[version]
405
def parent_names(self, version):
406
"""Return version names for parents of a version."""
407
return map(self.idx_to_name, self._parents[self.lookup(version)])
401
410
def minimal_parents(self, version):
402
411
"""Find the minimal set of parents for the version."""
403
412
included = self._parents[version]
774
783
retrieved from self after this call.
776
785
It is illegal for the two weaves to contain different values
786
or different parents for any version. See also reweave().
779
788
if other.numversions() == 0:
780
789
return # nothing to update, easy
790
# two loops so that we do not change ourselves before verifying it
781
792
# work through in index order to make sure we get all dependencies
782
793
for other_idx, name in enumerate(other._names):
794
if self._check_version_consistent(other, other_idx, name):
796
for other_idx, name in enumerate(other._names):
783
797
# TODO: If all the parents of the other version are already
784
798
# present then we can avoid some work by just taking the delta
785
799
# and adjusting the offsets.
786
if self._check_version_consistent(other, other_idx, name):
788
800
new_parents = self._imported_parents(other, other_idx)
789
801
lines = other.get_lines(other_idx)
790
802
sha1 = other._sha1s[other_idx]
831
raise WeaveError("inconsistent parents for version {%s}: "
843
raise WeaveParentMismatch("inconsistent parents "
844
"for version {%s}: %s vs %s" % (name, n1, n2))
835
846
return True # ok!
850
def reweave(self, other):
851
"""Reweave self with other."""
852
new_weave = reweave(self, other)
853
for attr in self.__slots__:
854
setattr(self, attr, getattr(new_weave, attr))
858
"""Combine two weaves and return the result.
860
This works even if a revision R has different parents in
861
wa and wb. In the resulting weave all the parents are given.
863
This is done by just building up a new weave, maintaining ordering
864
of the versions in the two inputs. More efficient approaches
865
might be possible but it should only be necessary to do
866
this operation rarely, when a new previously ghost version is
871
queue_a = range(wa.numversions())
872
queue_b = range(wb.numversions())
873
# first determine combined parents of all versions
874
# map from version name -> all parent names
875
combined_parents = _reweave_parent_graphs(wa, wb)
876
mutter("combined parents: %r", combined_parents)
877
order = _make_reweave_order(wa._names, wb._names, combined_parents)
878
mutter("order to reweave: %r", order)
880
if name in wa._name_map:
881
lines = wa.get_lines(name)
882
if name in wb._name_map:
883
assert lines == wb.get_lines(name)
885
lines = wb.get_lines(name)
886
wr.add(name, combined_parents[name], lines)
890
def _reweave_parent_graphs(wa, wb):
891
"""Return combined parent ancestry for two weaves.
893
Returned as a list of (version_name, set(parent_names))"""
895
for weave in [wa, wb]:
896
for idx, name in enumerate(weave._names):
897
p = combined.setdefault(name, set())
898
p.update(map(weave.idx_to_name, weave._parents[idx]))
902
def _make_reweave_order(wa_order, wb_order, combined_parents):
903
"""Return an order to reweave versions respecting parents."""
907
next_a = next_b = None
908
len_a = len(wa_order)
909
len_b = len(wb_order)
910
while ia < len(wa_order) or ib < len(wb_order):
912
next_a = wa_order[ia]
916
if combined_parents[next_a].issubset(done):
918
result.append(next_a)
922
next_b = wb_order[ib]
926
elif combined_parents[next_b].issubset(done):
928
result.append(next_b)
931
raise WeaveError("don't know how to reweave at {%s} and {%s}"
840
936
def weave_toc(w):
841
937
"""Show the weave's table-of-contents"""