1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
use crate::bstr::BStr;
use git_object::tree::EntryMode;
use crate::Id;
/// An event emitted when finding differences between two trees.
#[derive(Debug, Clone, Copy)]
pub enum Event<'a, 'old, 'new> {
/// An entry was added, like the addition of a file or directory.
Addition {
/// The mode of the added entry.
entry_mode: git_object::tree::EntryMode,
/// The object id of the added entry.
id: Id<'new>,
},
/// An entry was deleted, like the deletion of a file or directory.
Deletion {
/// The mode of the deleted entry.
entry_mode: git_object::tree::EntryMode,
/// The object id of the deleted entry.
id: Id<'old>,
},
/// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning
/// a file into a symbolic link adjusts its mode.
Modification {
/// The mode of the entry before the modification.
previous_entry_mode: git_object::tree::EntryMode,
/// The object id of the entry before the modification.
previous_id: Id<'old>,
/// The mode of the entry after the modification.
entry_mode: git_object::tree::EntryMode,
/// The object id after the modification.
id: Id<'new>,
},
/// Entries are considered renamed if they are not trees and they, according to some understanding of identity, appeared
/// as [`Deletion`][Event::Deletion] in case of the previous source of the rename as well as [`Addition`][Event::Addition]
/// acting as destination all the while [rename tracking][super::Platform::track_renames()] is enabled.
///
/// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa.
Rename {
/// The location of the source of the rename operation.
///
/// It may be empty if neither [file names][super::Platform::track_filename()] nor [file paths][super::Platform::track_path()]
/// are tracked.
source_location: &'a BStr,
/// The mode of the entry before the rename.
source_entry_mode: git_object::tree::EntryMode,
/// The object id of the entry before the rename.
///
/// Note that this is the same as `id` if we require the [similarity to be 100%][super::Renames::percentage], but may
/// be different otherwise.
source_id: Id<'old>,
/// The mode of the entry after the rename.
/// It could differ but still be considered a rename as we are concerned only about content.
entry_mode: git_object::tree::EntryMode,
/// The object id after the rename.
id: Id<'new>,
},
/// This entry is considered to be a copy of another, according to some understanding of identity, as its source still exists.
/// If the source wouldn't exist, it would be considered a [rename][Event::Rename].
///
/// This variant may only occur if [rename tracking][super::Platform::track_renames()] is enabled, otherwise copies appear to be
/// plain [additions][Event::Addition].
Copy {
/// The location of the source of the copy operation.
///
/// It may be empty if neither [file names][super::Platform::track_filename()] nor [file paths][super::Platform::track_path()]
/// are tracked.
source_location: &'a BStr,
/// The mode of the entry that is considered the source.
source_entry_mode: git_object::tree::EntryMode,
/// The object id of the source of the copy.
///
/// Note that this is the same as `id` if we require the [similarity to be 100%][super::Renames::percentage], but may
/// be different otherwise.
source_id: Id<'old>,
/// The mode of the entry after the copy, or the destination of it.
/// It could differ but still be considered a copy as we are concerned only about content.
entry_mode: git_object::tree::EntryMode,
/// The object id after the copy, or the destination of it.
id: Id<'new>,
},
}
impl<'a, 'old, 'new> Event<'a, 'old, 'new> {
/// Produce a platform for performing a line-diff, or `None` if this is not a [`Modification`][Event::Modification]
/// or one of the entries to compare is not a blob.
pub fn diff(
&self,
) -> Option<Result<crate::object::blob::diff::Platform<'old, 'new>, crate::object::blob::diff::init::Error>> {
match self {
Event::Modification {
previous_entry_mode: EntryMode::BlobExecutable | EntryMode::Blob,
previous_id,
entry_mode: EntryMode::BlobExecutable | EntryMode::Blob,
id,
} => Some(crate::object::blob::diff::Platform::from_ids(previous_id, id)),
_ => None,
}
}
/// Return the current mode of this instance.
pub fn entry_mode(&self) -> git_object::tree::EntryMode {
match self {
Event::Addition { entry_mode, .. }
| Event::Deletion { entry_mode, .. }
| Event::Modification { entry_mode, .. }
| Event::Rename { entry_mode, .. } => *entry_mode,
Event::Copy { entry_mode, .. } => *entry_mode,
}
}
}