@@ -969,49 +969,36 @@ impl<'repo> StackTransaction<'repo> {
969969 where
970970 P : AsRef < PatchName > ,
971971 {
972- let stupid = self . stack . repo . stupid ( ) ;
973- stupid. with_temp_index ( |stupid_temp| {
974- let mut temp_index_tree_id: Option < gix:: ObjectId > = None ;
975-
976- let merged = if check_merged {
977- Some ( self . check_merged ( patchnames, stupid_temp, & mut temp_index_tree_id) ?)
978- } else {
979- None
980- } ;
981-
982- for ( i, patchname) in patchnames. iter ( ) . enumerate ( ) {
983- let patchname = patchname. as_ref ( ) ;
984- let is_last = i + 1 == patchnames. len ( ) ;
985- let already_merged = merged
986- . as_ref ( )
987- . is_some_and ( |merged| merged. contains ( & patchname) ) ;
988- self . push_patch (
989- patchname,
990- already_merged,
991- is_last,
992- stupid_temp,
993- & mut temp_index_tree_id,
994- ) ?;
995- }
996-
997- Ok ( ( ) )
998- } )
972+ self . push_patches_impl ( patchnames, check_merged, & [ ] )
999973 }
1000974
1001975 /// Push unapplied patches, running exec commands after each successful push.
1002976 ///
1003- /// This is similar to `push_patches`, but after each patch is pushed successfully,
1004- /// all provided exec commands are run in sequence. If any exec command fails, the
1005- /// entire transaction is rolled back (no patches remain applied).
977+ /// After each patch is successfully pushed, all provided exec commands are run
978+ /// in sequence. If any exec command fails, the entire transaction is rolled back
979+ /// (no patches remain applied).
1006980 ///
1007981 /// This supports the `stg rebase --exec` functionality. Note that this differs from
1008- /// `git rebase --exec` which leaves you at the failing point; stgit's behavior is
1009- /// safer and consistent with how stgit transactions work.
982+ /// `git rebase --exec` which leaves you at the failing point; stgit's rollback
983+ /// behavior is safer and consistent with how stgit transactions work.
1010984 pub ( crate ) fn push_patches_with_exec < P > (
1011985 & mut self ,
1012986 patchnames : & [ P ] ,
1013987 check_merged : bool ,
1014- exec_cmds : & [ String ] ,
988+ exec_cmds : & [ & str ] ,
989+ ) -> Result < ( ) >
990+ where
991+ P : AsRef < PatchName > ,
992+ {
993+ self . push_patches_impl ( patchnames, check_merged, exec_cmds)
994+ }
995+
996+ /// Core implementation for pushing patches with optional exec commands.
997+ fn push_patches_impl < P > (
998+ & mut self ,
999+ patchnames : & [ P ] ,
1000+ check_merged : bool ,
1001+ exec_cmds : & [ & str ] ,
10151002 ) -> Result < ( ) >
10161003 where
10171004 P : AsRef < PatchName > ,
@@ -1028,22 +1015,26 @@ impl<'repo> StackTransaction<'repo> {
10281015
10291016 for ( i, patchname) in patchnames. iter ( ) . enumerate ( ) {
10301017 let patchname = patchname. as_ref ( ) ;
1031- let is_last = i + 1 == patchnames. len ( ) && exec_cmds. is_empty ( ) ;
1018+ // When exec commands are provided, we can't optimize the final checkout
1019+ // because the commands may modify the working tree. Only treat the last
1020+ // patch as "last" (enabling checkout optimization) when there are no
1021+ // exec commands.
1022+ let should_optimize_final_checkout =
1023+ i + 1 == patchnames. len ( ) && exec_cmds. is_empty ( ) ;
10321024 let already_merged = merged
10331025 . as_ref ( )
10341026 . is_some_and ( |merged| merged. contains ( & patchname) ) ;
10351027 self . push_patch (
10361028 patchname,
10371029 already_merged,
1038- is_last ,
1030+ should_optimize_final_checkout ,
10391031 stupid_temp,
10401032 & mut temp_index_tree_id,
10411033 ) ?;
10421034
1043- // Run exec commands after each successful push
1044- for exec_cmd in exec_cmds {
1045- self . ui . print_exec ( exec_cmd) ?;
1046- stupid. exec_cmd ( exec_cmd) ?;
1035+ for cmd in exec_cmds {
1036+ self . ui . print_exec ( cmd) ?;
1037+ stupid. exec_cmd ( cmd) ?;
10471038 }
10481039 }
10491040
0 commit comments