Merge branch 'js/prepare-sequencer'
Update of the sequencer codebase to make it reusable to reimplement "rebase -i" continues. * js/prepare-sequencer: (27 commits) sequencer: mark all error messages for translation sequencer: start error messages consistently with lower case sequencer: quote filenames in error messages sequencer: mark action_name() for translation sequencer: remove overzealous assumption in rebase -i mode sequencer: teach write_message() to append an optional LF sequencer: refactor write_message() to take a pointer/length sequencer: roll back lock file if write_message() failed sequencer: stop releasing the strbuf in write_message() sequencer: left-trim lines read from the script sequencer: support cleaning up commit messages sequencer: support amending commits sequencer: allow editing the commit message on a case-by-case basis sequencer: introduce a helper to read files written by scripts sequencer: prepare for rebase -i's commit functionality sequencer: remember the onelines when parsing the todo file sequencer: get rid of the subcommand field sequencer: avoid completely different messages for different actions sequencer: strip CR from the todo script sequencer: completely revamp the "todo" script parsing ...
This commit is contained in:
commit
cca3be6ea1
@ -183,7 +183,7 @@ static void determine_whence(struct wt_status *s)
|
||||
whence = FROM_MERGE;
|
||||
else if (file_exists(git_path_cherry_pick_head())) {
|
||||
whence = FROM_CHERRY_PICK;
|
||||
if (file_exists(git_path(SEQ_DIR)))
|
||||
if (file_exists(git_path_seq_dir()))
|
||||
sequencer_in_use = 1;
|
||||
}
|
||||
else
|
||||
|
@ -71,7 +71,7 @@ static void verify_opt_compatible(const char *me, const char *base_opt, ...)
|
||||
die(_("%s: %s cannot be used with %s"), me, this_opt, base_opt);
|
||||
}
|
||||
|
||||
static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
||||
static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
|
||||
{
|
||||
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
|
||||
const char *me = action_name(opts);
|
||||
@ -115,25 +115,15 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
||||
if (opts->keep_redundant_commits)
|
||||
opts->allow_empty = 1;
|
||||
|
||||
/* Set the subcommand */
|
||||
if (cmd == 'q')
|
||||
opts->subcommand = REPLAY_REMOVE_STATE;
|
||||
else if (cmd == 'c')
|
||||
opts->subcommand = REPLAY_CONTINUE;
|
||||
else if (cmd == 'a')
|
||||
opts->subcommand = REPLAY_ROLLBACK;
|
||||
else
|
||||
opts->subcommand = REPLAY_NONE;
|
||||
|
||||
/* Check for incompatible command line arguments */
|
||||
if (opts->subcommand != REPLAY_NONE) {
|
||||
if (cmd) {
|
||||
char *this_operation;
|
||||
if (opts->subcommand == REPLAY_REMOVE_STATE)
|
||||
if (cmd == 'q')
|
||||
this_operation = "--quit";
|
||||
else if (opts->subcommand == REPLAY_CONTINUE)
|
||||
else if (cmd == 'c')
|
||||
this_operation = "--continue";
|
||||
else {
|
||||
assert(opts->subcommand == REPLAY_ROLLBACK);
|
||||
assert(cmd == 'a');
|
||||
this_operation = "--abort";
|
||||
}
|
||||
|
||||
@ -156,7 +146,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
||||
"--edit", opts->edit,
|
||||
NULL);
|
||||
|
||||
if (opts->subcommand != REPLAY_NONE) {
|
||||
if (cmd) {
|
||||
opts->revs = NULL;
|
||||
} else {
|
||||
struct setup_revision_opt s_r_opt;
|
||||
@ -174,20 +164,30 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
||||
|
||||
if (argc > 1)
|
||||
usage_with_options(usage_str, options);
|
||||
|
||||
/* These option values will be free()d */
|
||||
opts->gpg_sign = xstrdup_or_null(opts->gpg_sign);
|
||||
opts->strategy = xstrdup_or_null(opts->strategy);
|
||||
|
||||
if (cmd == 'q')
|
||||
return sequencer_remove_state(opts);
|
||||
if (cmd == 'c')
|
||||
return sequencer_continue(opts);
|
||||
if (cmd == 'a')
|
||||
return sequencer_rollback(opts);
|
||||
return sequencer_pick_revisions(opts);
|
||||
}
|
||||
|
||||
int cmd_revert(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct replay_opts opts;
|
||||
struct replay_opts opts = REPLAY_OPTS_INIT;
|
||||
int res;
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
if (isatty(0))
|
||||
opts.edit = 1;
|
||||
opts.action = REPLAY_REVERT;
|
||||
git_config(git_default_config, NULL);
|
||||
parse_args(argc, argv, &opts);
|
||||
res = sequencer_pick_revisions(&opts);
|
||||
res = run_sequencer(argc, argv, &opts);
|
||||
if (res < 0)
|
||||
die(_("revert failed"));
|
||||
return res;
|
||||
@ -195,14 +195,12 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
|
||||
|
||||
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct replay_opts opts;
|
||||
struct replay_opts opts = REPLAY_OPTS_INIT;
|
||||
int res;
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.action = REPLAY_PICK;
|
||||
git_config(git_default_config, NULL);
|
||||
parse_args(argc, argv, &opts);
|
||||
res = sequencer_pick_revisions(&opts);
|
||||
res = run_sequencer(argc, argv, &opts);
|
||||
if (res < 0)
|
||||
die(_("cherry-pick failed"));
|
||||
return res;
|
||||
|
682
sequencer.c
682
sequencer.c
File diff suppressed because it is too large
Load Diff
23
sequencer.h
23
sequencer.h
@ -1,10 +1,7 @@
|
||||
#ifndef SEQUENCER_H
|
||||
#define SEQUENCER_H
|
||||
|
||||
#define SEQ_DIR "sequencer"
|
||||
#define SEQ_HEAD_FILE "sequencer/head"
|
||||
#define SEQ_TODO_FILE "sequencer/todo"
|
||||
#define SEQ_OPTS_FILE "sequencer/opts"
|
||||
const char *git_path_seq_dir(void);
|
||||
|
||||
#define APPEND_SIGNOFF_DEDUP (1u << 0)
|
||||
|
||||
@ -13,16 +10,8 @@ enum replay_action {
|
||||
REPLAY_PICK
|
||||
};
|
||||
|
||||
enum replay_subcommand {
|
||||
REPLAY_NONE,
|
||||
REPLAY_REMOVE_STATE,
|
||||
REPLAY_CONTINUE,
|
||||
REPLAY_ROLLBACK
|
||||
};
|
||||
|
||||
struct replay_opts {
|
||||
enum replay_action action;
|
||||
enum replay_subcommand subcommand;
|
||||
|
||||
/* Boolean options */
|
||||
int edit;
|
||||
@ -37,18 +26,22 @@ struct replay_opts {
|
||||
|
||||
int mainline;
|
||||
|
||||
const char *gpg_sign;
|
||||
char *gpg_sign;
|
||||
|
||||
/* Merge strategy */
|
||||
const char *strategy;
|
||||
const char **xopts;
|
||||
char *strategy;
|
||||
char **xopts;
|
||||
size_t xopts_nr, xopts_alloc;
|
||||
|
||||
/* Only used by REPLAY_NONE */
|
||||
struct rev_info *revs;
|
||||
};
|
||||
#define REPLAY_OPTS_INIT { -1 }
|
||||
|
||||
int sequencer_pick_revisions(struct replay_opts *opts);
|
||||
int sequencer_continue(struct replay_opts *opts);
|
||||
int sequencer_rollback(struct replay_opts *opts);
|
||||
int sequencer_remove_state(struct replay_opts *opts);
|
||||
|
||||
extern const char sign_off_header[];
|
||||
|
||||
|
@ -96,7 +96,7 @@ test_expect_success 'revert forbidden on dirty working tree' '
|
||||
echo content >extra_file &&
|
||||
git add extra_file &&
|
||||
test_must_fail git revert HEAD 2>errors &&
|
||||
test_i18ngrep "Your local changes would be overwritten by " errors
|
||||
test_i18ngrep "your local changes would be overwritten by " errors
|
||||
|
||||
'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user