11use super :: * ;
2+ use history:: RewriteData ;
23use pest:: Parser ;
34use std:: path:: Path ;
45mod opt;
@@ -65,7 +66,11 @@ pub fn empty() -> Filter {
6566 to_filter ( Op :: Empty )
6667}
6768
68- pub fn squash ( ids : Option < & [ ( git2:: Oid , String ) ] > ) -> Filter {
69+ pub fn message ( m : & str ) -> Filter {
70+ to_filter ( Op :: Message ( m. to_string ( ) ) )
71+ }
72+
73+ pub fn squash ( ids : Option < & [ ( git2:: Oid , Filter ) ] > ) -> Filter {
6974 if let Some ( ids) = ids {
7075 to_filter ( Op :: Squash ( Some (
7176 ids. iter ( )
@@ -130,7 +135,7 @@ enum Op {
130135
131136 // We use BTreeMap rather than HashMap to guarantee deterministic results when
132137 // converting to Filter
133- Squash ( Option < std:: collections:: BTreeMap < LazyRef , String > > ) ,
138+ Squash ( Option < std:: collections:: BTreeMap < LazyRef , Filter > > ) ,
134139 Author ( String , String ) ,
135140
136141 // We use BTreeMap rather than HashMap to guarantee deterministic results when
@@ -151,6 +156,7 @@ enum Op {
151156 Workspace ( std:: path:: PathBuf ) ,
152157
153158 Glob ( String ) ,
159+ Message ( String ) ,
154160
155161 Compose ( Vec < Filter > ) ,
156162 Chain ( Filter , Filter ) ,
@@ -235,14 +241,7 @@ fn pretty2(op: &Op, indent: usize, compose: bool) -> String {
235241 Op :: Squash ( Some ( ids) ) => {
236242 let mut v = ids
237243 . iter ( )
238- . map ( |( oid, msg) | {
239- format ! (
240- "{}{}:{}" ,
241- " " . repeat( indent) ,
242- & oid. to_string( ) ,
243- parse:: quote( msg)
244- )
245- } )
244+ . map ( |( oid, f) | format ! ( "{}{}{}" , " " . repeat( indent) , & oid. to_string( ) , spec( * f) ) )
246245 . collect :: < Vec < _ > > ( ) ;
247246 v. sort ( ) ;
248247 format ! ( ":squash(\n {}\n )" , v. join( "\n " ) )
@@ -479,7 +478,7 @@ fn spec2(op: &Op) -> String {
479478 Op :: Squash ( Some ( ids) ) => {
480479 let mut v = ids
481480 . iter ( )
482- . map ( |( oid, msg ) | format ! ( "{}: {}" , oid. to_string( ) , parse :: quote ( msg ) ) )
481+ . map ( |( oid, f ) | format ! ( "{}{}" , oid. to_string( ) , spec ( * f ) ) )
483482 . collect :: < Vec < _ > > ( ) ;
484483 v. sort ( ) ;
485484 format ! ( ":squash({})" , v. join( "," ) )
@@ -493,6 +492,9 @@ fn spec2(op: &Op) -> String {
493492 Op :: Author ( author, email) => {
494493 format ! ( ":author={};{}" , parse:: quote( author) , parse:: quote( email) )
495494 }
495+ Op :: Message ( m) => {
496+ format ! ( ":{}" , parse:: quote( m) )
497+ }
496498 }
497499}
498500
@@ -635,9 +637,12 @@ fn apply_to_commit2(
635637 repo,
636638 commit,
637639 & [ ] ,
638- & commit. tree ( ) ?,
639- None ,
640- None ,
640+ RewriteData {
641+ tree : commit. tree ( ) ?,
642+ author : None ,
643+ committer : None ,
644+ message : None ,
645+ } ,
641646 true ,
642647 ) )
643648 . transpose ( )
@@ -679,7 +684,7 @@ fn apply_to_commit2(
679684
680685 rs_tracing:: trace_scoped!( "apply_to_commit" , "spec" : spec( filter) , "commit" : commit. id( ) . to_string( ) ) ;
681686
682- let filtered_tree = match & to_op ( filter) {
687+ let rewrite_data = match & to_op ( filter) {
683688 Op :: Rev ( filters) => {
684689 let nf = * filters
685690 . get ( & LazyRef :: Resolved ( git2:: Oid :: zero ( ) ) )
@@ -721,11 +726,41 @@ fn apply_to_commit2(
721726 }
722727 }
723728
724- apply ( transaction, nf, commit. tree ( ) ?) ?
729+ RewriteData {
730+ tree : apply ( transaction, nf, commit. tree ( ) ?) ?,
731+ message : None ,
732+ author : None ,
733+ committer : None ,
734+ }
725735 }
726736 Op :: Squash ( Some ( ids) ) => {
727- if ids. get ( & LazyRef :: Resolved ( commit. id ( ) ) ) . is_some ( ) {
728- commit. tree ( ) ?
737+ if let Some ( sq) = ids. get ( & LazyRef :: Resolved ( commit. id ( ) ) ) {
738+ let oid = if let Some ( oid) =
739+ apply_to_commit2 ( & Op :: Chain ( filter:: squash ( None ) , * sq) , commit, transaction) ?
740+ {
741+ oid
742+ } else {
743+ return Ok ( None ) ;
744+ } ;
745+
746+ let rc = transaction. repo ( ) . find_commit ( oid) ?;
747+ let author = rc
748+ . author ( )
749+ . name ( )
750+ . map ( |x| x. to_owned ( ) )
751+ . zip ( rc. author ( ) . email ( ) . map ( |x| x. to_owned ( ) ) ) ;
752+ let committer = rc
753+ . committer ( )
754+ . name ( )
755+ . map ( |x| x. to_owned ( ) )
756+ . zip ( rc. committer ( ) . email ( ) . map ( |x| x. to_owned ( ) ) ) ;
757+ RewriteData {
758+ tree : rc. tree ( ) ?,
759+ message : rc. message_raw ( ) . map ( |x| x. to_owned ( ) ) ,
760+ author : author,
761+ committer : committer,
762+ }
763+ //commit.tree()?
729764 } else {
730765 if let Some ( parent) = commit. parents ( ) . next ( ) {
731766 return Ok (
@@ -762,11 +797,14 @@ fn apply_to_commit2(
762797 return Some ( history:: create_filtered_commit (
763798 commit,
764799 vec ! [ parent] ,
765- commit. tree ( ) ?,
800+ RewriteData {
801+ tree : commit. tree ( ) ?,
802+ author : None ,
803+ committer : None ,
804+ message : None ,
805+ } ,
766806 transaction,
767807 filter,
768- None ,
769- None ,
770808 ) )
771809 . transpose ( ) ;
772810 }
@@ -847,11 +885,14 @@ fn apply_to_commit2(
847885 return Some ( history:: create_filtered_commit (
848886 commit,
849887 filtered_parent_ids,
850- filtered_tree,
888+ RewriteData {
889+ tree : filtered_tree,
890+ author : None ,
891+ committer : None ,
892+ message : None ,
893+ } ,
851894 transaction,
852895 filter,
853- None ,
854- None ,
855896 ) )
856897 . transpose ( ) ;
857898 }
@@ -874,9 +915,36 @@ fn apply_to_commit2(
874915 filtered_tree = tree:: overlay ( transaction, filtered_tree, t) ?;
875916 }
876917
877- repo. find_tree ( filtered_tree) ?
918+ let filtered_tree = repo. find_tree ( filtered_tree) ?;
919+ RewriteData {
920+ tree : filtered_tree,
921+ author : None ,
922+ committer : None ,
923+ message : None ,
924+ }
878925 }
879- _ => apply ( transaction, filter, commit. tree ( ) ?) ?,
926+ Op :: Author ( author, email) => RewriteData {
927+ tree : commit. tree ( ) ?,
928+ author : Some ( ( author. clone ( ) , email. clone ( ) ) ) ,
929+ committer : Some ( ( author. clone ( ) , email. clone ( ) ) ) ,
930+ message : None ,
931+ } ,
932+ Op :: Message ( m) => RewriteData {
933+ tree : commit. tree ( ) ?,
934+ author : None ,
935+ committer : None ,
936+ // Pass the message through `strfmt` to enable future extensions
937+ message : Some ( strfmt:: strfmt (
938+ m,
939+ & std:: collections:: HashMap :: < String , & dyn strfmt:: DisplayStr > :: new ( ) ,
940+ ) ?) ,
941+ } ,
942+ _ => RewriteData {
943+ tree : apply ( transaction, filter, commit. tree ( ) ?) ?,
944+ message : None ,
945+ author : None ,
946+ committer : None ,
947+ } ,
880948 } ;
881949
882950 let filtered_parent_ids = {
@@ -889,24 +957,12 @@ fn apply_to_commit2(
889957
890958 let filtered_parent_ids = some_or ! ( filtered_parent_ids, { return Ok ( None ) } ) ;
891959
892- let author = match to_op ( filter) {
893- Op :: Author ( author, email) => Some ( ( author, email) ) ,
894- _ => None ,
895- } ;
896-
897- let message = match to_op ( filter) {
898- Op :: Squash ( Some ( ids) ) => ids. get ( & LazyRef :: Resolved ( commit. id ( ) ) ) . cloned ( ) ,
899- _ => None ,
900- } ;
901-
902960 Some ( history:: create_filtered_commit (
903961 commit,
904962 filtered_parent_ids,
905- filtered_tree ,
963+ rewrite_data ,
906964 transaction,
907965 filter,
908- author,
909- message,
910966 ) )
911967 . transpose ( )
912968}
@@ -931,6 +987,7 @@ fn apply2<'a>(
931987 Op :: Empty => return Ok ( tree:: empty ( repo) ) ,
932988 Op :: Fold => Ok ( tree) ,
933989 Op :: Squash ( None ) => Ok ( tree) ,
990+ Op :: Message ( _) => Ok ( tree) ,
934991 Op :: Author ( _, _) => Ok ( tree) ,
935992 Op :: Squash ( Some ( _) ) => Err ( josh_error ( "not applicable to tree" ) ) ,
936993 Op :: Linear => Ok ( tree) ,
0 commit comments