Skip to content

Commit 6b26435

Browse files
committed
feat: handle RefLogLookup::Date
1 parent 2fed5b0 commit 6b26435

File tree

3 files changed

+56
-17
lines changed

3 files changed

+56
-17
lines changed

gix/src/revision/spec/parse/delegate/revision.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,51 @@ impl delegate::Revision for Delegate<'_> {
106106
fn reflog(&mut self, query: ReflogLookup) -> Option<()> {
107107
self.unset_disambiguate_call();
108108
match query {
109-
ReflogLookup::Date(_date) => {
110-
// TODO: actually do this - this should be possible now despite incomplete date parsing
111-
self.err.push(Error::Planned {
112-
dependency: "remote handling and ref-specs are fleshed out more",
113-
});
114-
None
109+
ReflogLookup::Date(date) => {
110+
let r = match &mut self.refs[self.idx] {
111+
Some(r) => r.clone().attach(self.repo),
112+
val @ None => match self.repo.head().map(crate::Head::try_into_referent) {
113+
Ok(Some(r)) => {
114+
*val = Some(r.clone().detach());
115+
r
116+
}
117+
Ok(None) => {
118+
self.err.push(Error::UnbornHeadsHaveNoRefLog);
119+
return None;
120+
}
121+
Err(err) => {
122+
self.err.push(err.into());
123+
return None;
124+
}
125+
},
126+
};
127+
128+
let mut platform = r.log_iter();
129+
match platform.rev().ok().flatten() {
130+
Some(it) => match it
131+
.filter_map(Result::ok)
132+
.min_by_key(|l| (date - l.signature.time).abs())
133+
{
134+
Some(closest_line) => {
135+
self.objs[self.idx]
136+
.get_or_insert_with(HashSet::default)
137+
.insert(closest_line.new_oid);
138+
Some(())
139+
}
140+
None => {
141+
// do we need an another error variant?
142+
self.err.push(Error::SingleNotFound);
143+
None
144+
}
145+
},
146+
None => {
147+
self.err.push(Error::MissingRefLog {
148+
reference: r.name().as_bstr().into(),
149+
action: "lookup entry",
150+
});
151+
None
152+
}
153+
}
115154
}
116155
ReflogLookup::Entry(no) => {
117156
let r = match &mut self.refs[self.idx] {

gix/src/revision/spec/parse/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ pub enum Error {
7777
direction: remote::Direction,
7878
source: Box<dyn std::error::Error + Send + Sync + 'static>,
7979
},
80-
#[error("This feature will be implemented once {dependency}")]
81-
Planned { dependency: &'static str },
8280
#[error("Reference {reference:?} does not have a reference log, cannot {action}")]
8381
MissingRefLog { reference: BString, action: &'static str },
8482
#[error("HEAD has {available} prior checkouts and checkout number {desired} is out of range")]
@@ -194,4 +192,6 @@ pub enum Error {
194192
Walk(#[from] crate::revision::walk::Error),
195193
#[error("Spec does not contain a single object id")]
196194
SingleNotFound,
195+
#[error("Reflog does not contain any entries")]
196+
EmptyReflog,
197197
}

gix/tests/gix/revision/spec/from_bytes/reflog.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use gix::{
2-
prelude::ObjectIdExt,
3-
revision::{spec::parse::Error, Spec},
4-
};
1+
use gix::{prelude::ObjectIdExt, revision::Spec};
52

63
use crate::{
74
revision::spec::from_bytes::{parse_spec, parse_spec_no_baseline, repo},
@@ -78,10 +75,13 @@ fn by_index() {
7875
}
7976

8077
#[test]
81-
fn by_date_is_planned_until_git_date_crate_is_implements_parsing() {
78+
fn by_date() {
8279
let repo = repo("complex_graph").unwrap();
83-
assert!(matches!(
84-
parse_spec_no_baseline("main@{1979-02-26 18:30:00}", &repo).unwrap_err(),
85-
Error::Planned { .. }
86-
));
80+
81+
let spec = parse_spec_no_baseline("main@{1979-02-26 18:30:00}", &repo).unwrap();
82+
83+
assert_eq!(
84+
spec,
85+
Spec::from_id(hex_to_id("9f9eac6bd1cd4b4cc6a494f044b28c985a22972b").attach(&repo))
86+
);
8787
}

0 commit comments

Comments
 (0)