@@ -98,6 +98,7 @@ enum Op {
98
98
Fold ,
99
99
Paths ,
100
100
Squash ( Option < std:: collections:: HashMap < git2:: Oid , ( String , String , String ) > > ) ,
101
+ AtCommit ( git2:: Oid , Filter ) ,
101
102
Linear ,
102
103
103
104
RegexReplace ( regex:: Regex , String ) ,
@@ -194,6 +195,7 @@ fn nesting2(op: &Op) -> usize {
194
195
Op :: Workspace ( _) => usize:: MAX ,
195
196
Op :: Chain ( a, b) => 1 + nesting ( * a) . max ( nesting ( * b) ) ,
196
197
Op :: Subtract ( a, b) => 1 + nesting ( * a) . max ( nesting ( * b) ) ,
198
+ Op :: AtCommit ( _, filter) => 1 + nesting ( * filter) ,
197
199
_ => 0 ,
198
200
}
199
201
}
@@ -223,6 +225,9 @@ fn spec2(op: &Op) -> String {
223
225
Op :: Exclude ( b) => {
224
226
format ! ( ":exclude[{}]" , spec( * b) )
225
227
}
228
+ Op :: AtCommit ( id, b) => {
229
+ format ! ( ":at_commit={}[{}]" , id, spec( * b) )
230
+ }
226
231
Op :: Workspace ( path) => {
227
232
format ! ( ":workspace={}" , parse:: quote( & path. to_string_lossy( ) ) )
228
233
}
@@ -384,6 +389,18 @@ fn apply_to_commit2(
384
389
rs_tracing:: trace_scoped!( "apply_to_commit" , "spec" : spec( filter) , "commit" : commit. id( ) . to_string( ) ) ;
385
390
386
391
let filtered_tree = match & to_op ( filter) {
392
+ Op :: AtCommit ( id, startfilter) => {
393
+ if * id == commit. id ( ) {
394
+ if let Some ( start) = apply_to_commit2 ( & to_op ( * startfilter) , & commit, transaction) ? {
395
+ transaction. insert ( filter, commit. id ( ) , start, true ) ;
396
+ return Ok ( Some ( start) ) ;
397
+ } else {
398
+ return Ok ( None ) ;
399
+ }
400
+ } else {
401
+ commit. tree ( ) ?
402
+ }
403
+ }
387
404
Op :: Squash ( Some ( ids) ) => {
388
405
if let Some ( _) = ids. get ( & commit. id ( ) ) {
389
406
commit. tree ( ) ?
@@ -619,6 +636,7 @@ fn apply2<'a>(
619
636
Op :: Squash ( None ) => Ok ( tree) ,
620
637
Op :: Squash ( Some ( _) ) => Err ( josh_error ( "not applicable to tree" ) ) ,
621
638
Op :: Linear => Ok ( tree) ,
639
+ Op :: AtCommit ( _, _) => Err ( josh_error ( "not applicable to tree" ) ) ,
622
640
623
641
Op :: RegexReplace ( regex, replacement) => {
624
642
tree:: regex_replace ( tree. id ( ) , & regex, & replacement, transaction)
@@ -712,7 +730,11 @@ pub fn unapply<'a>(
712
730
parent_tree : git2:: Tree < ' a > ,
713
731
) -> JoshResult < git2:: Tree < ' a > > {
714
732
if let Ok ( inverted) = invert ( filter) {
715
- let matching = apply ( transaction, chain ( filter, inverted) , parent_tree. clone ( ) ) ?;
733
+ let matching = apply (
734
+ transaction,
735
+ chain ( invert ( inverted) ?, inverted) ,
736
+ parent_tree. clone ( ) ,
737
+ ) ?;
716
738
let stripped = tree:: subtract ( transaction, parent_tree. id ( ) , matching. id ( ) ) ?;
717
739
let new_tree = apply ( transaction, inverted, tree) ?;
718
740
@@ -733,7 +755,8 @@ pub fn unapply<'a>(
733
755
}
734
756
735
757
if let Op :: Chain ( a, b) = to_op ( filter) {
736
- let p = apply ( transaction, a, parent_tree. clone ( ) ) ?;
758
+ let i = if let Ok ( i) = invert ( a) { invert ( i) ? } else { a } ;
759
+ let p = apply ( transaction, i, parent_tree. clone ( ) ) ?;
737
760
return unapply (
738
761
transaction,
739
762
a,
0 commit comments