Skip to content

Commit 55363ea

Browse files
committed
feat: State::entry_by_path_and_stage() to find entries. (#427)
1 parent 92de081 commit 55363ea

File tree

5 files changed

+37
-11
lines changed

5 files changed

+37
-11
lines changed

git-index/src/access.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use bstr::{BStr, ByteSlice};
22

3-
use crate::{extension, Entry, PathStorage, State, Version};
3+
use crate::{entry, extension, Entry, PathStorage, State, Version};
44

5+
/// General information and entries
56
impl State {
67
pub fn version(&self) -> Version {
78
self.version
@@ -58,6 +59,20 @@ impl State {
5859
(e, path)
5960
})
6061
}
62+
63+
/// Find the entry index in [`entries()`][State::entries()] matching the given repository-relative
64+
/// `path` and `stage`, or `None`.
65+
///
66+
/// Use the index for accessing multiple stages if they exists, but at least the single matching entry.
67+
pub fn entry_by_path_and_stage(&self, path: &BStr, stage: entry::Stage) -> Option<usize> {
68+
self.entries
69+
.binary_search_by(|e| e.path(self).cmp(path).then_with(|| e.stage().cmp(&stage)))
70+
.ok()
71+
}
72+
}
73+
74+
/// Extensions
75+
impl State {
6176
pub fn tree(&self) -> Option<&extension::Tree> {
6277
self.tree.as_ref()
6378
}

git-index/src/entry.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use bitflags::bitflags;
22

3+
/// The stage of an entry, one of 0 = base, 1 = ours, 2 = theirs
4+
pub type Stage = u32;
5+
36
bitflags! {
47
pub struct Mode: u32 {
58
/// directory (only used for sparse checkouts), equivalent to a tree
@@ -106,12 +109,12 @@ bitflags! {
106109
}
107110

108111
impl Flags {
109-
pub fn stage(&self) -> u32 {
112+
pub fn stage(&self) -> Stage {
110113
(*self & Flags::STAGE_MASK).bits >> 12
111114
}
112115
}
113116

114-
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
117+
#[derive(Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
115118
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
116119
pub struct Time {
117120
/// The amount of seconds elapsed since EPOCH
@@ -120,7 +123,7 @@ pub struct Time {
120123
pub nsecs: u32,
121124
}
122125

123-
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
126+
#[derive(Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
124127
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
125128
pub struct Stat {
126129
pub mtime: Time,
@@ -136,7 +139,7 @@ pub struct Stat {
136139
mod access {
137140
use bstr::{BStr, ByteSlice};
138141

139-
use crate::{Entry, State};
142+
use crate::{entry, Entry, State};
140143

141144
impl Entry {
142145
pub fn path<'a>(&self, state: &'a State) -> &'a BStr {
@@ -147,7 +150,7 @@ mod access {
147150
(backing[self.path.clone()]).as_bstr()
148151
}
149152

150-
pub fn stage(&self) -> u32 {
153+
pub fn stage(&self) -> entry::Stage {
151154
self.flags.stage()
152155
}
153156
}

git-index/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub enum Version {
3737
}
3838

3939
/// An entry in the index, identifying a non-tree item on disk.
40-
#[derive(Clone)]
40+
#[derive(Debug, Clone, Eq, PartialEq)]
4141
pub struct Entry {
4242
pub stat: entry::Stat,
4343
pub id: git_hash::ObjectId,

git-index/tests/index/file/access.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
use crate::index::file::read;
2+
13
#[test]
2-
#[ignore]
3-
fn entry_by_path() {
4-
todo!()
4+
fn entry_by_path_and_stage() {
5+
let file = read::file("v4_more_files_IEOT");
6+
for entry in file.entries() {
7+
let path = entry.path(&file);
8+
assert_eq!(
9+
file.entry_by_path_and_stage(path, 0).map(|idx| &file.entries()[idx]),
10+
Some(entry)
11+
);
12+
}
513
}

git-index/tests/index/file/read.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn loose_file(name: &str) -> git_index::File {
1818
let file = git_index::File::at(path, git_index::decode::Options::default()).unwrap();
1919
verify(file)
2020
}
21-
fn file(name: &str) -> git_index::File {
21+
pub(crate) fn file(name: &str) -> git_index::File {
2222
let file = git_index::File::at(crate::fixture_index_path(name), git_index::decode::Options::default()).unwrap();
2323
verify(file)
2424
}

0 commit comments

Comments
 (0)