Skip to content

Commit

Permalink
support for parent traversal (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 2, 2022
1 parent 5a0d6b7 commit aa80030
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 4 deletions.
55 changes: 53 additions & 2 deletions git-repository/src/revision/spec/parse/delegate.rs
Expand Up @@ -286,9 +286,60 @@ impl<'repo> delegate::Revision for Delegate<'repo> {
}

impl<'repo> delegate::Navigate for Delegate<'repo> {
fn traverse(&mut self, _kind: Traversal) -> Option<()> {
fn traverse(&mut self, kind: Traversal) -> Option<()> {
self.unset_disambiguate_call();
todo!()
self.follow_refs_to_objects_if_needed()?;

let mut replacements = SmallVec::<[(ObjectId, ObjectId); 1]>::default();
let mut errors = Vec::new();
let objs = self.objs[self.idx].as_mut()?;
let repo = self.repo;

for obj in objs.iter() {
match kind {
Traversal::NthParent(num) => {
match self.repo.find_object(*obj).map_err(Error::from).and_then(|obj| {
obj.try_into_commit().map_err(|err| {
let object::try_into::Error { actual, expected, id } = err;
Error::ObjectKind {
oid: id.attach(repo).shorten_or_id(),
actual,
expected,
}
})
}) {
Ok(commit) => match commit.parent_ids().skip(num.saturating_sub(1)).next() {
Some(id) => replacements.push((commit.id, id.detach())),
None => errors.push((
commit.id,
Error::ParentOutOfRange {
oid: commit.id().shorten_or_id(),
desired: num,
available: commit.parent_ids().count(),
},
)),
},
Err(err) => errors.push((*obj, err)),
}
}
Traversal::NthAncestor(_num) => todo!("ancestor"),
}
}

if errors.len() == objs.len() {
self.err.extend(errors.into_iter().map(|(_, err)| err));
None
} else {
for (obj, err) in errors {
objs.remove(&obj);
self.err.push(err);
}
for (find, replace) in replacements {
objs.remove(&find);
objs.insert(replace);
}
Some(())
}
}

fn peel_until(&mut self, kind: PeelTo<'_>) -> Option<()> {
Expand Down
6 changes: 6 additions & 0 deletions git-repository/src/revision/spec/parse/types.rs
Expand Up @@ -61,6 +61,12 @@ pub struct Options {
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("Commit {oid} has {available} parents and parent number {desired} is out of range")]
ParentOutOfRange {
oid: git_hash::Prefix,
desired: usize,
available: usize,
},
#[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,
Expand Down
Git LFS file not shown
6 changes: 6 additions & 0 deletions git-repository/tests/fixtures/make_rev_spec_parse_repos.sh
Expand Up @@ -336,6 +336,7 @@ git init complex_graph
git merge c || :
{ echo g && echo h && echo i && echo j && echo d && echo e && echo f && echo b && echo c && echo a; } > file
git add file && git commit -m A
git branch a

baseline ":/message" # finds 'message recent' instead of 'initial message'
baseline ":/!-message" # above, negated
Expand All @@ -346,4 +347,9 @@ git init complex_graph
baseline ":file" # index lookup, default stage 0
baseline ":1:file" # stage 1
baseline ":foo" # not found
# parents
baseline "a"
baseline "a^1"
baseline "a^0"
baseline "a^42"
)
22 changes: 22 additions & 0 deletions git-repository/tests/revision/spec/from_bytes/mod.rs
Expand Up @@ -7,6 +7,28 @@ pub use util::*;

mod ambiguous;
mod regex;

mod traverse {
use crate::revision::spec::from_bytes::{parse_spec, repo};
use git_repository::prelude::ObjectIdExt;
use git_repository::revision::Spec;
use git_testtools::hex_to_id;

#[test]
fn parent() {
let repo = repo("complex_graph").unwrap();
assert_eq!(
parse_spec("a^1", &repo).unwrap(),
Spec::from_id(hex_to_id("5b3f9e24965d0b28780b7ce5daf2b5b7f7e0459f").attach(&repo))
);
assert_eq!(parse_spec("a", &repo).unwrap(), parse_spec("a^0", &repo).unwrap(),);
assert_eq!(
parse_spec("a^42", &repo).unwrap_err().to_string(),
"Commit 55e825e has 2 parents and parent number 42 is out of range"
);
}
}

mod index {
use crate::revision::spec::from_bytes::{parse_spec, repo};
use git_repository::prelude::ObjectIdExt;
Expand Down

0 comments on commit aa80030

Please sign in to comment.