323
323
parent_invs = map(self._load_updated_inventory, present_parents)
324
324
for file_id in inv:
325
325
ie = inv[file_id]
326
self._set_revision(rev, ie, parent_invs)
327
if not ie.has_text():
329
326
self._convert_file_version(rev, ie, parent_invs)
332
def _set_revision(self, rev, ie, parent_invs):
333
"""Set name version for a file.
335
Done in a slightly lazy way: if the file is renamed or in a merge revision
336
it gets a new version, otherwise the same as before.
339
if ie.kind == 'root_directory':
341
if len(parent_invs) != 1:
342
ie.revision = rev.revision_id
344
old_inv = parent_invs[0]
345
if not old_inv.has_id(file_id):
346
ie.revision = rev.revision_id
348
old_ie = old_inv[file_id]
349
if (old_ie.parent_id != ie.parent_id
350
or old_ie.name != ie.name):
351
ie.revision = rev.revision_id
353
ie.revision = old_ie.revision
357
328
def _convert_file_version(self, rev, ie, parent_invs):
358
329
"""Convert one version of one file.
360
331
The file needs to be added into the weave if it is a merge
361
332
of >=2 parents or if it's changed from its parent.
334
if ie.kind == 'root_directory':
363
336
file_id = ie.file_id
364
337
rev_id = rev.revision_id
365
338
w = self.text_weaves.get(file_id)
367
340
w = Weave(file_id)
368
341
self.text_weaves[file_id] = w
370
342
text_changed = False
343
previous_revisions = {}
371
344
for parent_inv in parent_invs:
372
345
if parent_inv.has_id(file_id):
373
parent_ie = parent_inv[file_id]
374
old_revision = parent_ie.revision
346
previous_ie = parent_inv[file_id]
347
if previous_ie.revision in previous_revisions:
348
assert previous_revisions[previous_ie.revision] == previous_ie
350
previous_revisions[previous_ie.revision] = previous_ie
351
old_revision = previous_ie.revision
352
for old_revision in previous_revisions:
375
353
# if this fails, its a ghost ?
376
354
assert old_revision in self.converted_revs
377
if old_revision not in file_parents:
378
file_parents.append(old_revision)
379
if parent_ie.text_sha1 != ie.text_sha1:
381
if len(file_parents) != 1 or text_changed:
355
self.snapshot_ie(previous_revisions, ie, w, rev_id)
357
assert getattr(ie, 'revision', None) is not None
359
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
360
# TODO: convert this logic, which is ~= snapshot to
361
# a call to:. This needs the path figured out. rather than a work_tree
362
# a v4 revision_tree can be given, or something that can give the
363
# text for the ie if it needs it.
364
# and we need something that looks like a weave store for snapshot to
366
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
367
if len(previous_revisions) == 1:
368
previous_ie = previous_revisions.values()[0]
369
if ie._unchanged(previous_ie):
370
ie.revision = previous_ie.revision
372
parent_indexes = map(w.lookup, previous_revisions)
382
374
file_lines = self.branch.text_store[ie.text_id].readlines()
383
375
assert sha_strings(file_lines) == ie.text_sha1
384
376
assert sum(map(len, file_lines)) == ie.text_size
385
w.add(rev_id, file_parents, file_lines, ie.text_sha1)
377
w.add(rev_id, parent_indexes, file_lines, ie.text_sha1)
387
378
self.text_count += 1
388
##mutter('import text {%s} of {%s}',
389
## ie.text_id, file_id)
391
##mutter('text of {%s} unchanged from parent', file_id)
392
ie.revision = file_parents[0]
380
w.add(rev_id, parent_indexes, [], None)
382
##mutter('import text {%s} of {%s}',
383
## ie.text_id, file_id)
397
385
def _make_order(self):
398
386
"""Return a suitable order for importing revisions.