1
1
use super :: * ;
2
+ use history:: RewriteData ;
2
3
use pest:: Parser ;
3
4
use std:: path:: Path ;
4
5
mod opt;
@@ -65,7 +66,11 @@ pub fn empty() -> Filter {
65
66
to_filter ( Op :: Empty )
66
67
}
67
68
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 {
69
74
if let Some ( ids) = ids {
70
75
to_filter ( Op :: Squash ( Some (
71
76
ids. iter ( )
@@ -130,7 +135,7 @@ enum Op {
130
135
131
136
// We use BTreeMap rather than HashMap to guarantee deterministic results when
132
137
// converting to Filter
133
- Squash ( Option < std:: collections:: BTreeMap < LazyRef , String > > ) ,
138
+ Squash ( Option < std:: collections:: BTreeMap < LazyRef , Filter > > ) ,
134
139
Author ( String , String ) ,
135
140
136
141
// We use BTreeMap rather than HashMap to guarantee deterministic results when
@@ -151,6 +156,7 @@ enum Op {
151
156
Workspace ( std:: path:: PathBuf ) ,
152
157
153
158
Glob ( String ) ,
159
+ Message ( String ) ,
154
160
155
161
Compose ( Vec < Filter > ) ,
156
162
Chain ( Filter , Filter ) ,
@@ -235,14 +241,7 @@ fn pretty2(op: &Op, indent: usize, compose: bool) -> String {
235
241
Op :: Squash ( Some ( ids) ) => {
236
242
let mut v = ids
237
243
. 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) ) )
246
245
. collect :: < Vec < _ > > ( ) ;
247
246
v. sort ( ) ;
248
247
format ! ( ":squash(\n {}\n )" , v. join( "\n " ) )
@@ -479,7 +478,7 @@ fn spec2(op: &Op) -> String {
479
478
Op :: Squash ( Some ( ids) ) => {
480
479
let mut v = ids
481
480
. iter ( )
482
- . map ( |( oid, msg ) | format ! ( "{}: {}" , oid. to_string( ) , parse :: quote ( msg ) ) )
481
+ . map ( |( oid, f ) | format ! ( "{}{}" , oid. to_string( ) , spec ( * f ) ) )
483
482
. collect :: < Vec < _ > > ( ) ;
484
483
v. sort ( ) ;
485
484
format ! ( ":squash({})" , v. join( "," ) )
@@ -493,6 +492,9 @@ fn spec2(op: &Op) -> String {
493
492
Op :: Author ( author, email) => {
494
493
format ! ( ":author={};{}" , parse:: quote( author) , parse:: quote( email) )
495
494
}
495
+ Op :: Message ( m) => {
496
+ format ! ( ":{}" , parse:: quote( m) )
497
+ }
496
498
}
497
499
}
498
500
@@ -635,9 +637,12 @@ fn apply_to_commit2(
635
637
repo,
636
638
commit,
637
639
& [ ] ,
638
- & commit. tree ( ) ?,
639
- None ,
640
- None ,
640
+ RewriteData {
641
+ tree : commit. tree ( ) ?,
642
+ author : None ,
643
+ committer : None ,
644
+ message : None ,
645
+ } ,
641
646
true ,
642
647
) )
643
648
. transpose ( )
@@ -679,7 +684,7 @@ fn apply_to_commit2(
679
684
680
685
rs_tracing:: trace_scoped!( "apply_to_commit" , "spec" : spec( filter) , "commit" : commit. id( ) . to_string( ) ) ;
681
686
682
- let filtered_tree = match & to_op ( filter) {
687
+ let rewrite_data = match & to_op ( filter) {
683
688
Op :: Rev ( filters) => {
684
689
let nf = * filters
685
690
. get ( & LazyRef :: Resolved ( git2:: Oid :: zero ( ) ) )
@@ -721,11 +726,41 @@ fn apply_to_commit2(
721
726
}
722
727
}
723
728
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
+ }
725
735
}
726
736
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()?
729
764
} else {
730
765
if let Some ( parent) = commit. parents ( ) . next ( ) {
731
766
return Ok (
@@ -762,11 +797,14 @@ fn apply_to_commit2(
762
797
return Some ( history:: create_filtered_commit (
763
798
commit,
764
799
vec ! [ parent] ,
765
- commit. tree ( ) ?,
800
+ RewriteData {
801
+ tree : commit. tree ( ) ?,
802
+ author : None ,
803
+ committer : None ,
804
+ message : None ,
805
+ } ,
766
806
transaction,
767
807
filter,
768
- None ,
769
- None ,
770
808
) )
771
809
. transpose ( ) ;
772
810
}
@@ -847,11 +885,14 @@ fn apply_to_commit2(
847
885
return Some ( history:: create_filtered_commit (
848
886
commit,
849
887
filtered_parent_ids,
850
- filtered_tree,
888
+ RewriteData {
889
+ tree : filtered_tree,
890
+ author : None ,
891
+ committer : None ,
892
+ message : None ,
893
+ } ,
851
894
transaction,
852
895
filter,
853
- None ,
854
- None ,
855
896
) )
856
897
. transpose ( ) ;
857
898
}
@@ -874,9 +915,36 @@ fn apply_to_commit2(
874
915
filtered_tree = tree:: overlay ( transaction, filtered_tree, t) ?;
875
916
}
876
917
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
+ }
878
925
}
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
+ } ,
880
948
} ;
881
949
882
950
let filtered_parent_ids = {
@@ -889,24 +957,12 @@ fn apply_to_commit2(
889
957
890
958
let filtered_parent_ids = some_or ! ( filtered_parent_ids, { return Ok ( None ) } ) ;
891
959
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
-
902
960
Some ( history:: create_filtered_commit (
903
961
commit,
904
962
filtered_parent_ids,
905
- filtered_tree ,
963
+ rewrite_data ,
906
964
transaction,
907
965
filter,
908
- author,
909
- message,
910
966
) )
911
967
. transpose ( )
912
968
}
@@ -931,6 +987,7 @@ fn apply2<'a>(
931
987
Op :: Empty => return Ok ( tree:: empty ( repo) ) ,
932
988
Op :: Fold => Ok ( tree) ,
933
989
Op :: Squash ( None ) => Ok ( tree) ,
990
+ Op :: Message ( _) => Ok ( tree) ,
934
991
Op :: Author ( _, _) => Ok ( tree) ,
935
992
Op :: Squash ( Some ( _) ) => Err ( josh_error ( "not applicable to tree" ) ) ,
936
993
Op :: Linear => Ok ( tree) ,
0 commit comments