Skip to content

Commit

Permalink
feat: handle RefLogLookup::Date
Browse files Browse the repository at this point in the history
  • Loading branch information
dvtkrlbs authored and Byron committed Dec 21, 2024
1 parent ca54b8c commit d0df20a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
51 changes: 45 additions & 6 deletions gix/src/revision/spec/parse/delegate/revision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,51 @@ impl delegate::Revision for Delegate<'_> {
fn reflog(&mut self, query: ReflogLookup) -> Option<()> {
self.unset_disambiguate_call();
match query {
ReflogLookup::Date(_date) => {
// TODO: actually do this - this should be possible now despite incomplete date parsing
self.err.push(Error::Planned {
dependency: "remote handling and ref-specs are fleshed out more",
});
None
ReflogLookup::Date(date) => {
let r = match &mut self.refs[self.idx] {
Some(r) => r.clone().attach(self.repo),
val @ None => match self.repo.head().map(crate::Head::try_into_referent) {
Ok(Some(r)) => {
*val = Some(r.clone().detach());
r
}
Ok(None) => {
self.err.push(Error::UnbornHeadsHaveNoRefLog);
return None;
}
Err(err) => {
self.err.push(err.into());
return None;
}
},
};

let mut platform = r.log_iter();
match platform.rev().ok().flatten() {
Some(it) => match it
.filter_map(Result::ok)
.min_by_key(|l| (date - l.signature.time).abs())
{
Some(closest_line) => {
self.objs[self.idx]
.get_or_insert_with(HashSet::default)
.insert(closest_line.new_oid);
Some(())
}
None => {
// do we need an another error variant?
self.err.push(Error::SingleNotFound);
None
}
},
None => {
self.err.push(Error::MissingRefLog {
reference: r.name().as_bstr().into(),
action: "lookup entry",
});
None
}
}
}
ReflogLookup::Entry(no) => {
let r = match &mut self.refs[self.idx] {
Expand Down
4 changes: 2 additions & 2 deletions gix/src/revision/spec/parse/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ pub enum Error {
direction: remote::Direction,
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},
#[error("This feature will be implemented once {dependency}")]
Planned { dependency: &'static str },
#[error("Reference {reference:?} does not have a reference log, cannot {action}")]
MissingRefLog { reference: BString, action: &'static str },
#[error("HEAD has {available} prior checkouts and checkout number {desired} is out of range")]
Expand Down Expand Up @@ -194,4 +192,6 @@ pub enum Error {
Walk(#[from] crate::revision::walk::Error),
#[error("Spec does not contain a single object id")]
SingleNotFound,
#[error("Reflog does not contain any entries")]
EmptyReflog,
}
18 changes: 9 additions & 9 deletions gix/tests/gix/revision/spec/from_bytes/reflog.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use gix::{
prelude::ObjectIdExt,
revision::{spec::parse::Error, Spec},
};
use gix::{prelude::ObjectIdExt, revision::Spec};

use crate::{
revision::spec::from_bytes::{parse_spec, parse_spec_no_baseline, repo},
Expand Down Expand Up @@ -78,10 +75,13 @@ fn by_index() {
}

#[test]
fn by_date_is_planned_until_git_date_crate_is_implements_parsing() {
fn by_date() {
let repo = repo("complex_graph").unwrap();
assert!(matches!(
parse_spec_no_baseline("main@{1979-02-26 18:30:00}", &repo).unwrap_err(),
Error::Planned { .. }
));

let spec = parse_spec_no_baseline("main@{1979-02-26 18:30:00}", &repo).unwrap();

assert_eq!(
spec,
Spec::from_id(hex_to_id("9f9eac6bd1cd4b4cc6a494f044b28c985a22972b").attach(&repo))
);
}

0 comments on commit d0df20a

Please sign in to comment.