@@ -60,13 +60,14 @@ struct replay_opts {
6060 int allow_rerere_auto ;
6161
6262 int mainline ;
63- int commit_argc ;
64- const char * * commit_argv ;
6563
6664 /* Merge strategy */
6765 const char * strategy ;
6866 const char * * xopts ;
6967 size_t xopts_nr , xopts_alloc ;
68+
69+ /* Only used by REPLAY_NONE */
70+ struct rev_info * revs ;
7071};
7172
7273#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
@@ -169,9 +170,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
169170 die (_ ("program error" ));
170171 }
171172
172- opts -> commit_argc = parse_options (argc , argv , NULL , options , usage_str ,
173- PARSE_OPT_KEEP_ARGV0 |
174- PARSE_OPT_KEEP_UNKNOWN );
173+ argc = parse_options (argc , argv , NULL , options , usage_str ,
174+ PARSE_OPT_KEEP_ARGV0 |
175+ PARSE_OPT_KEEP_UNKNOWN );
175176
176177 /* Check for incompatible subcommands */
177178 verify_opt_mutually_compatible (me ,
@@ -213,17 +214,27 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
213214 NULL );
214215 }
215216
216- else if (opts -> commit_argc < 2 )
217- usage_with_options (usage_str , options );
218-
219217 if (opts -> allow_ff )
220218 verify_opt_compatible (me , "--ff" ,
221219 "--signoff" , opts -> signoff ,
222220 "--no-commit" , opts -> no_commit ,
223221 "-x" , opts -> record_origin ,
224222 "--edit" , opts -> edit ,
225223 NULL );
226- opts -> commit_argv = argv ;
224+
225+ if (opts -> subcommand != REPLAY_NONE ) {
226+ opts -> revs = NULL ;
227+ } else {
228+ opts -> revs = xmalloc (sizeof (* opts -> revs ));
229+ init_revisions (opts -> revs , NULL );
230+ opts -> revs -> no_walk = 1 ;
231+ if (argc < 2 )
232+ usage_with_options (usage_str , options );
233+ argc = setup_revisions (argc , argv , opts -> revs , NULL );
234+ }
235+
236+ if (argc > 1 )
237+ usage_with_options (usage_str , options );
227238}
228239
229240struct commit_message {
@@ -631,23 +642,15 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
631642 return res ;
632643}
633644
634- static void prepare_revs (struct rev_info * revs , struct replay_opts * opts )
645+ static void prepare_revs (struct replay_opts * opts )
635646{
636- int argc ;
637-
638- init_revisions (revs , NULL );
639- revs -> no_walk = 1 ;
640647 if (opts -> action != REVERT )
641- revs -> reverse = 1 ;
642-
643- argc = setup_revisions (opts -> commit_argc , opts -> commit_argv , revs , NULL );
644- if (argc > 1 )
645- usage (* revert_or_cherry_pick_usage (opts ));
648+ opts -> revs -> reverse ^= 1 ;
646649
647- if (prepare_revision_walk (revs ))
650+ if (prepare_revision_walk (opts -> revs ))
648651 die (_ ("revision walk setup failed" ));
649652
650- if (!revs -> commits )
653+ if (!opts -> revs -> commits )
651654 die (_ ("empty commit set passed" ));
652655}
653656
@@ -844,14 +847,13 @@ static void read_populate_opts(struct replay_opts **opts_ptr)
844847static void walk_revs_populate_todo (struct commit_list * * todo_list ,
845848 struct replay_opts * opts )
846849{
847- struct rev_info revs ;
848850 struct commit * commit ;
849851 struct commit_list * * next ;
850852
851- prepare_revs (& revs , opts );
853+ prepare_revs (opts );
852854
853855 next = todo_list ;
854- while ((commit = get_revision (& revs )))
856+ while ((commit = get_revision (opts -> revs )))
855857 next = commit_list_append (commit , next );
856858}
857859
@@ -942,7 +944,7 @@ static int sequencer_rollback(struct replay_opts *opts)
942944 }
943945 if (reset_for_rollback (sha1 ))
944946 goto fail ;
945- remove_sequencer_state (1 );
947+ remove_sequencer_state ();
946948 strbuf_release (& buf );
947949 return 0 ;
948950fail :
@@ -1016,33 +1018,64 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
10161018 for (cur = todo_list ; cur ; cur = cur -> next ) {
10171019 save_todo (cur , opts );
10181020 res = do_pick_commit (cur -> item , opts );
1019- if (res ) {
1020- if (!cur -> next )
1021- /*
1022- * An error was encountered while
1023- * picking the last commit; the
1024- * sequencer state is useless now --
1025- * the user simply needs to resolve
1026- * the conflict and commit
1027- */
1028- remove_sequencer_state (0 );
1021+ if (res )
10291022 return res ;
1030- }
10311023 }
10321024
10331025 /*
10341026 * Sequence of picks finished successfully; cleanup by
10351027 * removing the .git/sequencer directory
10361028 */
1037- remove_sequencer_state (1 );
1029+ remove_sequencer_state ();
10381030 return 0 ;
10391031}
10401032
1033+ static int continue_single_pick (void )
1034+ {
1035+ const char * argv [] = { "commit" , NULL };
1036+
1037+ if (!file_exists (git_path ("CHERRY_PICK_HEAD" )) &&
1038+ !file_exists (git_path ("REVERT_HEAD" )))
1039+ return error (_ ("no cherry-pick or revert in progress" ));
1040+ return run_command_v_opt (argv , RUN_GIT_CMD );
1041+ }
1042+
1043+ static int sequencer_continue (struct replay_opts * opts )
1044+ {
1045+ struct commit_list * todo_list = NULL ;
1046+
1047+ if (!file_exists (git_path (SEQ_TODO_FILE )))
1048+ return continue_single_pick ();
1049+ read_populate_opts (& opts );
1050+ read_populate_todo (& todo_list , opts );
1051+
1052+ /* Verify that the conflict has been resolved */
1053+ if (file_exists (git_path ("CHERRY_PICK_HEAD" )) ||
1054+ file_exists (git_path ("REVERT_HEAD" ))) {
1055+ int ret = continue_single_pick ();
1056+ if (ret )
1057+ return ret ;
1058+ }
1059+ if (index_differs_from ("HEAD" , 0 ))
1060+ return error_dirty_index (opts );
1061+ todo_list = todo_list -> next ;
1062+ return pick_commits (todo_list , opts );
1063+ }
1064+
1065+ static int single_pick (struct commit * cmit , struct replay_opts * opts )
1066+ {
1067+ setenv (GIT_REFLOG_ACTION , action_name (opts ), 0 );
1068+ return do_pick_commit (cmit , opts );
1069+ }
1070+
10411071static int pick_revisions (struct replay_opts * opts )
10421072{
10431073 struct commit_list * todo_list = NULL ;
10441074 unsigned char sha1 [20 ];
10451075
1076+ if (opts -> subcommand == REPLAY_NONE )
1077+ assert (opts -> revs );
1078+
10461079 read_and_refresh_cache (opts );
10471080
10481081 /*
@@ -1051,21 +1084,32 @@ static int pick_revisions(struct replay_opts *opts)
10511084 * one that is being continued
10521085 */
10531086 if (opts -> subcommand == REPLAY_REMOVE_STATE ) {
1054- remove_sequencer_state (1 );
1087+ remove_sequencer_state ();
10551088 return 0 ;
10561089 }
10571090 if (opts -> subcommand == REPLAY_ROLLBACK )
10581091 return sequencer_rollback (opts );
1059- if (opts -> subcommand == REPLAY_CONTINUE ) {
1060- if (!file_exists (git_path (SEQ_TODO_FILE )))
1061- return error (_ ("No %s in progress" ), action_name (opts ));
1062- read_populate_opts (& opts );
1063- read_populate_todo (& todo_list , opts );
1064-
1065- /* Verify that the conflict has been resolved */
1066- if (!index_differs_from ("HEAD" , 0 ))
1067- todo_list = todo_list -> next ;
1068- return pick_commits (todo_list , opts );
1092+ if (opts -> subcommand == REPLAY_CONTINUE )
1093+ return sequencer_continue (opts );
1094+
1095+ /*
1096+ * If we were called as "git cherry-pick <commit>", just
1097+ * cherry-pick/revert it, set CHERRY_PICK_HEAD /
1098+ * REVERT_HEAD, and don't touch the sequencer state.
1099+ * This means it is possible to cherry-pick in the middle
1100+ * of a cherry-pick sequence.
1101+ */
1102+ if (opts -> revs -> cmdline .nr == 1 &&
1103+ opts -> revs -> cmdline .rev -> whence == REV_CMD_REV &&
1104+ opts -> revs -> no_walk &&
1105+ !opts -> revs -> cmdline .rev -> flags ) {
1106+ struct commit * cmit ;
1107+ if (prepare_revision_walk (opts -> revs ))
1108+ die (_ ("revision walk setup failed" ));
1109+ cmit = get_revision (opts -> revs );
1110+ if (!cmit || get_revision (opts -> revs ))
1111+ die ("BUG: expected exactly one commit from walk" );
1112+ return single_pick (cmit , opts );
10691113 }
10701114
10711115 /*
0 commit comments