summaryrefslogtreecommitdiff
path: root/sequencer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sequencer.c')
-rw-r--r--sequencer.c285
1 files changed, 187 insertions, 98 deletions
diff --git a/sequencer.c b/sequencer.c
index b4c63ae207..614d56f5e2 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -164,6 +164,7 @@ static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")
static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")
static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, "rebase-merge/allow_rerere_autoupdate")
static GIT_PATH_FUNC(rebase_path_reschedule_failed_exec, "rebase-merge/reschedule-failed-exec")
+static GIT_PATH_FUNC(rebase_path_no_reschedule_failed_exec, "rebase-merge/no-reschedule-failed-exec")
static GIT_PATH_FUNC(rebase_path_drop_redundant_commits, "rebase-merge/drop_redundant_commits")
static GIT_PATH_FUNC(rebase_path_keep_redundant_commits, "rebase-merge/keep_redundant_commits")
@@ -402,7 +403,7 @@ static void print_advice(struct repository *r, int show_hint,
char *msg = getenv("GIT_CHERRY_PICK_HELP");
if (msg) {
- fprintf(stderr, "%s\n", msg);
+ advise("%s\n", msg);
/*
* A conflict has occurred but the porcelain
* (typically rebase --interactive) wants to take care
@@ -417,10 +418,22 @@ static void print_advice(struct repository *r, int show_hint,
if (opts->no_commit)
advise(_("after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'"));
+ else if (opts->action == REPLAY_PICK)
+ advise(_("After resolving the conflicts, mark them with\n"
+ "\"git add/rm <pathspec>\", then run\n"
+ "\"git cherry-pick --continue\".\n"
+ "You can instead skip this commit with \"git cherry-pick --skip\".\n"
+ "To abort and get back to the state before \"git cherry-pick\",\n"
+ "run \"git cherry-pick --abort\"."));
+ else if (opts->action == REPLAY_REVERT)
+ advise(_("After resolving the conflicts, mark them with\n"
+ "\"git add/rm <pathspec>\", then run\n"
+ "\"git revert --continue\".\n"
+ "You can instead skip this commit with \"git revert --skip\".\n"
+ "To abort and get back to the state before \"git revert\",\n"
+ "run \"git revert --abort\"."));
else
- advise(_("after resolving the conflicts, mark the corrected paths\n"
- "with 'git add <paths>' or 'git rm <paths>'\n"
- "and commit the result with 'git commit'"));
+ BUG("unexpected pick action in print_advice()");
}
}
@@ -485,7 +498,7 @@ static int error_dirty_index(struct repository *repo, struct replay_opts *opts)
error(_("your local changes would be overwritten by %s."),
_(action_name(opts)));
- if (advice_commit_before_merge)
+ if (advice_enabled(ADVICE_COMMIT_BEFORE_MERGE))
advise(_("commit your changes or stash them to proceed."));
return -1;
}
@@ -524,7 +537,7 @@ static int fast_forward_to(struct repository *r,
if (!transaction ||
ref_transaction_update(transaction, "HEAD",
to, unborn && !is_rebase_i(opts) ?
- &null_oid : from,
+ null_oid() : from,
0, sb.buf, &err) ||
ref_transaction_commit(transaction, &err)) {
ref_transaction_free(transaction);
@@ -635,7 +648,7 @@ static int do_recursive_merge(struct repository *r,
for (i = 0; i < opts->xopts_nr; i++)
parse_merge_opt(&o, opts->xopts[i]);
- if (opts->strategy && !strcmp(opts->strategy, "ort")) {
+ if (!opts->strategy || !strcmp(opts->strategy, "ort")) {
memset(&result, 0, sizeof(result));
merge_incore_nonrecursive(&o, base_tree, head_tree, next_tree,
&result);
@@ -651,6 +664,7 @@ static int do_recursive_merge(struct repository *r,
merge_switch_to_result(&o, head_tree, &result, 1, show_output);
clean = result.clean;
} else {
+ ensure_full_index(r->index);
clean = merge_trees(&o, head_tree, next_tree, base_tree);
if (is_rebase_i(opts) && clean <= 0)
fputs(o.obuf.buf, stdout);
@@ -982,7 +996,8 @@ static int run_git_commit(const char *defmsg,
cmd.git_cmd = 1;
- if (is_rebase_i(opts) && read_env_script(&cmd.env_array)) {
+ if (is_rebase_i(opts) && !(!defmsg && (flags & AMEND_MSG)) &&
+ read_env_script(&cmd.env_array)) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
return error(_(staged_changes_advice),
@@ -1131,7 +1146,7 @@ int update_head_with_reflog(const struct commit *old_head,
transaction = ref_transaction_begin(err);
if (!transaction ||
ref_transaction_update(transaction, "HEAD", new_head,
- old_head ? &old_head->object.oid : &null_oid,
+ old_head ? &old_head->object.oid : null_oid(),
0, sb.buf, err) ||
ref_transaction_commit(transaction, err)) {
ret = -1;
@@ -1240,7 +1255,7 @@ N_("Your name and email address were configured automatically based\n"
static const char *implicit_ident_advice(void)
{
- char *user_config = expand_user_path("~/.gitconfig", 0);
+ char *user_config = interpolate_path("~/.gitconfig", 0);
char *xdg_config = xdg_config_home("config");
int config_exists = file_exists(user_config) || file_exists(xdg_config);
@@ -1292,7 +1307,7 @@ void print_commit_summary(struct repository *r,
if (!committer_ident_sufficiently_given()) {
strbuf_addstr(&format, "\n Committer: ");
strbuf_addbuf_percentquote(&format, &committer_ident);
- if (advice_implicit_identity) {
+ if (advice_enabled(ADVICE_IMPLICIT_IDENTITY)) {
strbuf_addch(&format, '\n');
strbuf_addstr(&format, implicit_ident_advice());
}
@@ -2032,13 +2047,24 @@ static void record_in_rewritten(struct object_id *oid,
flush_rewritten_pending();
}
+static int should_edit(struct replay_opts *opts) {
+ if (opts->edit < 0)
+ /*
+ * Note that we only handle the case of non-conflicted
+ * commits; continue_single_pick() handles the conflicted
+ * commits itself instead of calling this function.
+ */
+ return (opts->action == REPLAY_REVERT && isatty(0)) ? 1 : 0;
+ return opts->edit;
+}
+
static int do_pick_commit(struct repository *r,
struct todo_item *item,
struct replay_opts *opts,
int final_fixup, int *check_todo)
{
- unsigned int flags = opts->edit ? EDIT_MSG : 0;
- const char *msg_file = opts->edit ? NULL : git_path_merge_msg(r);
+ unsigned int flags = should_edit(opts) ? EDIT_MSG : 0;
+ const char *msg_file = should_edit(opts) ? NULL : git_path_merge_msg(r);
struct object_id head;
struct commit *base, *next, *parent;
const char *base_label, *next_label;
@@ -2053,7 +2079,7 @@ static int do_pick_commit(struct repository *r,
/*
* We do not intend to commit immediately. We just want to
* merge the differences in, so let's compute the tree
- * that represents the "current" state for merge-recursive
+ * that represents the "current" state for the merge machinery
* to work on.
*/
if (write_index_as_tree(&head, r->index, r->index_file, 0, NULL))
@@ -2270,6 +2296,7 @@ static int do_pick_commit(struct repository *r,
refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD",
NULL, 0);
unlink(git_path_merge_msg(r));
+ unlink(git_path_auto_merge(r));
fprintf(stderr,
_("dropping %s %s -- patch contents already upstream\n"),
oid_to_hex(&commit->object.oid), msg.subject);
@@ -2333,6 +2360,7 @@ static int read_and_refresh_cache(struct repository *r,
_(action_name(opts)));
}
refresh_index(r->index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
+
if (index_fd >= 0) {
if (write_locked_index(r->index, &index_lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED)) {
@@ -2340,6 +2368,13 @@ static int read_and_refresh_cache(struct repository *r,
_(action_name(opts)));
}
}
+
+ /*
+ * If we are resolving merges in any way other than "ort", then
+ * expand the sparse index.
+ */
+ if (opts->strategy && strcmp(opts->strategy, "ort"))
+ ensure_full_index(r->index);
return 0;
}
@@ -2633,6 +2668,8 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)
need_cleanup = 1;
}
+ unlink(git_path_auto_merge(r));
+
if (!need_cleanup)
return;
@@ -2854,6 +2891,8 @@ static int read_populate_opts(struct replay_opts *opts)
if (file_exists(rebase_path_reschedule_failed_exec()))
opts->reschedule_failed_exec = 1;
+ else if (file_exists(rebase_path_no_reschedule_failed_exec()))
+ opts->reschedule_failed_exec = 0;
if (file_exists(rebase_path_drop_redundant_commits()))
opts->drop_redundant_commits = 1;
@@ -2954,6 +2993,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
write_file(rebase_path_ignore_date(), "%s", "");
if (opts->reschedule_failed_exec)
write_file(rebase_path_reschedule_failed_exec(), "%s", "");
+ else
+ write_file(rebase_path_no_reschedule_failed_exec(), "%s", "");
return 0;
}
@@ -3022,7 +3063,7 @@ static int create_seq_dir(struct repository *r)
}
if (in_progress_error) {
error("%s", in_progress_error);
- if (advice_sequencer_in_use)
+ if (advice_enabled(ADVICE_SEQUENCER_IN_USE))
advise(in_progress_advice,
advise_skip ? "--skip | " : "");
return -1;
@@ -3226,7 +3267,7 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)
give_advice:
error(_("there is nothing to skip"));
- if (advice_resolve_conflict) {
+ if (advice_enabled(ADVICE_RESOLVE_CONFLICT)) {
advise(_("have you committed already?\n"
"try \"git %s --continue\""),
action == REPLAY_REVERT ? "revert" : "cherry-pick");
@@ -3283,9 +3324,9 @@ static int save_opts(struct replay_opts *opts)
if (opts->no_commit)
res |= git_config_set_in_file_gently(opts_file,
"options.no-commit", "true");
- if (opts->edit)
- res |= git_config_set_in_file_gently(opts_file,
- "options.edit", "true");
+ if (opts->edit >= 0)
+ res |= git_config_set_in_file_gently(opts_file, "options.edit",
+ opts->edit ? "true" : "false");
if (opts->allow_empty)
res |= git_config_set_in_file_gently(opts_file,
"options.allow-empty", "true");
@@ -3502,6 +3543,7 @@ static int do_exec(struct repository *r, const char *command_line)
return status;
}
+__attribute__((format (printf, 2, 3)))
static int safe_append(const char *filename, const char *fmt, ...)
{
va_list ap;
@@ -3579,8 +3621,27 @@ static int do_label(struct repository *r, const char *name, int len)
return ret;
}
+__attribute__((format (printf, 3, 4)))
static const char *reflog_message(struct replay_opts *opts,
- const char *sub_action, const char *fmt, ...);
+ const char *sub_action, const char *fmt, ...)
+{
+ va_list ap;
+ static struct strbuf buf = STRBUF_INIT;
+ char *reflog_action = getenv(GIT_REFLOG_ACTION);
+
+ va_start(ap, fmt);
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, reflog_action ? reflog_action : action_name(opts));
+ if (sub_action)
+ strbuf_addf(&buf, " (%s)", sub_action);
+ if (fmt) {
+ strbuf_addstr(&buf, ": ");
+ strbuf_vaddf(&buf, fmt, ap);
+ }
+ va_end(ap);
+
+ return buf.buf;
+}
static int do_reset(struct repository *r,
const char *name, int len,
@@ -3700,10 +3761,9 @@ static struct commit *lookup_label(const char *label, int len,
static int do_merge(struct repository *r,
struct commit *commit,
const char *arg, int arg_len,
- int flags, struct replay_opts *opts)
+ int flags, int *check_todo, struct replay_opts *opts)
{
- int run_commit_flags = (flags & TODO_EDIT_MERGE_MSG) ?
- EDIT_MSG | VERIFY_MSG : 0;
+ int run_commit_flags = 0;
struct strbuf ref_name = STRBUF_INIT;
struct commit *head_commit, *merge_commit, *i;
struct commit_list *bases, *j, *reversed = NULL;
@@ -3777,6 +3837,45 @@ static int do_merge(struct repository *r,
goto leave_merge;
}
+ /*
+ * If HEAD is not identical to the first parent of the original merge
+ * commit, we cannot fast-forward.
+ */
+ can_fast_forward = opts->allow_ff && commit && commit->parents &&
+ oideq(&commit->parents->item->object.oid,
+ &head_commit->object.oid);
+
+ /*
+ * If any merge head is different from the original one, we cannot
+ * fast-forward.
+ */
+ if (can_fast_forward) {
+ struct commit_list *p = commit->parents->next;
+
+ for (j = to_merge; j && p; j = j->next, p = p->next)
+ if (!oideq(&j->item->object.oid,
+ &p->item->object.oid)) {
+ can_fast_forward = 0;
+ break;
+ }
+ /*
+ * If the number of merge heads differs from the original merge
+ * commit, we cannot fast-forward.
+ */
+ if (j || p)
+ can_fast_forward = 0;
+ }
+
+ if (can_fast_forward) {
+ rollback_lock_file(&lock);
+ ret = fast_forward_to(r, &commit->object.oid,
+ &head_commit->object.oid, 0, opts);
+ if (flags & TODO_EDIT_MERGE_MSG)
+ goto fast_forward_edit;
+
+ goto leave_merge;
+ }
+
if (commit) {
const char *encoding = get_commit_output_encoding();
const char *message = logmsg_reencode(commit, NULL, encoding);
@@ -3826,46 +3925,6 @@ static int do_merge(struct repository *r,
}
}
- /*
- * If HEAD is not identical to the first parent of the original merge
- * commit, we cannot fast-forward.
- */
- can_fast_forward = opts->allow_ff && commit && commit->parents &&
- oideq(&commit->parents->item->object.oid,
- &head_commit->object.oid);
-
- /*
- * If any merge head is different from the original one, we cannot
- * fast-forward.
- */
- if (can_fast_forward) {
- struct commit_list *p = commit->parents->next;
-
- for (j = to_merge; j && p; j = j->next, p = p->next)
- if (!oideq(&j->item->object.oid,
- &p->item->object.oid)) {
- can_fast_forward = 0;
- break;
- }
- /*
- * If the number of merge heads differs from the original merge
- * commit, we cannot fast-forward.
- */
- if (j || p)
- can_fast_forward = 0;
- }
-
- if (can_fast_forward) {
- rollback_lock_file(&lock);
- ret = fast_forward_to(r, &commit->object.oid,
- &head_commit->object.oid, 0, opts);
- if (flags & TODO_EDIT_MERGE_MSG) {
- run_commit_flags |= AMEND_MSG;
- goto fast_forward_edit;
- }
- goto leave_merge;
- }
-
if (strategy || to_merge->next) {
/* Octopus merge */
struct child_process cmd = CHILD_PROCESS_INIT;
@@ -3896,7 +3955,10 @@ static int do_merge(struct repository *r,
strvec_pushf(&cmd.args,
"-X%s", opts->xopts[k]);
}
- strvec_push(&cmd.args, "--no-edit");
+ if (!(flags & TODO_EDIT_MERGE_MSG))
+ strvec_push(&cmd.args, "--no-edit");
+ else
+ strvec_push(&cmd.args, "--edit");
strvec_push(&cmd.args, "--no-ff");
strvec_push(&cmd.args, "--no-log");
strvec_push(&cmd.args, "--no-stat");
@@ -3949,7 +4011,7 @@ static int do_merge(struct repository *r,
o.branch2 = ref_name.buf;
o.buffer_output = 2;
- if (opts->strategy && !strcmp(opts->strategy, "ort")) {
+ if (!opts->strategy || !strcmp(opts->strategy, "ort")) {
/*
* TODO: Should use merge_incore_recursive() and
* merge_switch_to_result(), skipping the call to
@@ -3996,10 +4058,17 @@ static int do_merge(struct repository *r,
* value (a negative one would indicate that the `merge`
* command needs to be rescheduled).
*/
- fast_forward_edit:
ret = !!run_git_commit(git_path_merge_msg(r), opts,
run_commit_flags);
+ if (!ret && flags & TODO_EDIT_MERGE_MSG) {
+ fast_forward_edit:
+ *check_todo = 1;
+ run_commit_flags |= AMEND_MSG | EDIT_MSG | VERIFY_MSG;
+ ret = !!run_git_commit(NULL, opts, run_commit_flags);
+ }
+
+
leave_merge:
strbuf_release(&ref_name);
rollback_lock_file(&lock);
@@ -4159,27 +4228,6 @@ int apply_autostash_oid(const char *stash_oid)
return apply_save_autostash_oid(stash_oid, 1);
}
-static const char *reflog_message(struct replay_opts *opts,
- const char *sub_action, const char *fmt, ...)
-{
- va_list ap;
- static struct strbuf buf = STRBUF_INIT;
- char *reflog_action = getenv(GIT_REFLOG_ACTION);
-
- va_start(ap, fmt);
- strbuf_reset(&buf);
- strbuf_addstr(&buf, reflog_action ? reflog_action : action_name(opts));
- if (sub_action)
- strbuf_addf(&buf, " (%s)", sub_action);
- if (fmt) {
- strbuf_addstr(&buf, ": ");
- strbuf_vaddf(&buf, fmt, ap);
- }
- va_end(ap);
-
- return buf.buf;
-}
-
static int run_git_checkout(struct repository *r, struct replay_opts *opts,
const char *commit, const char *action)
{
@@ -4259,7 +4307,7 @@ static int pick_commits(struct repository *r,
prev_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
if (opts->allow_ff)
assert(!(opts->signoff || opts->no_commit ||
- opts->record_origin || opts->edit ||
+ opts->record_origin || should_edit(opts) ||
opts->committer_date_is_author_date ||
opts->ignore_date));
if (read_and_refresh_cache(r, opts))
@@ -4293,6 +4341,7 @@ static int pick_commits(struct repository *r,
unlink(rebase_path_stopped_sha());
unlink(rebase_path_amend());
unlink(git_path_merge_head(r));
+ unlink(git_path_auto_merge(r));
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
if (item->command == TODO_BREAK) {
@@ -4386,9 +4435,8 @@ static int pick_commits(struct repository *r,
if ((res = do_reset(r, arg, item->arg_len, opts)))
reschedule = 1;
} else if (item->command == TODO_MERGE) {
- if ((res = do_merge(r, item->commit,
- arg, item->arg_len,
- item->flags, opts)) < 0)
+ if ((res = do_merge(r, item->commit, arg, item->arg_len,
+ item->flags, &check_todo, opts)) < 0)
reschedule = 1;
else if (item->commit)
record_in_rewritten(&item->commit->object.oid,
@@ -4552,14 +4600,33 @@ cleanup_head_ref:
return sequencer_remove_state(opts);
}
-static int continue_single_pick(struct repository *r)
+static int continue_single_pick(struct repository *r, struct replay_opts *opts)
{
- const char *argv[] = { "commit", NULL };
+ struct strvec argv = STRVEC_INIT;
+ int ret;
if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))
return error(_("no cherry-pick or revert in progress"));
- return run_command_v_opt(argv, RUN_GIT_CMD);
+
+ strvec_push(&argv, "commit");
+
+ /*
+ * continue_single_pick() handles the case of recovering from a
+ * conflict. should_edit() doesn't handle that case; for a conflict,
+ * we want to edit if the user asked for it, or if they didn't specify
+ * and stdin is a tty.
+ */
+ if (!opts->edit || (opts->edit < 0 && !isatty(0)))
+ /*
+ * Include --cleanup=strip as well because we don't want the
+ * "# Conflicts:" messages.
+ */
+ strvec_pushl(&argv, "--no-edit", "--cleanup=strip", NULL);
+
+ ret = run_command_v_opt(argv.v, RUN_GIT_CMD);
+ strvec_clear(&argv);
+ return ret;
}
static int commit_staged_changes(struct repository *r,
@@ -4678,6 +4745,9 @@ static int commit_staged_changes(struct repository *r,
refs_delete_ref(get_main_ref_store(r), "",
"CHERRY_PICK_HEAD", NULL, 0))
return error(_("could not remove CHERRY_PICK_HEAD"));
+ if (unlink(git_path_merge_msg(r)) && errno != ENOENT)
+ return error_errno(_("could not remove '%s'"),
+ git_path_merge_msg(r));
if (!final_fixup)
return 0;
}
@@ -4687,6 +4757,7 @@ static int commit_staged_changes(struct repository *r,
return error(_("could not commit staged changes."));
unlink(rebase_path_amend());
unlink(git_path_merge_head(r));
+ unlink(git_path_auto_merge(r));
if (final_fixup) {
unlink(rebase_path_fixup_msg());
unlink(rebase_path_squash_msg());
@@ -4729,7 +4800,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
goto release_todo_list;
}
} else if (!file_exists(get_todo_path(opts)))
- return continue_single_pick(r);
+ return continue_single_pick(r, opts);
else if ((res = read_populate_todo(r, &todo_list, opts)))
goto release_todo_list;
@@ -4738,7 +4809,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
if (refs_ref_exists(get_main_ref_store(r),
"CHERRY_PICK_HEAD") ||
refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) {
- res = continue_single_pick(r);
+ res = continue_single_pick(r, opts);
if (res)
goto release_todo_list;
}
@@ -5060,6 +5131,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
+ int skipped_commit = 0;
struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
struct strbuf label = STRBUF_INIT;
struct commit_list *commits = NULL, **tail = &commits, *iter;
@@ -5110,8 +5182,13 @@ static int make_script_with_merges(struct pretty_print_context *pp,
oidset_insert(&interesting, &commit->object.oid);
is_empty = is_original_commit_empty(commit);
- if (!is_empty && (commit->object.flags & PATCHSAME))
+ if (!is_empty && (commit->object.flags & PATCHSAME)) {
+ if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)
+ warning(_("skipped previously applied commit %s"),
+ short_commit_name(commit));
+ skipped_commit = 1;
continue;
+ }
if (is_empty && !keep_empty)
continue;
@@ -5175,6 +5252,9 @@ static int make_script_with_merges(struct pretty_print_context *pp,
oidcpy(&entry->entry.oid, &commit->object.oid);
oidmap_put(&commit2todo, entry);
}
+ if (skipped_commit)
+ advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,
+ _("use --reapply-cherry-picks to include skipped commits"));
/*
* Second phase:
@@ -5295,6 +5375,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
int reapply_cherry_picks = flags & TODO_LIST_REAPPLY_CHERRY_PICKS;
+ int skipped_commit = 0;
repo_init_revisions(r, &revs, NULL);
revs.verbose_header = 1;
@@ -5330,8 +5411,13 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
while ((commit = get_revision(&revs))) {
int is_empty = is_original_commit_empty(commit);
- if (!is_empty && (commit->object.flags & PATCHSAME))
+ if (!is_empty && (commit->object.flags & PATCHSAME)) {
+ if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)
+ warning(_("skipped previously applied commit %s"),
+ short_commit_name(commit));
+ skipped_commit = 1;
continue;
+ }
if (is_empty && !keep_empty)
continue;
strbuf_addf(out, "%s %s ", insn,
@@ -5341,6 +5427,9 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
strbuf_addf(out, " %c empty", comment_line_char);
strbuf_addch(out, '\n');
}
+ if (skipped_commit)
+ advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,
+ _("use --reapply-cherry-picks to include skipped commits"));
return 0;
}