Makes it easier to use these types for different kinds of commit walking. No matter how the history graph is traversed some concepts remain identical.
Unified · Split
| @@ -1,4 +1,3 @@ | ||
| 1 | −use gix_object::FindExt; | |
| 2 | 1 | use smallvec::SmallVec; |
| 3 | 2 | |
| 4 | 3 | /// An iterator over the ancestors one or more starting commits |
| @@ -7,20 +6,10 @@ pub struct Ancestors<Find, Predicate, StateMut> { · 2 unmodified lines | ||
| 7 | 6 | cache: Option<gix_commitgraph::Graph>, |
| 8 | 7 | predicate: Predicate, |
| 9 | 8 | state: StateMut, |
| 10 | − parents: Parents, | |
| 9 | + parents: super::Parents, | |
| 11 | 10 | sorting: Sorting, |
| 12 | 11 | } |
| 13 | 12 | |
| 14 | −/// Specify how to handle commit parents during traversal. | |
| 15 | −#[derive(Default, Copy, Clone)] | |
| 16 | −pub enum Parents { | |
| 17 | − /// Traverse all parents, useful for traversing the entire ancestry. | |
| 18 | − #[default] | |
| 19 | − All, | |
| 20 | − /// Only traverse along the first parent, which commonly ignores all branches. | |
| 21 | − First, | |
| 22 | −} | |
| 23 | − | |
| 24 | 13 | /// Specify how to sort commits during traversal. |
| 25 | 14 | /// |
| 26 | 15 | /// ### Sample History |
| @@ -69,23 +58,6 @@ pub enum Sorting { · 42 unmodified lines | ||
| 69 | 58 | }, |
| 70 | 59 | } |
| 71 | 60 | |
| 72 | −/// The collection of parent ids we saw as part of the iteration. | |
| 73 | −/// | |
| 74 | −/// Note that this list is truncated if [`Parents::First`] was used. | |
| 75 | −pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>; | |
| 76 | − | |
| 77 | −/// Information about a commit that we obtained naturally as part of the iteration. | |
| 78 | −#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] | |
| 79 | −pub struct Info { | |
| 80 | − /// The id of the commit. | |
| 81 | − pub id: gix_hash::ObjectId, | |
| 82 | − /// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled. | |
| 83 | − pub parent_ids: ParentIds, | |
| 84 | − /// The time at which the commit was created. It's only `Some(_)` if sorting is not [`Sorting::BreadthFirst`], as the walk | |
| 85 | − /// needs to require the commit-date. | |
| 86 | − pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>, | |
| 87 | −} | |
| 88 | − | |
| 89 | 61 | /// |
| 90 | 62 | #[allow(clippy::empty_docs)] |
| 91 | 63 | pub mod ancestors { |
| @@ -100,7 +72,10 @@ pub mod ancestors { · 8 unmodified lines | ||
| 100 | 72 | use gix_object::{CommitRefIter, FindExt}; |
| 101 | 73 | use smallvec::SmallVec; |
| 102 | 74 | |
| 103 | − use super::{collect_parents, Ancestors, Either, Info, ParentIds, Parents, Sorting}; | |
| 75 | + use super::{ | |
| 76 | + super::{Either, Info, ParentIds, Parents}, | |
| 77 | + collect_parents, Ancestors, Sorting, | |
| 78 | + }; | |
| 104 | 79 | |
| 105 | 80 | /// The error is part of the item returned by the [Ancestors] iterator. |
| 106 | 81 | #[derive(Debug, thiserror::Error)] |
| @@ -339,7 +314,7 @@ pub mod ancestors { · 232 unmodified lines | ||
| 339 | 314 | |
| 340 | 315 | let (commit_time, oid) = state.queue.pop()?; |
| 341 | 316 | let mut parents: ParentIds = Default::default(); |
| 342 | − match super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) { | |
| 317 | + match super::super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) { | |
| 343 | 318 | Ok(Either::CachedCommit(commit)) => { |
| 344 | 319 | if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) { |
| 345 | 320 | // drop corrupt caches and try again with ODB |
| @@ -406,7 +381,7 @@ pub mod ancestors { · 60 unmodified lines | ||
| 406 | 381 | let state = self.state.borrow_mut(); |
| 407 | 382 | let oid = state.next.pop_front()?; |
| 408 | 383 | let mut parents: ParentIds = Default::default(); |
| 409 | − match super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) { | |
| 384 | + match super::super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) { | |
| 410 | 385 | Ok(Either::CachedCommit(commit)) => { |
| 411 | 386 | if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) { |
| 412 | 387 | // drop corrupt caches and try again with ODB |
| @@ -457,11 +432,6 @@ pub mod ancestors { · 44 unmodified lines | ||
| 457 | 432 | |
| 458 | 433 | pub use ancestors::{Error, State}; |
| 459 | 434 | |
| 460 | −enum Either<'buf, 'cache> { | |
| 461 | − CommitRefIter(gix_object::CommitRefIter<'buf>), | |
| 462 | − CachedCommit(gix_commitgraph::file::Commit<'cache>), | |
| 463 | −} | |
| 464 | − | |
| 465 | 435 | fn collect_parents( |
| 466 | 436 | dest: &mut SmallVec<[(gix_hash::ObjectId, gix_date::SecondsSinceUnixEpoch); 2]>, |
| 467 | 437 | cache: Option<&gix_commitgraph::Graph>, |
| @@ -483,18 +453,3 @@ fn collect_parents( · 15 unmodified lines | ||
| 483 | 453 | } |
| 484 | 454 | true |
| 485 | 455 | } |
| 486 | − | |
| 487 | −fn find<'cache, 'buf, Find>( | |
| 488 | − cache: Option<&'cache gix_commitgraph::Graph>, | |
| 489 | − objects: Find, | |
| 490 | − id: &gix_hash::oid, | |
| 491 | − buf: &'buf mut Vec<u8>, | |
| 492 | −) -> Result<Either<'buf, 'cache>, gix_object::find::existing_iter::Error> | |
| 493 | −where | |
| 494 | − Find: gix_object::Find, | |
| 495 | −{ | |
| 496 | − match cache.and_then(|cache| cache.commit_by_id(id).map(Either::CachedCommit)) { | |
| 497 | − Some(c) => Ok(c), | |
| 498 | − None => objects.find_commit_iter(id, buf).map(Either::CommitRefIter), | |
| 499 | − } | |
| 500 | −} | |
| @@ -1,3 +1,53 @@ | ||
| 1 | +use gix_object::FindExt; | |
| 2 | +use smallvec::SmallVec; | |
| 3 | + | |
| 1 | 4 | /// Simple ancestors traversal |
| 2 | 5 | pub mod ancestors; |
| 3 | −pub use ancestors::{Ancestors, Info, ParentIds, Parents, Sorting}; | |
| 6 | +pub use ancestors::{Ancestors, Sorting}; | |
| 7 | + | |
| 8 | +/// Specify how to handle commit parents during traversal. | |
| 9 | +#[derive(Default, Copy, Clone)] | |
| 10 | +pub enum Parents { | |
| 11 | + /// Traverse all parents, useful for traversing the entire ancestry. | |
| 12 | + #[default] | |
| 13 | + All, | |
| 14 | + /// Only traverse along the first parent, which commonly ignores all branches. | |
| 15 | + First, | |
| 16 | +} | |
| 17 | + | |
| 18 | +/// The collection of parent ids we saw as part of the iteration. | |
| 19 | +/// | |
| 20 | +/// Note that this list is truncated if [`Parents::First`] was used. | |
| 21 | +pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>; | |
| 22 | + | |
| 23 | +/// Information about a commit that we obtained naturally as part of the iteration. | |
| 24 | +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] | |
| 25 | +pub struct Info { | |
| 26 | + /// The id of the commit. | |
| 27 | + pub id: gix_hash::ObjectId, | |
| 28 | + /// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled. | |
| 29 | + pub parent_ids: ParentIds, | |
| 30 | + /// The time at which the commit was created. It's only `Some(_)` if sorting is not [`Sorting::BreadthFirst`], as the walk | |
| 31 | + /// needs to require the commit-date. | |
| 32 | + pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>, | |
| 33 | +} | |
| 34 | + | |
| 35 | +enum Either<'buf, 'cache> { | |
| 36 | + CommitRefIter(gix_object::CommitRefIter<'buf>), | |
| 37 | + CachedCommit(gix_commitgraph::file::Commit<'cache>), | |
| 38 | +} | |
| 39 | + | |
| 40 | +fn find<'cache, 'buf, Find>( | |
| 41 | + cache: Option<&'cache gix_commitgraph::Graph>, | |
| 42 | + objects: Find, | |
| 43 | + id: &gix_hash::oid, | |
| 44 | + buf: &'buf mut Vec<u8>, | |
| 45 | +) -> Result<Either<'buf, 'cache>, gix_object::find::existing_iter::Error> | |
| 46 | +where | |
| 47 | + Find: gix_object::Find, | |
| 48 | +{ | |
| 49 | + match cache.and_then(|cache| cache.commit_by_id(id).map(Either::CachedCommit)) { | |
| 50 | + Some(c) => Ok(c), | |
| 51 | + None => objects.find_commit_iter(id, buf).map(Either::CommitRefIter), | |
| 52 | + } | |
| 53 | +} | |