Skip to content

Commit

Permalink
Index lookup works and provides hints en-par with git in terms of inf…
Browse files Browse the repository at this point in the history
…ormation at least. (#427)
  • Loading branch information
Byron committed Aug 2, 2022
1 parent 6d8d5e6 commit a049bd3
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 9 deletions.
34 changes: 30 additions & 4 deletions git-repository/src/revision/spec/parse/delegate.rs
Expand Up @@ -523,12 +523,38 @@ impl<'repo> delegate::Navigate for Delegate<'repo> {
}
}

fn index_lookup(&mut self, _path: &BStr, _stage: u8) -> Option<()> {
fn index_lookup(&mut self, path: &BStr, stage: u8) -> Option<()> {
self.unset_disambiguate_call();
match self.repo.index() {
Ok(_index) => {
todo!("index lookup")
}
Ok(index) => match index.entry_by_path_and_stage(path, stage.into()) {
Some(entry) => {
self.objs[self.idx]
.get_or_insert_with(HashSet::default)
.insert(entry.id);
Some(())
}
None => {
let stage_hint = [0, 1, 2]
.iter()
.filter(|our_stage| **our_stage != stage)
.find_map(|stage| {
index
.entry_index_by_path_and_stage(path, (*stage).into())
.map(|_| (*stage).into())
});
let exists = self
.repo
.work_dir()
.map_or(false, |root| root.join(git_path::from_bstr(path)).exists());
self.err.push(Error::IndexLookup {
desired_path: path.into(),
desired_stage: stage.into(),
exists,
stage_hint,
});
None
}
},
Err(err) => {
self.err.push(err.into());
None
Expand Down
7 changes: 7 additions & 0 deletions git-repository/src/revision/spec/parse/types.rs
Expand Up @@ -61,6 +61,13 @@ pub struct Options {
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("Path {desired_path:?} did not exist in index at stage {desired_stage}{}{}", stage_hint.map(|actual|format!(". It does exist at stage {actual}")).unwrap_or_default(), exists.then(|| ". It exists on disk").unwrap_or(". It does not exist on disk"))]
IndexLookup {
desired_path: BString,
desired_stage: git_index::entry::Stage,
stage_hint: Option<git_index::entry::Stage>,
exists: bool,
},
#[error(transparent)]
Index(#[from] crate::worktree::open_index::Error),
#[error(transparent)]
Expand Down
Git LFS file not shown
2 changes: 2 additions & 0 deletions git-repository/tests/fixtures/make_rev_spec_parse_repos.sh
Expand Up @@ -344,4 +344,6 @@ git init complex_graph
baseline ":/not there" # definitely not in graph
baseline "@^{/!-B}" # negation from branch
baseline ":file" # index lookup, default stage 0
baseline ":1:file" # stage 1
baseline ":foo" # not found
)
7 changes: 3 additions & 4 deletions git-repository/tests/revision/spec/from_bytes/mod.rs
Expand Up @@ -14,8 +14,7 @@ mod index {
use git_testtools::hex_to_id;

#[test]
#[ignore]
fn at_default_stage() {
fn at_stages() {
let repo = repo("complex_graph").unwrap();
assert_eq!(
parse_spec(":file", &repo).unwrap(),
Expand All @@ -24,12 +23,12 @@ mod index {

assert_eq!(
parse_spec(":1:file", &repo).unwrap_err().to_string(),
"give hint as to where to find the file in the index and if it exists on disk",
"Path \"file\" did not exist in index at stage 1. It does exist at stage 0. It exists on disk",
);

assert_eq!(
parse_spec(":foo", &repo).unwrap_err().to_string(),
"does not exist (but use same error message as above, as it's parametric)",
"Path \"foo\" did not exist in index at stage 0. It does not exist on disk",
);
}
}
Expand Down

0 comments on commit a049bd3

Please sign in to comment.