@@ -286,6 +286,8 @@ enum Op {
286286 Pattern ( String ) ,
287287 Message ( String ) ,
288288
289+ HistoryConcat ( LazyRef , Filter ) ,
290+
289291 Compose ( Vec < Filter > ) ,
290292 Chain ( Filter , Filter ) ,
291293 Subtract ( Filter , Filter ) ,
@@ -410,6 +412,13 @@ fn lazy_refs2(op: &Op) -> Vec<String> {
410412 av
411413 }
412414 Op :: Rev ( filters) => lazy_refs2 ( & Op :: Join ( filters. clone ( ) ) ) ,
415+ Op :: HistoryConcat ( r, _) => {
416+ let mut lr = Vec :: new ( ) ;
417+ if let LazyRef :: Lazy ( s) = r {
418+ lr. push ( s. to_owned ( ) ) ;
419+ }
420+ lr
421+ }
413422 Op :: Join ( filters) => {
414423 let mut lr = lazy_refs2 ( & Op :: Compose ( filters. values ( ) . copied ( ) . collect ( ) ) ) ;
415424 lr. extend ( filters. keys ( ) . filter_map ( |x| {
@@ -470,6 +479,19 @@ fn resolve_refs2(refs: &std::collections::HashMap<String, git2::Oid>, op: &Op) -
470479 . collect ( ) ;
471480 Op :: Rev ( lr)
472481 }
482+ Op :: HistoryConcat ( r, filter) => {
483+ let f = resolve_refs ( refs, * filter) ;
484+ let resolved_ref = if let LazyRef :: Lazy ( s) = r {
485+ if let Some ( res) = refs. get ( s) {
486+ LazyRef :: Resolved ( * res)
487+ } else {
488+ r. clone ( )
489+ }
490+ } else {
491+ r. clone ( )
492+ } ;
493+ Op :: HistoryConcat ( resolved_ref, f)
494+ }
473495 Op :: Join ( filters) => {
474496 let lr = filters
475497 . iter ( )
@@ -611,6 +633,9 @@ fn spec2(op: &Op) -> String {
611633 Op :: Message ( m) => {
612634 format ! ( ":{}" , parse:: quote( m) )
613635 }
636+ Op :: HistoryConcat ( r, filter) => {
637+ format ! ( ":concat({}{})" , r. to_string( ) , spec( * filter) )
638+ }
614639 Op :: Hook ( hook) => {
615640 format ! ( ":hook={}" , parse:: quote( hook) )
616641 }
@@ -1025,6 +1050,19 @@ fn apply_to_commit2(
10251050
10261051 return per_rev_filter ( transaction, commit, filter, commit_filter, parent_filters) ;
10271052 }
1053+ Op :: HistoryConcat ( r, f) => {
1054+ if let LazyRef :: Resolved ( c) = r {
1055+ let a = apply_to_commit2 ( & to_op ( * f) , & repo. find_commit ( * c) ?, transaction) ?;
1056+ let a = some_or ! ( a, { return Ok ( None ) } ) ;
1057+ if commit. id ( ) == a {
1058+ transaction. insert ( filter, commit. id ( ) , * c, true ) ;
1059+ return Ok ( Some ( * c) ) ;
1060+ }
1061+ } else {
1062+ return Err ( josh_error ( "unresolved lazy ref" ) ) ;
1063+ }
1064+ Apply :: from_commit ( commit) ?
1065+ }
10281066 _ => apply ( transaction, filter, Apply :: from_commit ( commit) ?) ?,
10291067 } ;
10301068
@@ -1065,7 +1103,7 @@ fn apply2<'a>(transaction: &'a cache::Transaction, op: &Op, x: Apply<'a>) -> Jos
10651103 Op :: Nop => Ok ( x) ,
10661104 Op :: Empty => Ok ( x. with_tree ( tree:: empty ( repo) ) ) ,
10671105 Op :: Fold => Ok ( x) ,
1068- Op :: Squash ( None ) => Ok ( x) ,
1106+ Op :: Squash ( .. ) => Ok ( x) ,
10691107 Op :: Author ( author, email) => Ok ( x. with_author ( ( author. clone ( ) , email. clone ( ) ) ) ) ,
10701108 Op :: Committer ( author, email) => Ok ( x. with_committer ( ( author. clone ( ) , email. clone ( ) ) ) ) ,
10711109 Op :: Message ( m) => Ok ( x. with_message (
@@ -1075,7 +1113,7 @@ fn apply2<'a>(transaction: &'a cache::Transaction, op: &Op, x: Apply<'a>) -> Jos
10751113 & std:: collections:: HashMap :: < String , & dyn strfmt:: DisplayStr > :: new ( ) ,
10761114 ) ?,
10771115 ) ) ,
1078- Op :: Squash ( Some ( _ ) ) => Err ( josh_error ( "not applicable to tree" ) ) ,
1116+ Op :: HistoryConcat ( .. ) => Ok ( x ) ,
10791117 Op :: Linear => Ok ( x) ,
10801118 Op :: Prune => Ok ( x) ,
10811119 Op :: Unsign => Ok ( x) ,
0 commit comments