@@ -155,6 +155,7 @@ pub struct Platform<'repo> {
155155 /// The owning repository.
156156 pub repo : & ' repo Repository ,
157157 pub ( crate ) tips : Vec < ObjectId > ,
158+ pub ( crate ) hidden : Vec < ObjectId > ,
158159 pub ( crate ) boundary : Vec < ObjectId > ,
159160 pub ( crate ) sorting : Sorting ,
160161 pub ( crate ) parents : gix_traverse:: commit:: Parents ,
@@ -167,6 +168,7 @@ impl<'repo> Platform<'repo> {
167168 revision:: walk:: Platform {
168169 repo,
169170 tips : tips. into_iter ( ) . map ( Into :: into) . collect ( ) ,
171+ hidden : Vec :: new ( ) ,
170172 sorting : Default :: default ( ) ,
171173 parents : Default :: default ( ) ,
172174 use_commit_graph : None ,
@@ -210,13 +212,13 @@ impl Platform<'_> {
210212 self
211213 }
212214
213- /// Don't cross the given `ids` during traversal.
215+ /// Don't cross the given `ids` (commits) during traversal.
214216 ///
215217 /// Note that this forces the [sorting](Self::sorting()) to [`ByCommitTimeCutoff`](Sorting::ByCommitTimeCutoff)
216218 /// configured with the oldest available commit time, ensuring that no commits older than the oldest of `ids` will be returned either.
217219 /// Also note that commits that can't be accessed or are missing are simply ignored for the purpose of obtaining the cutoff date.
218220 ///
219- /// A boundary is distinctly different from exclusive refsepcs `^branch-to-not-list` in Git log.
221+ /// A boundary is distinctly different from exclusive revspecs `^branch-to-not-list` in Git log.
220222 ///
221223 /// If this is not desired, [set the sorting](Self::sorting()) to something else right after this call.
222224 pub fn with_boundary ( mut self , ids : impl IntoIterator < Item = impl Into < ObjectId > > ) -> Self {
@@ -242,6 +244,20 @@ impl Platform<'_> {
242244 }
243245 self
244246 }
247+
248+ /// Don't cross the given `tips` (commits) during traversal or return them, and also don't return any of their ancestors.
249+ ///
250+ /// This allows achieving revspecs like `^branch-to-not-list`, where the commit behind that name would be passed as `ids`.
251+ ///
252+ /// In other words, each of the `tips` acts like a starting point for an iteration that will paint commits as unwanted, and
253+ /// wanted commits cannot cross it.
254+ ///
255+ /// The side effect of this is that commits can't be returned immediately as one still has to wait and see if they may be unwanted later.
256+ /// This makes traversals with hidden commits more costly, with a chance to traverse all commits if the hidden and non-hidden commits are disjoint.
257+ pub fn with_hidden ( mut self , tips : impl IntoIterator < Item = impl Into < ObjectId > > ) -> Self {
258+ self . hidden = tips. into_iter ( ) . map ( Into :: into) . collect ( ) ;
259+ self
260+ }
245261}
246262
247263/// Produce the iterator
@@ -262,6 +278,7 @@ impl<'repo> Platform<'repo> {
262278 use_commit_graph,
263279 commit_graph,
264280 mut boundary,
281+ hidden,
265282 } = self ;
266283 boundary. sort ( ) ;
267284 Ok ( revision:: Walk {
@@ -301,6 +318,7 @@ impl<'repo> Platform<'repo> {
301318 } )
302319 . sorting ( sorting. into_simple ( ) . expect ( "for now there is nothing else" ) ) ?
303320 . parents ( parents)
321+ . hide ( hidden) ?
304322 . commit_graph (
305323 commit_graph. or ( use_commit_graph
306324 . map_or_else ( || self . repo . config . may_use_commit_graph ( ) , Ok ) ?
0 commit comments