@@ -60,13 +60,14 @@ struct replay_opts {
60
60
int allow_rerere_auto ;
61
61
62
62
int mainline ;
63
- int commit_argc ;
64
- const char * * commit_argv ;
65
63
66
64
/* Merge strategy */
67
65
const char * strategy ;
68
66
const char * * xopts ;
69
67
size_t xopts_nr , xopts_alloc ;
68
+
69
+ /* Only used by REPLAY_NONE */
70
+ struct rev_info * revs ;
70
71
};
71
72
72
73
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
@@ -169,9 +170,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
169
170
die (_ ("program error" ));
170
171
}
171
172
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 );
175
176
176
177
/* Check for incompatible subcommands */
177
178
verify_opt_mutually_compatible (me ,
@@ -213,17 +214,27 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
213
214
NULL );
214
215
}
215
216
216
- else if (opts -> commit_argc < 2 )
217
- usage_with_options (usage_str , options );
218
-
219
217
if (opts -> allow_ff )
220
218
verify_opt_compatible (me , "--ff" ,
221
219
"--signoff" , opts -> signoff ,
222
220
"--no-commit" , opts -> no_commit ,
223
221
"-x" , opts -> record_origin ,
224
222
"--edit" , opts -> edit ,
225
223
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 );
227
238
}
228
239
229
240
struct commit_message {
@@ -631,23 +642,15 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
631
642
return res ;
632
643
}
633
644
634
- static void prepare_revs (struct rev_info * revs , struct replay_opts * opts )
645
+ static void prepare_revs (struct replay_opts * opts )
635
646
{
636
- int argc ;
637
-
638
- init_revisions (revs , NULL );
639
- revs -> no_walk = 1 ;
640
647
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 ;
646
649
647
- if (prepare_revision_walk (revs ))
650
+ if (prepare_revision_walk (opts -> revs ))
648
651
die (_ ("revision walk setup failed" ));
649
652
650
- if (!revs -> commits )
653
+ if (!opts -> revs -> commits )
651
654
die (_ ("empty commit set passed" ));
652
655
}
653
656
@@ -844,14 +847,13 @@ static void read_populate_opts(struct replay_opts **opts_ptr)
844
847
static void walk_revs_populate_todo (struct commit_list * * todo_list ,
845
848
struct replay_opts * opts )
846
849
{
847
- struct rev_info revs ;
848
850
struct commit * commit ;
849
851
struct commit_list * * next ;
850
852
851
- prepare_revs (& revs , opts );
853
+ prepare_revs (opts );
852
854
853
855
next = todo_list ;
854
- while ((commit = get_revision (& revs )))
856
+ while ((commit = get_revision (opts -> revs )))
855
857
next = commit_list_append (commit , next );
856
858
}
857
859
@@ -942,7 +944,7 @@ static int sequencer_rollback(struct replay_opts *opts)
942
944
}
943
945
if (reset_for_rollback (sha1 ))
944
946
goto fail ;
945
- remove_sequencer_state (1 );
947
+ remove_sequencer_state ();
946
948
strbuf_release (& buf );
947
949
return 0 ;
948
950
fail :
@@ -1016,33 +1018,64 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
1016
1018
for (cur = todo_list ; cur ; cur = cur -> next ) {
1017
1019
save_todo (cur , opts );
1018
1020
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 )
1029
1022
return res ;
1030
- }
1031
1023
}
1032
1024
1033
1025
/*
1034
1026
* Sequence of picks finished successfully; cleanup by
1035
1027
* removing the .git/sequencer directory
1036
1028
*/
1037
- remove_sequencer_state (1 );
1029
+ remove_sequencer_state ();
1038
1030
return 0 ;
1039
1031
}
1040
1032
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
+
1041
1071
static int pick_revisions (struct replay_opts * opts )
1042
1072
{
1043
1073
struct commit_list * todo_list = NULL ;
1044
1074
unsigned char sha1 [20 ];
1045
1075
1076
+ if (opts -> subcommand == REPLAY_NONE )
1077
+ assert (opts -> revs );
1078
+
1046
1079
read_and_refresh_cache (opts );
1047
1080
1048
1081
/*
@@ -1051,21 +1084,32 @@ static int pick_revisions(struct replay_opts *opts)
1051
1084
* one that is being continued
1052
1085
*/
1053
1086
if (opts -> subcommand == REPLAY_REMOVE_STATE ) {
1054
- remove_sequencer_state (1 );
1087
+ remove_sequencer_state ();
1055
1088
return 0 ;
1056
1089
}
1057
1090
if (opts -> subcommand == REPLAY_ROLLBACK )
1058
1091
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 );
1069
1113
}
1070
1114
1071
1115
/*
0 commit comments