diff --git a/gix-traverse/src/commit/topo/init.rs b/gix-traverse/src/commit/topo/init.rs index 86fb45b7321..9877e10c58b 100644 --- a/gix-traverse/src/commit/topo/init.rs +++ b/gix-traverse/src/commit/topo/init.rs @@ -28,22 +28,40 @@ where tips: impl IntoIterator>, ends: Option>>, ) -> Self { - let tips = tips.into_iter().map(Into::into).collect::>(); - let ends = ends - .map(|e| e.into_iter().map(Into::into).collect::>()) - .unwrap_or_default(); + Self::new(find).with_tips(tips).with_ends(ends.into_iter().flatten()) + } + /// Create a new `Builder` for a [`Topo`] that reads commits from a + /// repository with `find`. + pub fn new(find: Find) -> Self { Self { commit_graph: Default::default(), find, sorting: Default::default(), parents: Default::default(), - tips, - ends, + tips: Default::default(), + ends: Default::default(), predicate: |_| true, } } + /// Add commits to start reading from. + /// + /// The behavior is similar to specifying additional `ends` in `git rev-list --topo-order ^ends tips`. + pub fn with_tips(mut self, tips: impl IntoIterator>) -> Self { + self.tips.extend(tips.into_iter().map(Into::into)); + self + } + + /// Add commits ending the traversal. + /// + /// These commits themselves will not be read, i.e. the behavior is similar to specifying additional + /// `ends` in `git rev-list --topo-order ^ends tips`. + pub fn with_ends(mut self, ends: impl IntoIterator>) -> Self { + self.ends.extend(ends.into_iter().map(Into::into)); + self + } + /// Set a `predicate` to filter out revisions from the walk. Can be used to /// implement e.g. filtering on paths or time. This does *not* exclude the /// parent(s) of a revision that is excluded. Specify a revision as an 'end'