1414#include "merge-recursive.h"
1515#include "refs.h"
1616#include "dir.h"
17+ #include "sequencer.h"
1718
1819/*
1920 * This implements the builtins revert and cherry-pick.
2829
2930static const char * const revert_usage [] = {
3031 "git revert [options] <commit-ish>" ,
32+ "git revert <subcommand>" ,
3133 NULL
3234};
3335
3436static const char * const cherry_pick_usage [] = {
3537 "git cherry-pick [options] <commit-ish>" ,
38+ "git cherry-pick <subcommand>" ,
3639 NULL
3740};
3841
3942enum replay_action { REVERT , CHERRY_PICK };
43+ enum replay_subcommand { REPLAY_NONE , REPLAY_RESET };
4044
4145struct replay_opts {
4246 enum replay_action action ;
47+ enum replay_subcommand subcommand ;
4348
4449 /* Boolean options */
4550 int edit ;
@@ -61,11 +66,6 @@ struct replay_opts {
6166
6267#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
6368
64- #define SEQ_DIR "sequencer"
65- #define SEQ_HEAD_FILE "sequencer/head"
66- #define SEQ_TODO_FILE "sequencer/todo"
67- #define SEQ_OPTS_FILE "sequencer/opts"
68-
6969static const char * action_name (const struct replay_opts * opts )
7070{
7171 return opts -> action == REVERT ? "revert" : "cherry-pick" ;
@@ -113,7 +113,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
113113 const char * const * usage_str = revert_or_cherry_pick_usage (opts );
114114 const char * me = action_name (opts );
115115 int noop ;
116+ int reset = 0 ;
116117 struct option options [] = {
118+ OPT_BOOLEAN (0 , "reset" , & reset , "forget the current operation" ),
117119 OPT_BOOLEAN ('n' , "no-commit" , & opts -> no_commit , "don't automatically commit" ),
118120 OPT_BOOLEAN ('e' , "edit" , & opts -> edit , "edit the commit message" ),
119121 { OPTION_BOOLEAN , 'r' , NULL , & noop , NULL , "no-op (backward compatibility)" ,
@@ -142,7 +144,27 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
142144 opts -> commit_argc = parse_options (argc , argv , NULL , options , usage_str ,
143145 PARSE_OPT_KEEP_ARGV0 |
144146 PARSE_OPT_KEEP_UNKNOWN );
145- if (opts -> commit_argc < 2 )
147+
148+ /* Set the subcommand */
149+ if (reset )
150+ opts -> subcommand = REPLAY_RESET ;
151+ else
152+ opts -> subcommand = REPLAY_NONE ;
153+
154+ /* Check for incompatible command line arguments */
155+ if (opts -> subcommand == REPLAY_RESET ) {
156+ verify_opt_compatible (me , "--reset" ,
157+ "--no-commit" , opts -> no_commit ,
158+ "--signoff" , opts -> signoff ,
159+ "--mainline" , opts -> mainline ,
160+ "--strategy" , opts -> strategy ? 1 : 0 ,
161+ "--strategy-option" , opts -> xopts ? 1 : 0 ,
162+ "-x" , opts -> record_origin ,
163+ "--ff" , opts -> allow_ff ,
164+ NULL );
165+ }
166+
167+ else if (opts -> commit_argc < 2 )
146168 usage_with_options (usage_str , options );
147169
148170 if (opts -> allow_ff )
@@ -729,7 +751,6 @@ static void save_opts(struct replay_opts *opts)
729751
730752static int pick_commits (struct commit_list * todo_list , struct replay_opts * opts )
731753{
732- struct strbuf buf = STRBUF_INIT ;
733754 struct commit_list * cur ;
734755 int res ;
735756
@@ -750,9 +771,7 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
750771 * Sequence of picks finished successfully; cleanup by
751772 * removing the .git/sequencer directory
752773 */
753- strbuf_addf (& buf , "%s" , git_path (SEQ_DIR ));
754- remove_dir_recursively (& buf , 0 );
755- strbuf_release (& buf );
774+ remove_sequencer_state (1 );
756775 return 0 ;
757776}
758777
@@ -768,16 +787,21 @@ static int pick_revisions(struct replay_opts *opts)
768787 * cherry-pick should be handled differently from an existing
769788 * one that is being continued
770789 */
771- walk_revs_populate_todo (& todo_list , opts );
772- create_seq_dir ();
773- if (get_sha1 ("HEAD" , sha1 )) {
774- if (opts -> action == REVERT )
775- die (_ ("Can't revert as initial commit" ));
776- die (_ ("Can't cherry-pick into empty head" ));
790+ if (opts -> subcommand == REPLAY_RESET ) {
791+ remove_sequencer_state (1 );
792+ return 0 ;
793+ } else {
794+ /* Start a new cherry-pick/ revert sequence */
795+ walk_revs_populate_todo (& todo_list , opts );
796+ create_seq_dir ();
797+ if (get_sha1 ("HEAD" , sha1 )) {
798+ if (opts -> action == REVERT )
799+ die (_ ("Can't revert as initial commit" ));
800+ die (_ ("Can't cherry-pick into empty head" ));
801+ }
802+ save_head (sha1_to_hex (sha1 ));
803+ save_opts (opts );
777804 }
778- save_head (sha1_to_hex (sha1 ));
779- save_opts (opts );
780-
781805 return pick_commits (todo_list , opts );
782806}
783807
0 commit comments