pub struct Index {
pub entries: Vec<IndexEntry>,
/* private fields */
}Expand description
In-memory staging index.
entries stays pub for the many read-only call sites across the CLI
(.iter(), indexing, .len()) that predate the path index below and
have no reason to route through a method. Any code that mutates
entries — inserting, removing, or reordering — MUST go through
Index::upsert_entry, Index::remove_entry_at,
Index::remove_path, or Index::retain_entries instead of touching
the Vec directly, or by_path silently goes stale (see those methods’
docs). In-place field mutation of an entry already at a known position
(status/hash/stat-cache updates that leave path unchanged) is fine
either way, since it never moves or renames anything by_path tracks.
Fields§
§entries: Vec<IndexEntry>Entries in insertion order.
Implementations§
Source§impl Index
impl Index
Sourcepub fn find_entry(&self, path: &str) -> Option<usize>
pub fn find_entry(&self, path: &str) -> Option<usize>
Find an entry by path. O(log n).
Sourcepub fn tracks_path_or_descendant(&self, path: &str) -> bool
pub fn tracks_path_or_descendant(&self, path: &str) -> bool
true if path is itself tracked (a non-removed entry) or is an
ancestor directory of a tracked path. Used to decide whether an
ignored worktree path must still be visited because it (or its
subtree) holds tracked content. O(log n + k), k = number of
tracked entries directly under path.
Sourcepub fn has_tracked_file_at(&self, path: &str) -> bool
pub fn has_tracked_file_at(&self, path: &str) -> bool
true if a tracked (non-removed) entry exists at exactly path.
Because the index stores only leaf paths (files / symlinks / exec
files, never directories), a hit means path is tracked as a
non-directory object. Used by the untracked-discovery walks to detect
a worktree directory that shadows a tracked file: git suppresses the
directory’s contents as untracked in that case (#288), reporting only
the tracked-side deletion. A Removed tombstone does not count —
the path is no longer tracked, so its replacement is genuinely
untracked. O(log n).
Sourcepub fn staged_count(&self) -> usize
pub fn staged_count(&self) -> usize
Count non-removed entries.
Sourcepub fn upsert_entry(&mut self, entry: IndexEntry)
pub fn upsert_entry(&mut self, entry: IndexEntry)
Insert entry, replacing any existing entry at the same path.
O(log n). The sanctioned way to add or wholesale-replace an
entry — unlike a direct entries.push/entries[i] = entry, this
keeps by_path in lockstep.
Sourcepub fn remove_entry_at(&mut self, pos: usize) -> IndexEntry
pub fn remove_entry_at(&mut self, pos: usize) -> IndexEntry
Remove and return the entry at pos. O(n) — same asymptotic cost
as the underlying Vec::remove shift (every later entry’s position
changes), so by_path is fully rebuilt. Intended for single-path
removals (rm/restore/conflict abort), not a per-file staging
loop.
§Panics
Panics if pos >= self.entries.len() (same as Vec::remove).
Sourcepub fn remove_path(&mut self, path: &str) -> Option<IndexEntry>
pub fn remove_path(&mut self, path: &str) -> Option<IndexEntry>
Remove the entry at path, if any tracked or tombstoned entry
exists there. O(log n) to find it, O(n) to remove (see
Index::remove_entry_at).
Sourcepub fn retain_entries(&mut self, keep: impl FnMut(&IndexEntry) -> bool)
pub fn retain_entries(&mut self, keep: impl FnMut(&IndexEntry) -> bool)
Retain only entries matching keep, rebuilding by_path in one
pass afterward. O(n) — the same cost Vec::retain already pays.
Sourcepub fn remove_directory_conflicts(&mut self, path: &str)
pub fn remove_directory_conflicts(&mut self, path: &str)
Remove any entry that conflicts with staging path as a file leaf:
a tracked ancestor directory-as-file (blocks descending into it), or
a tracked descendant nested under path treated as a directory (the
reverse conflict). An entry at exactly path is left untouched —
callers replace/insert it separately via Index::upsert_entry.
O(depth) in the common case where staging path has no conflict
(checked via by_path rather than a full scan of the index); falls
back to an O(n) retain + rebuild only when a conflict is actually
found, which is rare relative to the number of files staged.
Trait Implementations§
impl Eq for Index
Source§impl PartialEq for Index
Value equality compares staged content only — by_path is a derived
lookup cache, not user-visible state, and two indexes with identical
entries are equal regardless of whether their caches happen to be
populated (e.g. one built via deserialize, the other via
entries.push in a test fixture that never queries it).
impl PartialEq for Index
Value equality compares staged content only — by_path is a derived
lookup cache, not user-visible state, and two indexes with identical
entries are equal regardless of whether their caches happen to be
populated (e.g. one built via deserialize, the other via
entries.push in a test fixture that never queries it).
Auto Trait Implementations§
impl Freeze for Index
impl RefUnwindSafe for Index
impl Send for Index
impl Sync for Index
impl Unpin for Index
impl UnsafeUnpin for Index
impl UnwindSafe for Index
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more