summaryrefslogtreecommitdiff
path: root/builtin/rebase.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/rebase.c')
-rw-r--r--builtin/rebase.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/builtin/rebase.c b/builtin/rebase.c
index bff53d5d16..c466923869 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -85,6 +85,7 @@ struct rebase_options {
const char *action;
int signoff;
int allow_rerere_autoupdate;
+ int keep_empty;
int autosquash;
char *gpg_sign_opt;
int autostash;
@@ -95,11 +96,13 @@ struct rebase_options {
struct strbuf git_format_patch_opt;
int reschedule_failed_exec;
int use_legacy_rebase;
+ int reapply_cherry_picks;
};
#define REBASE_OPTIONS_INIT { \
.type = REBASE_UNSPECIFIED, \
.empty = EMPTY_UNSPECIFIED, \
+ .keep_empty = 1, \
.default_backend = "merge", \
.flags = REBASE_NO_QUIET, \
.git_am_opts = ARGV_ARRAY_INIT, \
@@ -379,11 +382,13 @@ static int run_sequencer_rebase(struct rebase_options *opts,
git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands);
+ flags |= opts->keep_empty ? TODO_LIST_KEEP_EMPTY : 0;
flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
flags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;
flags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
+ flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;
switch (command) {
case ACTION_NONE: {
@@ -442,6 +447,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
return ret;
}
+static void imply_merge(struct rebase_options *opts, const char *option);
static int parse_opt_keep_empty(const struct option *opt, const char *arg,
int unset)
{
@@ -449,10 +455,8 @@ static int parse_opt_keep_empty(const struct option *opt, const char *arg,
BUG_ON_OPT_ARG(arg);
- /*
- * If we ever want to remap --keep-empty to --empty=keep, insert:
- * opts->empty = unset ? EMPTY_UNSPECIFIED : EMPTY_KEEP;
- */
+ imply_merge(opts, unset ? "--no-keep-empty" : "--keep-empty");
+ opts->keep_empty = !unset;
opts->type = REBASE_MERGE;
return 0;
}
@@ -471,7 +475,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
OPT_NEGBIT(0, "ff", &opts.flags, N_("allow fast-forward"),
REBASE_FORCE),
{ OPTION_CALLBACK, 'k', "keep-empty", &options, NULL,
- N_("(DEPRECATED) keep empty commits"),
+ N_("keep commits which start empty"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN,
parse_opt_keep_empty },
OPT_BOOL_F(0, "allow-empty-message", &opts.allow_empty_message,
@@ -559,7 +563,7 @@ static void imply_merge(struct rebase_options *opts, const char *option)
{
switch (opts->type) {
case REBASE_APPLY:
- die(_("%s requires an interactive rebase"), option);
+ die(_("%s requires the merge backend"), option);
break;
case REBASE_MERGE:
case REBASE_PRESERVE_MERGES:
@@ -868,6 +872,7 @@ static int reset_head(struct object_id *oid, const char *action,
unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
unpack_tree_opts.update = 1;
unpack_tree_opts.merge = 1;
+ init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL);
if (!detach_head)
unpack_tree_opts.reset = 1;
@@ -1162,6 +1167,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
opts->allow_rerere_autoupdate ?
opts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?
"--rerere-autoupdate" : "--no-rerere-autoupdate" : "");
+ add_var(&script_snippet, "keep_empty", opts->keep_empty ? "yes" : "");
add_var(&script_snippet, "autosquash", opts->autosquash ? "t" : "");
add_var(&script_snippet, "gpg_sign_opt", opts->gpg_sign_opt);
add_var(&script_snippet, "cmd", opts->cmd);
@@ -1547,7 +1553,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
N_("how to handle commits that become empty"),
PARSE_OPT_NONEG, parse_opt_empty),
{ OPTION_CALLBACK, 'k', "keep-empty", &options, NULL,
- N_("(DEPRECATED) keep empty commits"),
+ N_("keep commits which start empty"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN,
parse_opt_keep_empty },
OPT_BOOL(0, "autosquash", &options.autosquash,
@@ -1582,6 +1588,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "reschedule-failed-exec",
&reschedule_failed_exec,
N_("automatically re-schedule any `exec` that fails")),
+ OPT_BOOL(0, "reapply-cherry-picks", &options.reapply_cherry_picks,
+ N_("apply all changes, even those already present upstream")),
OPT_END(),
};
int i;
@@ -1592,6 +1600,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.allow_empty_message = 1;
git_config(rebase_config, &options);
+ /* options.gpg_sign_opt will be either "-S" or NULL */
+ gpg_sign = options.gpg_sign_opt ? "" : NULL;
+ FREE_AND_NULL(options.gpg_sign_opt);
if (options.use_legacy_rebase ||
!git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1))
@@ -1822,10 +1833,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (options.empty != EMPTY_UNSPECIFIED)
imply_merge(&options, "--empty");
- if (gpg_sign) {
- free(options.gpg_sign_opt);
+ if (options.reapply_cherry_picks)
+ imply_merge(&options, "--reapply-cherry-picks");
+
+ if (gpg_sign)
options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign);
- }
if (exec.nr) {
int i;