@@ -15,6 +15,7 @@ pub struct Config<'a> {
1515 pub force_detach : bool ,
1616 pub base : Option < & ' a str > ,
1717 pub and_rebase : bool ,
18+ pub rebase_options : & ' a Vec < & ' a str > ,
1819 pub whole_file : bool ,
1920 pub one_fixup_per_commit : bool ,
2021}
@@ -27,6 +28,12 @@ pub fn run(logger: &slog::Logger, config: &Config) -> Result<()> {
2728}
2829
2930fn run_with_repo ( logger : & slog:: Logger , config : & Config , repo : & git2:: Repository ) -> Result < ( ) > {
31+ if !config. rebase_options . is_empty ( ) && !config. and_rebase {
32+ return Err ( anyhow ! (
33+ "REBASE_OPTIONS were specified without --and-rebase flag"
34+ ) ) ;
35+ }
36+
3037 let config = config:: unify ( & config, repo) ;
3138 let stack = stack:: working_stack (
3239 repo,
@@ -367,6 +374,10 @@ fn run_with_repo(logger: &slog::Logger, config: &Config, repo: &git2::Repository
367374 let mut command = Command :: new ( "git" ) ;
368375 command. args ( [ "rebase" , "--interactive" , "--autosquash" , "--autostash" ] ) ;
369376
377+ for arg in config. rebase_options {
378+ command. arg ( arg) ;
379+ }
380+
370381 if number_of_parents == 0 {
371382 command. arg ( "--root" ) ;
372383 } else {
@@ -480,6 +491,7 @@ fn index_stats(repo: &git2::Repository) -> Result<git2::DiffStats> {
480491
481492#[ cfg( test) ]
482493mod tests {
494+ use git2:: message_trailers_strs;
483495 use std:: path:: PathBuf ;
484496
485497 use super :: * ;
@@ -684,6 +696,71 @@ mod tests {
684696 assert ! ( nothing_left_in_index( & ctx. repo) . unwrap( ) ) ;
685697 }
686698
699+ #[ test]
700+ fn and_rebase_flag_with_rebase_options ( ) {
701+ let ctx = repo_utils:: prepare_and_stage ( ) ;
702+ repo_utils:: set_config_option ( & ctx. repo , "core.editor" , "true" ) ;
703+
704+ // run 'git-absorb'
705+ let drain = slog:: Discard ;
706+ let logger = slog:: Logger :: root ( drain, o ! ( ) ) ;
707+ let config = Config {
708+ and_rebase : true ,
709+ rebase_options : & vec ! [ "--signoff" ] ,
710+ ..DEFAULT_CONFIG
711+ } ;
712+ repo_utils:: run_in_repo ( & ctx, || run_with_repo ( & logger, & config, & ctx. repo ) ) . unwrap ( ) ;
713+
714+ let mut revwalk = ctx. repo . revwalk ( ) . unwrap ( ) ;
715+ revwalk. push_head ( ) . unwrap ( ) ;
716+ assert_eq ! ( revwalk. count( ) , 1 ) ;
717+
718+ let trailers = message_trailers_strs (
719+ ctx. repo
720+ . head ( )
721+ . unwrap ( )
722+ . peel_to_commit ( )
723+ . unwrap ( )
724+ . message ( )
725+ . unwrap ( ) ,
726+ )
727+ . unwrap ( ) ;
728+ assert_eq ! (
729+ trailers
730+ . iter( )
731+ . filter( |trailer| trailer. 0 == "Signed-off-by" )
732+ . count( ) ,
733+ 1
734+ ) ;
735+
736+ assert ! ( nothing_left_in_index( & ctx. repo) . unwrap( ) ) ;
737+ }
738+
739+ #[ test]
740+ fn rebase_options_without_and_rebase_flag ( ) {
741+ let ctx = repo_utils:: prepare_and_stage ( ) ;
742+
743+ // run 'git-absorb'
744+ let drain = slog:: Discard ;
745+ let logger = slog:: Logger :: root ( drain, o ! ( ) ) ;
746+ let config = Config {
747+ rebase_options : & vec ! [ "--some-option" ] ,
748+ ..DEFAULT_CONFIG
749+ } ;
750+ let result = run_with_repo ( & logger, & config, & ctx. repo ) ;
751+
752+ assert_eq ! (
753+ result. err( ) . unwrap( ) . to_string( ) ,
754+ "REBASE_OPTIONS were specified without --and-rebase flag"
755+ ) ;
756+
757+ let mut revwalk = ctx. repo . revwalk ( ) . unwrap ( ) ;
758+ revwalk. push_head ( ) . unwrap ( ) ;
759+ assert_eq ! ( revwalk. count( ) , 1 ) ;
760+ let is_something_in_index = !nothing_left_in_index ( & ctx. repo ) . unwrap ( ) ;
761+ assert ! ( is_something_in_index) ;
762+ }
763+
687764 fn autostage_common ( ctx : & repo_utils:: Context , file_path : & PathBuf ) -> ( PathBuf , PathBuf ) {
688765 // 1 modification w/o staging
689766 let path = ctx. join ( & file_path) ;
@@ -809,6 +886,7 @@ mod tests {
809886 force_detach : false ,
810887 base : None ,
811888 and_rebase : false ,
889+ rebase_options : & Vec :: new ( ) ,
812890 whole_file : false ,
813891 one_fixup_per_commit : false ,
814892 } ;
0 commit comments