Skip to content

Commit

Permalink
feat: State::entry_by_path_and_stage() to find entries. (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 2, 2022
1 parent 92de081 commit 55363ea
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 11 deletions.
17 changes: 16 additions & 1 deletion git-index/src/access.rs
@@ -1,7 +1,8 @@
use bstr::{BStr, ByteSlice};

use crate::{extension, Entry, PathStorage, State, Version};
use crate::{entry, extension, Entry, PathStorage, State, Version};

/// General information and entries
impl State {
pub fn version(&self) -> Version {
self.version
Expand Down Expand Up @@ -58,6 +59,20 @@ impl State {
(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_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()
}
}

/// Extensions
impl State {
pub fn tree(&self) -> Option<&extension::Tree> {
self.tree.as_ref()
}
Expand Down
13 changes: 8 additions & 5 deletions git-index/src/entry.rs
@@ -1,5 +1,8 @@
use bitflags::bitflags;

/// The stage of an entry, one of 0 = base, 1 = ours, 2 = theirs
pub type Stage = u32;

bitflags! {
pub struct Mode: u32 {
/// directory (only used for sparse checkouts), equivalent to a tree
Expand Down Expand Up @@ -106,12 +109,12 @@ bitflags! {
}

impl Flags {
pub fn stage(&self) -> u32 {
pub fn stage(&self) -> Stage {
(*self & Flags::STAGE_MASK).bits >> 12
}
}

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

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

use crate::{Entry, State};
use crate::{entry, Entry, State};

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

pub fn stage(&self) -> u32 {
pub fn stage(&self) -> entry::Stage {
self.flags.stage()
}
}
Expand Down
2 changes: 1 addition & 1 deletion git-index/src/lib.rs
Expand Up @@ -37,7 +37,7 @@ pub enum Version {
}

/// An entry in the index, identifying a non-tree item on disk.
#[derive(Clone)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Entry {
pub stat: entry::Stat,
pub id: git_hash::ObjectId,
Expand Down
14 changes: 11 additions & 3 deletions git-index/tests/index/file/access.rs
@@ -1,5 +1,13 @@
use crate::index::file::read;

#[test]
#[ignore]
fn entry_by_path() {
todo!()
fn entry_by_path_and_stage() {
let file = read::file("v4_more_files_IEOT");
for entry in file.entries() {
let path = entry.path(&file);
assert_eq!(
file.entry_by_path_and_stage(path, 0).map(|idx| &file.entries()[idx]),
Some(entry)
);
}
}
2 changes: 1 addition & 1 deletion git-index/tests/index/file/read.rs
Expand Up @@ -18,7 +18,7 @@ fn loose_file(name: &str) -> git_index::File {
let file = git_index::File::at(path, git_index::decode::Options::default()).unwrap();
verify(file)
}
fn file(name: &str) -> git_index::File {
pub(crate) fn file(name: &str) -> git_index::File {
let file = git_index::File::at(crate::fixture_index_path(name), git_index::decode::Options::default()).unwrap();
verify(file)
}
Expand Down

0 comments on commit 55363ea

Please sign in to comment.