113
113
>>> i.id2path('2326')
114
114
'src/wibble/wibble.c'
117
# Constants returned by describe_change()
119
# TODO: These should probably move to some kind of FileChangeDescription
120
# class; that's like what's inside a TreeDelta but we want to be able to
121
# generate them just for one file at a time.
123
MODIFIED_AND_RENAMED = 'modified and renamed'
117
125
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',
118
126
'text_id', 'parent_id', 'children', 'executable',
353
361
"""Clone this inventory entry."""
354
362
raise NotImplementedError
356
def _describe_snapshot_change(self, previous_entries):
357
"""Describe how this entry will have changed in a new commit.
359
:param previous_entries: Dictionary from revision_id to inventory entry.
361
:returns: One-word description: "merged", "added", "renamed", "modified".
365
def describe_change(old_entry, new_entry):
366
"""Describe the change between old_entry and this.
368
This smells of being an InterInventoryEntry situation, but as its
369
the first one, we're making it a static method for now.
371
An entry with a different parent, or different name is considered
372
to be renamed. Reparenting is an internal detail.
373
Note that renaming the parent does not trigger a rename for the
363
# XXX: This assumes that the file *has* changed -- it should probably
364
# be fused with whatever does that detection. Why not just a single
365
# thing to compare the entries?
367
# TODO: Return some kind of object describing all the possible
368
# dimensions that can change, not just a string. That can then give
369
# both old and new names for renames, etc.
371
if len(previous_entries) > 1:
373
elif len(previous_entries) == 0:
376
# TODO: Perhaps return an object rather than just a string
377
if old_entry is new_entry:
378
# also the case of both being None
380
elif old_entry is None:
375
the_parent, = previous_entries.values()
376
if self.parent_id != the_parent.parent_id:
377
# actually, moved to another directory
379
elif self.name != the_parent.name:
382
elif new_entry is None:
384
text_modified, meta_modified = new_entry.detect_changes(old_entry)
385
if text_modified or meta_modified:
389
# TODO 20060511 (mbp, rbc) factor out 'detect_rename' here.
390
if old_entry.parent_id != new_entry.parent_id:
392
elif old_entry.name != new_entry.name:
396
if renamed and not modified:
397
return InventoryEntry.RENAMED
398
if modified and not renamed:
400
if modified and renamed:
401
return InventoryEntry.MODIFIED_AND_RENAMED
383
404
def __repr__(self):
384
405
return ("%s(%r, %r, parent_id=%r)"
420
441
mutter('new revision {%s} for {%s}', revision, self.file_id)
421
442
self.revision = revision
422
change = self._describe_snapshot_change(previous_entries)
423
443
self._snapshot_text(previous_entries, work_tree, weave_store,
427
446
def _snapshot_text(self, file_parents, work_tree, weave_store, transaction):
428
447
"""Record the 'text' of this entry, whatever form that takes.
656
675
self.text_sha1 = None
657
676
self.executable = None
659
def _snapshot_text(self, file_parents, work_tree, weave_store, transaction):
678
def _snapshot_text(self, file_parents, work_tree, versionedfile_store, transaction):
660
679
"""See InventoryEntry._snapshot_text."""
661
mutter('storing file {%s} in revision {%s}',
662
self.file_id, self.revision)
680
mutter('storing text of file {%s} in revision {%s} into %r',
681
self.file_id, self.revision, versionedfile_store)
663
682
# special case to avoid diffing on renames or
665
684
if (len(file_parents) == 1
666
685
and self.text_sha1 == file_parents.values()[0].text_sha1
667
686
and self.text_size == file_parents.values()[0].text_size):
668
687
previous_ie = file_parents.values()[0]
669
versionedfile = weave_store.get_weave(self.file_id, transaction)
688
versionedfile = versionedfile_store.get_weave(self.file_id, transaction)
670
689
versionedfile.clone_text(self.revision, previous_ie.revision, file_parents.keys())
672
691
new_lines = work_tree.get_file(self.file_id).readlines()
673
self._add_text_to_weave(new_lines, file_parents.keys(), weave_store,
692
self._add_text_to_weave(new_lines, file_parents.keys(), versionedfile_store,
675
694
self.text_sha1 = sha_strings(new_lines)
676
695
self.text_size = sum(map(len, new_lines))