pub struct Entry {
pub stat: Stat,
pub id: ObjectId,
pub flags: Flags,
pub mode: Mode,
/* private fields */
}
Expand description
An entry in the index, identifying a non-tree item on disk.
Fields§
§stat: Stat
The filesystem stat information for the file on disk.
id: ObjectId
The object id for this entry’s ODB representation (assuming it’s up-to-date with it).
flags: Flags
Additional flags for use in algorithms and for efficiently storing stage information.
mode: Mode
The kind of item this entry represents - it’s not all blobs in the index anymore.
Implementations§
source§impl Entry
impl Entry
sourcepub fn write_to(&self, out: impl Write, state: &State) -> Result<()>
pub fn write_to(&self, out: impl Write, state: &State) -> Result<()>
Serialize ourselves to out
with path access via state
, without padding.
Examples found in repository?
151 152 153 154 155 156 157 158 159 160 161 162 163 164
fn entries<T: std::io::Write>(out: &mut CountBytes<T>, state: &State, header_size: u32) -> Result<u32, std::io::Error> {
for entry in state.entries() {
entry.write_to(&mut *out, state)?;
match (out.count - header_size) % 8 {
0 => {}
n => {
let eight_null_bytes = [0u8; 8];
out.write_all(&eight_null_bytes[n as usize..])?;
}
};
}
Ok(out.count)
}
source§impl Entry
impl Entry
sourcepub fn path<'a>(&self, state: &'a State) -> &'a BStr
pub fn path<'a>(&self, state: &'a State) -> &'a BStr
Return an entry’s path, relative to the repository, which is extracted from its owning state
.
Examples found in repository?
More examples
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
pub fn entries_with_paths_by_filter_map<'a, T>(
&'a self,
mut filter_map: impl FnMut(&'a BStr, &Entry) -> Option<T> + 'a,
) -> impl Iterator<Item = (&'a BStr, T)> + 'a {
self.entries.iter().filter_map(move |e| {
let p = e.path(self);
filter_map(p, e).map(|t| (p, t))
})
}
/// Return mutable entries in a slice.
pub fn entries_mut(&mut self) -> &mut [Entry] {
&mut self.entries
}
/// Return mutable entries along with their paths in an iterator.
pub fn entries_mut_with_paths(&mut self) -> impl Iterator<Item = (&mut Entry, &BStr)> {
let paths = &self.path_backing;
self.entries.iter_mut().map(move |e| {
let path = paths[e.path.clone()].as_bstr();
(e, path)
})
}
/// Return mutable entries along with their path, as obtained from `backing`.
pub fn entries_mut_with_paths_in<'state, 'backing>(
&'state mut self,
backing: &'backing PathStorage,
) -> impl Iterator<Item = (&'state mut Entry, &'backing BStr)> {
self.entries.iter_mut().map(move |e| {
let path = backing[e.path.clone()].as_bstr();
(e, path)
})
}
/// Find the entry index in [`entries()`][State::entries()] matching the given repository-relative
/// `path` and `stage`, or `None`.
///
/// Use the index for accessing multiple stages if they exists, but at least the single matching entry.
pub fn entry_index_by_path_and_stage(&self, path: &BStr, stage: entry::Stage) -> Option<usize> {
self.entries
.binary_search_by(|e| e.path(self).cmp(path).then_with(|| e.stage().cmp(&stage)))
.ok()
}
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
pub fn verify_entries(&self) -> Result<(), entries::Error> {
let mut previous = None::<&crate::Entry>;
for (idx, entry) in self.entries.iter().enumerate() {
if let Some(prev) = previous {
if prev.cmp(entry, self) != Ordering::Less {
return Err(entries::Error::OutOfOrder {
current_index: idx,
current_path: entry.path(self).into(),
current_stage: entry.flags.stage() as u8,
previous_path: prev.path(self).into(),
previous_stage: prev.flags.stage() as u8,
});
}
}
previous = Some(entry);
}
Ok(())
}
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
pub fn write_to(&self, mut out: impl std::io::Write, state: &State) -> std::io::Result<()> {
let stat = self.stat;
out.write_all(&stat.ctime.secs.to_be_bytes())?;
out.write_all(&stat.ctime.nsecs.to_be_bytes())?;
out.write_all(&stat.mtime.secs.to_be_bytes())?;
out.write_all(&stat.mtime.nsecs.to_be_bytes())?;
out.write_all(&stat.dev.to_be_bytes())?;
out.write_all(&stat.ino.to_be_bytes())?;
out.write_all(&self.mode.bits().to_be_bytes())?;
out.write_all(&stat.uid.to_be_bytes())?;
out.write_all(&stat.gid.to_be_bytes())?;
out.write_all(&stat.size.to_be_bytes())?;
out.write_all(self.id.as_bytes())?;
let path = self.path(state);
let path_len: u16 = if path.len() >= entry::Flags::PATH_LEN.bits() as usize {
entry::Flags::PATH_LEN.bits() as u16
} else {
path.len()
.try_into()
.expect("we just checked that the length is smaller than 0xfff")
};
out.write_all(&(self.flags.to_storage().bits() | path_len).to_be_bytes())?;
if self.flags.contains(entry::Flags::EXTENDED) {
out.write_all(
&entry::at_rest::FlagsExtended::from_flags(self.flags)
.bits()
.to_be_bytes(),
)?;
}
out.write_all(path)?;
out.write_all(b"\0")
}
sourcepub fn path_in<'backing>(
&self,
backing: &'backing PathStorageRef
) -> &'backing BStr
pub fn path_in<'backing>(
&self,
backing: &'backing PathStorageRef
) -> &'backing BStr
Return an entry’s path using the given backing
.
Examples found in repository?
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
pub fn from_tree<Find>(tree: &git_hash::oid, mut find: Find) -> Result<Self, breadthfirst::Error>
where
Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<TreeRefIter<'a>>,
{
let mut buf = Vec::new();
let root = find(tree, &mut buf).ok_or(breadthfirst::Error::NotFound { oid: tree.into() })?;
let mut delegate = CollectEntries::new();
breadthfirst(root, breadthfirst::State::default(), &mut find, &mut delegate)?;
let CollectEntries {
mut entries,
path_backing,
path: _,
path_deque: _,
} = delegate;
entries.sort_by(|a, b| Entry::cmp_filepaths(a.path_in(&path_backing), b.path_in(&path_backing)));
Ok(State {
object_hash: tree.kind(),
timestamp: filetime::FileTime::now(),
version: Version::V2,
entries,
path_backing,
is_sparse: false,
tree: None,
link: None,
resolve_undo: None,
untracked: None,
fs_monitor: None,
})
}
sourcepub fn stage(&self) -> Stage
pub fn stage(&self) -> Stage
Return an entry’s stage.
Examples found in repository?
More examples
source§impl Entry
impl Entry
sourcepub fn cmp(&self, other: &Self, state: &State) -> Ordering
pub fn cmp(&self, other: &Self, state: &State) -> Ordering
Compare one entry to another by their path, by comparing only their common path portion byte by byte, then resorting to entry length and stage.
Examples found in repository?
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
pub fn verify_entries(&self) -> Result<(), entries::Error> {
let mut previous = None::<&crate::Entry>;
for (idx, entry) in self.entries.iter().enumerate() {
if let Some(prev) = previous {
if prev.cmp(entry, self) != Ordering::Less {
return Err(entries::Error::OutOfOrder {
current_index: idx,
current_path: entry.path(self).into(),
current_stage: entry.flags.stage() as u8,
previous_path: prev.path(self).into(),
previous_stage: prev.flags.stage() as u8,
});
}
}
previous = Some(entry);
}
Ok(())
}
sourcepub fn cmp_filepaths(a: &BStr, b: &BStr) -> Ordering
pub fn cmp_filepaths(a: &BStr, b: &BStr) -> Ordering
Compare one entry to another by their path, by comparing only their common path portion byte by byte, then resorting to entry length.
Examples found in repository?
More examples
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
pub fn from_tree<Find>(tree: &git_hash::oid, mut find: Find) -> Result<Self, breadthfirst::Error>
where
Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<TreeRefIter<'a>>,
{
let mut buf = Vec::new();
let root = find(tree, &mut buf).ok_or(breadthfirst::Error::NotFound { oid: tree.into() })?;
let mut delegate = CollectEntries::new();
breadthfirst(root, breadthfirst::State::default(), &mut find, &mut delegate)?;
let CollectEntries {
mut entries,
path_backing,
path: _,
path_deque: _,
} = delegate;
entries.sort_by(|a, b| Entry::cmp_filepaths(a.path_in(&path_backing), b.path_in(&path_backing)));
Ok(State {
object_hash: tree.kind(),
timestamp: filetime::FileTime::now(),
version: Version::V2,
entries,
path_backing,
is_sparse: false,
tree: None,
link: None,
resolve_undo: None,
untracked: None,
fs_monitor: None,
})
}