summaryrefslogtreecommitdiff
path: root/builtin/rebase.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/rebase.c')
-rw-r--r--builtin/rebase.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 8402765a79..774264bae8 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -104,6 +104,7 @@ struct rebase_options {
int rebase_merges, rebase_cousins;
char *strategy, *strategy_opts;
struct strbuf git_format_patch_opt;
+ int reschedule_failed_exec;
};
static int is_interactive(struct rebase_options *opts)
@@ -415,6 +416,8 @@ static int run_specific_rebase(struct rebase_options *opts)
argv_array_push(&child.args, opts->gpg_sign_opt);
if (opts->signoff)
argv_array_push(&child.args, "--signoff");
+ if (opts->reschedule_failed_exec)
+ argv_array_push(&child.args, "--reschedule-failed-exec");
status = run_command(&child);
goto finished_rebase;
@@ -600,7 +603,7 @@ static int reset_head(struct object_id *oid, const char *action,
}
tree = parse_tree_indirect(oid);
- prime_cache_tree(the_repository->index, tree);
+ prime_cache_tree(the_repository, the_repository->index, tree);
if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) {
ret = error(_("could not write index"));
@@ -680,6 +683,11 @@ static int rebase_config(const char *var, const char *value, void *data)
return 0;
}
+ if (!strcmp(var, "rebase.reschedulefailedexec")) {
+ opts->reschedule_failed_exec = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, data);
}
@@ -752,6 +760,23 @@ static int parse_opt_interactive(const struct option *opt, const char *arg,
return 0;
}
+struct opt_y {
+ struct string_list *list;
+ struct rebase_options *options;
+};
+
+static int parse_opt_y(const struct option *opt, const char *arg, int unset)
+{
+ struct opt_y *o = opt->value;
+
+ if (unset || !arg)
+ return -1;
+
+ o->options->reschedule_failed_exec = 1;
+ string_list_append(o->list, arg);
+ return 0;
+}
+
static void NORETURN error_on_missing_default_upstream(void)
{
struct branch *current_branch = branch_get(NULL);
@@ -832,6 +857,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct string_list strategy_options = STRING_LIST_INIT_NODUP;
struct object_id squash_onto;
char *squash_onto_name = NULL;
+ struct opt_y opt_y = { .list = &exec, .options = &options };
struct option builtin_rebase_options[] = {
OPT_STRING(0, "onto", &options.onto_name,
N_("revision"),
@@ -909,6 +935,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
N_("add exec lines after each commit of the "
"editable list")),
+ { OPTION_CALLBACK, 'y', NULL, &opt_y, N_("<cmd>"),
+ N_("same as --reschedule-failed-exec -x <cmd>"),
+ PARSE_OPT_NONEG, parse_opt_y },
OPT_BOOL(0, "allow-empty-message",
&options.allow_empty_message,
N_("allow rebasing commits with empty messages")),
@@ -926,6 +955,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
"strategy")),
OPT_BOOL(0, "root", &options.root,
N_("rebase all reachable commits up to the root(s)")),
+ OPT_BOOL(0, "reschedule-failed-exec",
+ &options.reschedule_failed_exec,
+ N_("automatically re-schedule any `exec` that fails")),
OPT_END(),
};
int i;
@@ -1030,7 +1062,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
&lock_file);
rollback_lock_file(&lock_file);
- if (has_unstaged_changes(1)) {
+ if (has_unstaged_changes(the_repository, 1)) {
puts(_("You must edit all merge conflicts and then\n"
"mark them as resolved using git add"));
exit(1);
@@ -1045,13 +1077,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.action = "skip";
set_reflog_action(&options);
- rerere_clear(&merge_rr);
+ rerere_clear(the_repository, &merge_rr);
string_list_clear(&merge_rr, 1);
if (reset_head(NULL, "reset", NULL, RESET_HEAD_HARD,
NULL, NULL) < 0)
die(_("could not discard worktree changes"));
- remove_branch_state();
+ remove_branch_state(the_repository);
if (read_basic_state(&options))
exit(1);
goto run_rebase;
@@ -1061,7 +1093,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.action = "abort";
set_reflog_action(&options);
- rerere_clear(&merge_rr);
+ rerere_clear(the_repository, &merge_rr);
string_list_clear(&merge_rr, 1);
if (read_basic_state(&options))
@@ -1071,7 +1103,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
NULL, NULL) < 0)
die(_("could not move back to %s"),
oid_to_hex(&options.orig_head));
- remove_branch_state();
+ remove_branch_state(the_repository);
ret = finish_rebase(&options);
goto cleanup;
}
@@ -1222,6 +1254,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
break;
}
+ if (options.reschedule_failed_exec && !is_interactive(&options))
+ die(_("--reschedule-failed-exec requires an interactive rebase"));
+
if (options.git_am_opts.argc) {
/* all am options except -q are compatible only with --am */
for (i = options.git_am_opts.argc - 1; i >= 0; i--)
@@ -1247,7 +1282,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.flags |= REBASE_FORCE;
}
- if (options.type == REBASE_PRESERVE_MERGES)
+ if (options.type == REBASE_PRESERVE_MERGES) {
/*
* Note: incompatibility with --signoff handled in signoff block above
* Note: incompatibility with --interactive is just a strong warning;
@@ -1257,6 +1292,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("error: cannot combine '--preserve-merges' with "
"'--rebase-merges'"));
+ if (options.reschedule_failed_exec)
+ die(_("error: cannot combine '--preserve-merges' with "
+ "'--reschedule-failed-exec'"));
+ }
+
if (options.rebase_merges) {
if (strategy_options.nr)
die(_("error: cannot combine '--rebase-merges' with "
@@ -1387,7 +1427,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
update_index_if_able(&the_index, &lock_file);
rollback_lock_file(&lock_file);
- if (has_unstaged_changes(1) || has_uncommitted_changes(1)) {
+ if (has_unstaged_changes(the_repository, 1) ||
+ has_uncommitted_changes(the_repository, 1)) {
const char *autostash =
state_dir_path("autostash", &options);
struct child_process stash = CHILD_PROCESS_INIT;
@@ -1433,7 +1474,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
}
}
- if (require_clean_work_tree("rebase",
+ if (require_clean_work_tree(the_repository, "rebase",
_("Please commit or stash them."), 1, 1)) {
ret = 1;
goto cleanup;