Skip to content

Commit

Permalink
support for ancestor traversal (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 2, 2022
1 parent 6ffbf4c commit ac2105f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
29 changes: 28 additions & 1 deletion git-repository/src/revision/spec/parse/delegate.rs
Expand Up @@ -324,7 +324,34 @@ impl<'repo> delegate::Navigate for Delegate<'repo> {
Err(err) => errors.push((*obj, err)),
}
}
Traversal::NthAncestor(_num) => todo!("ancestor"),
Traversal::NthAncestor(num) => {
let id = obj.attach(repo);
match id
.ancestors()
.first_parent_only()
.all()
.expect("cannot fail without sorting")
.skip(num)
.filter_map(Result::ok)
.next()
{
Some(id) => replacements.push((*obj, id.detach())),
None => errors.push((
*obj,
Error::AncestorOutOfRange {
oid: id.shorten_or_id(),
desired: num,
available: id
.ancestors()
.first_parent_only()
.all()
.expect("cannot fail without sorting")
.skip(1)
.count(),
},
)),
}
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions git-repository/src/revision/spec/parse/types.rs
Expand Up @@ -61,6 +61,14 @@ pub struct Options {
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(
"Commit {oid} has {available} ancestors along the first parent and ancestor number {desired} is out of range"
)]
AncestorOutOfRange {
oid: git_hash::Prefix,
desired: usize,
available: usize,
},
#[error("Commit {oid} has {available} parents and parent number {desired} is out of range")]
ParentOutOfRange {
oid: git_hash::Prefix,
Expand Down
Git LFS file not shown
4 changes: 4 additions & 0 deletions git-repository/tests/fixtures/make_rev_spec_parse_repos.sh
Expand Up @@ -350,6 +350,10 @@ git init complex_graph
# parents
baseline "a"
baseline "a^1"
baseline "a~1"
baseline "a^0"
baseline "a~0"
baseline "a^42"
baseline "a~42"
baseline "a~3"
)
18 changes: 18 additions & 0 deletions git-repository/tests/revision/spec/from_bytes/mod.rs
Expand Up @@ -27,6 +27,24 @@ mod traverse {
"Commit 55e825e has 2 parents and parent number 42 is out of range"
);
}

#[test]
fn ancestors() {
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~3", &repo).unwrap(),
Spec::from_id(hex_to_id("9f9eac6bd1cd4b4cc6a494f044b28c985a22972b").attach(&repo))
);
assert_eq!(
parse_spec("a~42", &repo).unwrap_err().to_string(),
"Commit 55e825e has 3 ancestors along the first parent and ancestor number 42 is out of range"
);
}
}

mod index {
Expand Down

0 comments on commit ac2105f

Please sign in to comment.