534
534
return KnitVersionedFile(name, transport, factory=self.factory,
535
535
delta=self.delta, create=True)
537
def _fix_parents(self, version_id, new_parents):
538
"""Fix the parents list for version.
540
This is done by appending a new version to the index
541
with identical data except for the parents list.
542
the parents list must be a superset of the current
545
current_values = self._index._cache[version_id]
546
assert set(current_values[4]).difference(set(new_parents)) == set()
547
self._index.add_version(version_id,
549
(None, current_values[2], current_values[3]),
552
537
def get_data_stream(self, required_versions):
553
538
"""Get a data stream for the specified versions.
2202
2187
self.source_ancestry = set(self.source.get_ancestry(version_ids))
2203
2188
this_versions = set(self.target._index.get_versions())
2189
# XXX: For efficiency we should not look at the whole index,
2190
# we only need to consider the referenced revisions - they
2191
# must all be present, or the method must be full-text.
2192
# TODO, RBC 20070919
2204
2193
needed_versions = self.source_ancestry - this_versions
2205
cross_check_versions = self.source_ancestry.intersection(this_versions)
2206
mismatched_versions = set()
2207
for version in cross_check_versions:
2208
# scan to include needed parents.
2209
n1 = set(self.target.get_parents_with_ghosts(version))
2210
n2 = set(self.source.get_parents_with_ghosts(version))
2212
# FIXME TEST this check for cycles being introduced works
2213
# the logic is we have a cycle if in our graph we are an
2214
# ancestor of any of the n2 revisions.
2220
parent_ancestors = self.source.get_ancestry(parent)
2221
if version in parent_ancestors:
2222
raise errors.GraphCycleError([parent, version])
2223
# ensure this parent will be available later.
2224
new_parents = n2.difference(n1)
2225
needed_versions.update(new_parents.difference(this_versions))
2226
mismatched_versions.add(version)
2228
if not needed_versions and not mismatched_versions:
2195
if not needed_versions:
2230
2197
full_list = topo_sort(self.source.get_graph())
2268
2235
raw_records.append((version_id, options, parents, len(raw_data)))
2269
2236
raw_datum.append(raw_data)
2270
2237
self.target._add_raw_records(raw_records, ''.join(raw_datum))
2272
for version in mismatched_versions:
2273
# FIXME RBC 20060309 is this needed?
2274
n1 = set(self.target.get_parents_with_ghosts(version))
2275
n2 = set(self.source.get_parents_with_ghosts(version))
2276
# write a combined record to our history preserving the current
2277
# parents as first in the list
2278
new_parents = self.target.get_parents_with_ghosts(version) + list(n2.difference(n1))
2279
self.target.fix_parents(version, new_parents)
2317
2275
self.source_ancestry = set(self.source.get_ancestry(version_ids))
2318
2276
this_versions = set(self.target._index.get_versions())
2319
2277
needed_versions = self.source_ancestry - this_versions
2320
cross_check_versions = self.source_ancestry.intersection(this_versions)
2321
mismatched_versions = set()
2322
for version in cross_check_versions:
2323
# scan to include needed parents.
2324
n1 = set(self.target.get_parents_with_ghosts(version))
2325
n2 = set(self.source.get_parents(version))
2326
# if all of n2's parents are in n1, then its fine.
2327
if n2.difference(n1):
2328
# FIXME TEST this check for cycles being introduced works
2329
# the logic is we have a cycle if in our graph we are an
2330
# ancestor of any of the n2 revisions.
2336
parent_ancestors = self.source.get_ancestry(parent)
2337
if version in parent_ancestors:
2338
raise errors.GraphCycleError([parent, version])
2339
# ensure this parent will be available later.
2340
new_parents = n2.difference(n1)
2341
needed_versions.update(new_parents.difference(this_versions))
2342
mismatched_versions.add(version)
2344
if not needed_versions and not mismatched_versions:
2279
if not needed_versions:
2346
2281
full_list = topo_sort(self.source.get_graph())
2361
2296
self.target.add_lines(
2362
2297
version_id, parents, self.source.get_lines(version_id))
2363
2298
count = count + 1
2365
for version in mismatched_versions:
2366
# FIXME RBC 20060309 is this needed?
2367
n1 = set(self.target.get_parents_with_ghosts(version))
2368
n2 = set(self.source.get_parents(version))
2369
# write a combined record to our history preserving the current
2370
# parents as first in the list
2371
new_parents = self.target.get_parents_with_ghosts(version) + list(n2.difference(n1))
2372
self.target.fix_parents(version, new_parents)