@@ -2626,8 +2626,63 @@ static int check_label_or_ref_arg(enum todo_command command, const char *arg)
26262626 return 0 ;
26272627}
26282628
2629- static int parse_insn_line (struct repository * r , struct todo_item * item ,
2630- const char * buf , const char * bol , char * eol )
2629+ static int check_merge_commit_insn (enum todo_command command )
2630+ {
2631+ switch (command ) {
2632+ case TODO_PICK :
2633+ error (_ ("'%s' does not accept merge commits" ),
2634+ todo_command_info [command ].str );
2635+ advise_if_enabled (ADVICE_REBASE_TODO_ERROR , _ (
2636+ /*
2637+ * TRANSLATORS: 'pick' and 'merge -C' should not be
2638+ * translated.
2639+ */
2640+ "'pick' does not take a merge commit. If you wanted to\n"
2641+ "replay the merge, use 'merge -C' on the commit." ));
2642+ return -1 ;
2643+
2644+ case TODO_REWORD :
2645+ error (_ ("'%s' does not accept merge commits" ),
2646+ todo_command_info [command ].str );
2647+ advise_if_enabled (ADVICE_REBASE_TODO_ERROR , _ (
2648+ /*
2649+ * TRANSLATORS: 'reword' and 'merge -c' should not be
2650+ * translated.
2651+ */
2652+ "'reword' does not take a merge commit. If you wanted to\n"
2653+ "replay the merge and reword the commit message, use\n"
2654+ "'merge -c' on the commit" ));
2655+ return -1 ;
2656+
2657+ case TODO_EDIT :
2658+ error (_ ("'%s' does not accept merge commits" ),
2659+ todo_command_info [command ].str );
2660+ advise_if_enabled (ADVICE_REBASE_TODO_ERROR , _ (
2661+ /*
2662+ * TRANSLATORS: 'edit', 'merge -C' and 'break' should
2663+ * not be translated.
2664+ */
2665+ "'edit' does not take a merge commit. If you wanted to\n"
2666+ "replay the merge, use 'merge -C' on the commit, and then\n"
2667+ "'break' to give the control back to you so that you can\n"
2668+ "do 'git commit --amend && git rebase --continue'." ));
2669+ return -1 ;
2670+
2671+ case TODO_FIXUP :
2672+ case TODO_SQUASH :
2673+ return error (_ ("cannot squash merge commit into another commit" ));
2674+
2675+ case TODO_MERGE :
2676+ return 0 ;
2677+
2678+ default :
2679+ BUG ("unexpected todo_command" );
2680+ }
2681+ }
2682+
2683+ static int parse_insn_line (struct repository * r , struct replay_opts * opts ,
2684+ struct todo_item * item , const char * buf ,
2685+ const char * bol , char * eol )
26312686{
26322687 struct object_id commit_oid ;
26332688 char * end_of_object_name ;
@@ -2731,7 +2786,12 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
27312786 return status ;
27322787
27332788 item -> commit = lookup_commit_reference (r , & commit_oid );
2734- return item -> commit ? 0 : -1 ;
2789+ if (!item -> commit )
2790+ return -1 ;
2791+ if (is_rebase_i (opts ) &&
2792+ item -> commit -> parents && item -> commit -> parents -> next )
2793+ return check_merge_commit_insn (item -> command );
2794+ return 0 ;
27352795}
27362796
27372797int sequencer_get_last_command (struct repository * r UNUSED , enum replay_action * action )
@@ -2761,8 +2821,8 @@ int sequencer_get_last_command(struct repository *r UNUSED, enum replay_action *
27612821 return ret ;
27622822}
27632823
2764- int todo_list_parse_insn_buffer (struct repository * r , char * buf ,
2765- struct todo_list * todo_list )
2824+ int todo_list_parse_insn_buffer (struct repository * r , struct replay_opts * opts ,
2825+ char * buf , struct todo_list * todo_list )
27662826{
27672827 struct todo_item * item ;
27682828 char * p = buf , * next_p ;
@@ -2780,7 +2840,7 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf,
27802840
27812841 item = append_new_todo (todo_list );
27822842 item -> offset_in_buf = p - todo_list -> buf .buf ;
2783- if (parse_insn_line (r , item , buf , p , eol )) {
2843+ if (parse_insn_line (r , opts , item , buf , p , eol )) {
27842844 res = error (_ ("invalid line %d: %.*s" ),
27852845 i , (int )(eol - p ), p );
27862846 item -> command = TODO_COMMENT + 1 ;
@@ -2930,7 +2990,7 @@ static int read_populate_todo(struct repository *r,
29302990 if (strbuf_read_file_or_whine (& todo_list -> buf , todo_file ) < 0 )
29312991 return -1 ;
29322992
2933- res = todo_list_parse_insn_buffer (r , todo_list -> buf .buf , todo_list );
2993+ res = todo_list_parse_insn_buffer (r , opts , todo_list -> buf .buf , todo_list );
29342994 if (res ) {
29352995 if (is_rebase_i (opts ))
29362996 return error (_ ("please fix this using "
@@ -2960,7 +3020,7 @@ static int read_populate_todo(struct repository *r,
29603020 struct todo_list done = TODO_LIST_INIT ;
29613021
29623022 if (strbuf_read_file (& done .buf , rebase_path_done (), 0 ) > 0 &&
2963- !todo_list_parse_insn_buffer (r , done .buf .buf , & done ))
3023+ !todo_list_parse_insn_buffer (r , opts , done .buf .buf , & done ))
29643024 todo_list -> done_nr = count_commands (& done );
29653025 else
29663026 todo_list -> done_nr = 0 ;
@@ -5317,7 +5377,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
53175377 goto release_todo_list ;
53185378
53195379 if (file_exists (rebase_path_dropped ())) {
5320- if ((res = todo_list_check_against_backup (r , & todo_list )))
5380+ if ((res = todo_list_check_against_backup (r , opts ,
5381+ & todo_list )))
53215382 goto release_todo_list ;
53225383
53235384 unlink (rebase_path_dropped ());
@@ -6360,7 +6421,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
63606421 return error (_ ("nothing to do" ));
63616422 }
63626423
6363- res = edit_todo_list (r , todo_list , & new_todo , shortrevisions ,
6424+ res = edit_todo_list (r , opts , todo_list , & new_todo , shortrevisions ,
63646425 shortonto , flags );
63656426 if (res == -1 )
63666427 return -1 ;
@@ -6388,7 +6449,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
63886449 strbuf_release (& buf2 );
63896450 /* Nothing is done yet, and we're reparsing, so let's reset the count */
63906451 new_todo .total_nr = 0 ;
6391- if (todo_list_parse_insn_buffer (r , new_todo .buf .buf , & new_todo ) < 0 )
6452+ if (todo_list_parse_insn_buffer (r , opts , new_todo .buf .buf , & new_todo ) < 0 )
63926453 BUG ("invalid todo list after expanding IDs:\n%s" ,
63936454 new_todo .buf .buf );
63946455
0 commit comments