@@ -4505,61 +4505,95 @@ int sequencer_make_script(struct repository *r, FILE *out,
4505
4505
* Add commands after pick and (series of) squash/fixup commands
4506
4506
* in the todo list.
4507
4507
*/
4508
- int sequencer_add_exec_commands (struct repository * r ,
4509
- const char * commands )
4508
+ static void todo_list_add_exec_commands (struct todo_list * todo_list ,
4509
+ struct string_list * commands )
4510
4510
{
4511
- const char * todo_file = rebase_path_todo ();
4512
- struct todo_list todo_list = TODO_LIST_INIT ;
4513
- struct strbuf * buf = & todo_list .buf ;
4514
- size_t offset = 0 , commands_len = strlen (commands );
4515
- int i , insert ;
4511
+ struct strbuf * buf = & todo_list -> buf ;
4512
+ size_t base_offset = buf -> len ;
4513
+ int i , insert , nr = 0 , alloc = 0 ;
4514
+ struct todo_item * items = NULL , * base_items = NULL ;
4516
4515
4517
- if (strbuf_read_file (& todo_list .buf , todo_file , 0 ) < 0 )
4518
- return error (_ ("could not read '%s'." ), todo_file );
4516
+ base_items = xcalloc (commands -> nr , sizeof (struct todo_item ));
4517
+ for (i = 0 ; i < commands -> nr ; i ++ ) {
4518
+ size_t command_len = strlen (commands -> items [i ].string );
4519
4519
4520
- if (todo_list_parse_insn_buffer (r , todo_list .buf .buf , & todo_list )) {
4521
- todo_list_release (& todo_list );
4522
- return error (_ ("unusable todo list: '%s'" ), todo_file );
4520
+ strbuf_addstr (buf , commands -> items [i ].string );
4521
+ strbuf_addch (buf , '\n' );
4522
+
4523
+ base_items [i ].command = TODO_EXEC ;
4524
+ base_items [i ].offset_in_buf = base_offset ;
4525
+ base_items [i ].arg_offset = base_offset + strlen ("exec " );
4526
+ base_items [i ].arg_len = command_len - strlen ("exec " );
4527
+
4528
+ base_offset += command_len + 1 ;
4523
4529
}
4524
4530
4525
4531
/*
4526
4532
* Insert <commands> after every pick. Here, fixup/squash chains
4527
4533
* are considered part of the pick, so we insert the commands *after*
4528
4534
* those chains if there are any.
4535
+ *
4536
+ * As we insert the exec commands immediatly after rearranging
4537
+ * any fixups and before the user edits the list, a fixup chain
4538
+ * can never contain comments (any comments are empty picks that
4539
+ * have been commented out because the user did not specify
4540
+ * --keep-empty). So, it is safe to insert an exec command
4541
+ * without looking at the command following a comment.
4529
4542
*/
4530
- insert = -1 ;
4531
- for (i = 0 ; i < todo_list .nr ; i ++ ) {
4532
- enum todo_command command = todo_list .items [i ].command ;
4533
-
4534
- if (insert >= 0 ) {
4535
- /* skip fixup/squash chains */
4536
- if (command == TODO_COMMENT )
4537
- continue ;
4538
- else if (is_fixup (command )) {
4539
- insert = i + 1 ;
4540
- continue ;
4541
- }
4542
- strbuf_insert (buf ,
4543
- todo_list .items [insert ].offset_in_buf +
4544
- offset , commands , commands_len );
4545
- offset += commands_len ;
4546
- insert = -1 ;
4543
+ insert = 0 ;
4544
+ for (i = 0 ; i < todo_list -> nr ; i ++ ) {
4545
+ enum todo_command command = todo_list -> items [i ].command ;
4546
+ if (insert && !is_fixup (command )) {
4547
+ ALLOC_GROW (items , nr + commands -> nr , alloc );
4548
+ COPY_ARRAY (items + nr , base_items , commands -> nr );
4549
+ nr += commands -> nr ;
4550
+
4551
+ insert = 0 ;
4547
4552
}
4548
4553
4554
+ ALLOC_GROW (items , nr + 1 , alloc );
4555
+ items [nr ++ ] = todo_list -> items [i ];
4556
+
4549
4557
if (command == TODO_PICK || command == TODO_MERGE )
4550
- insert = i + 1 ;
4558
+ insert = 1 ;
4551
4559
}
4552
4560
4553
4561
/* insert or append final <commands> */
4554
- if (insert >= 0 && insert < todo_list .nr )
4555
- strbuf_insert (buf , todo_list .items [insert ].offset_in_buf +
4556
- offset , commands , commands_len );
4557
- else if (insert >= 0 || !offset )
4558
- strbuf_add (buf , commands , commands_len );
4562
+ if (insert || nr == todo_list -> nr ) {
4563
+ ALLOC_GROW (items , nr + commands -> nr , alloc );
4564
+ COPY_ARRAY (items + nr , base_items , commands -> nr );
4565
+ nr += commands -> nr ;
4566
+ }
4567
+
4568
+ free (base_items );
4569
+ FREE_AND_NULL (todo_list -> items );
4570
+ todo_list -> items = items ;
4571
+ todo_list -> nr = nr ;
4572
+ todo_list -> alloc = alloc ;
4573
+ }
4574
+
4575
+ int sequencer_add_exec_commands (struct repository * r ,
4576
+ struct string_list * commands )
4577
+ {
4578
+ const char * todo_file = rebase_path_todo ();
4579
+ struct todo_list todo_list = TODO_LIST_INIT ;
4580
+ int res ;
4581
+
4582
+ if (strbuf_read_file (& todo_list .buf , todo_file , 0 ) < 0 )
4583
+ return error_errno (_ ("could not read '%s'." ), todo_file );
4559
4584
4560
- i = write_message (buf -> buf , buf -> len , todo_file , 0 );
4585
+ if (todo_list_parse_insn_buffer (r , todo_list .buf .buf , & todo_list )) {
4586
+ todo_list_release (& todo_list );
4587
+ return error (_ ("unusable todo list: '%s'" ), todo_file );
4588
+ }
4589
+
4590
+ todo_list_add_exec_commands (& todo_list , commands );
4591
+ res = todo_list_write_to_file (r , & todo_list , todo_file , NULL , NULL , -1 , 0 );
4561
4592
todo_list_release (& todo_list );
4562
- return i ;
4593
+
4594
+ if (res )
4595
+ return error_errno (_ ("could not write '%s'." ), todo_file );
4596
+ return 0 ;
4563
4597
}
4564
4598
4565
4599
static void todo_list_to_strbuf (struct repository * r , struct todo_list * todo_list ,
@@ -4790,7 +4824,7 @@ static int skip_unnecessary_picks(struct repository *r, struct object_id *output
4790
4824
4791
4825
int complete_action (struct repository * r , struct replay_opts * opts , unsigned flags ,
4792
4826
const char * shortrevisions , const char * onto_name ,
4793
- const char * onto , const char * orig_head , const char * cmd ,
4827
+ const char * onto , const char * orig_head , struct string_list * commands ,
4794
4828
unsigned autosquash )
4795
4829
{
4796
4830
const char * shortonto , * todo_file = rebase_path_todo ();
@@ -4809,8 +4843,8 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
4809
4843
if (autosquash && rearrange_squash (r ))
4810
4844
return -1 ;
4811
4845
4812
- if (cmd && * cmd )
4813
- sequencer_add_exec_commands (r , cmd );
4846
+ if (commands -> nr )
4847
+ sequencer_add_exec_commands (r , commands );
4814
4848
4815
4849
if (strbuf_read_file (buf , todo_file , 0 ) < 0 )
4816
4850
return error_errno (_ ("could not read '%s'." ), todo_file );
0 commit comments