From patchwork Fri Dec 20 17:09:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306001 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BE6331580 for ; Fri, 20 Dec 2019 17:09:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7EF9321D7E for ; Fri, 20 Dec 2019 17:09:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="e+pvUmcx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727444AbfLTRJz (ORCPT ); Fri, 20 Dec 2019 12:09:55 -0500 Received: from mail-ed1-f67.google.com ([209.85.208.67]:39227 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727419AbfLTRJy (ORCPT ); Fri, 20 Dec 2019 12:09:54 -0500 Received: by mail-ed1-f67.google.com with SMTP id t17so8937040eds.6 for ; Fri, 20 Dec 2019 09:09:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=stg3fR8nVO6/Gk9gpqshT6F4bxTbNS5vCVDHFepAOfA=; b=e+pvUmcxo/jHHkP19nhA67Ylf2ZI089qukLPtmEtGyciypwqgwcfL0/RxbpVoAAC3H wgdUNoZd9H0o8+YTsxD5eGxfP1Aiqi3cEjRJBnoH05be3ve8ezaNrxKsr0HT81qOe1st NI7QR4fjadWklPyAo1JkXgx3d1MBBSYcYKVa7QhWfKSuDU7paEZOPDShd6nQnYdy5yxT BbJEon+1JbsKW8uyxqK5KKOC/OvqJhu3rbwtnrMoltF8jTa46FXdM1XCeGGvVUseA4nH oDD0UJVCyE8cjfKDKSZKQJH46J5fne+8ZmPyJO3eocGhwmPikkvypNF5gcRRO6BLStDz vqpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=stg3fR8nVO6/Gk9gpqshT6F4bxTbNS5vCVDHFepAOfA=; b=CZSSP14hJOWUkaxv2Z0oHOtv8hvoNHpyYv4rPf0zgUtjp5LTmr2Irs+5yZ0SkOUISB CI1MPzMw3kxxAeYgoBXcJ20p87/onn4P1BsEK3wkMWCByCF6Dg+4gwHtqK88bF0lqc6a L4kH3e25Sgf3q5V/jeLhlnjLIReBzvNztuKHxDMdfZn1cxBOj5XqtUVzSy44PfA64RTT +qlUCI00EFI7eynJh+FBu9xPcW2dr6Y+2qPjvSTv19yToMV74v1ubnMckMvTvMSQ5mel 5/zA+KjsnA3hM0Z7kMRBkK4YhbR851r8+hWLorWh4hwofgaXCMQo1bekvMLlRXPaLvBl ydAA== X-Gm-Message-State: APjAAAXBI561arXWZryOkjXzAk2x76CyITUxTbksBYO03H1T0dktinqs wFebsGuqfQ5cz7D2oFzkpkA9N+ck X-Google-Smtp-Source: APXvYqxSueXDK8gNNtNp8WXQ5+7AG1nZ2/I6MmZp9Jm4DxNYpx+KS1YpC6sGVSbJOTydtmwpWcyKbA== X-Received: by 2002:a50:e108:: with SMTP id h8mr17266672edl.196.1576861790568; Fri, 20 Dec 2019 09:09:50 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p8sm1158222ejm.1.2019.12.20.09.09.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:50 -0800 (PST) Message-Id: <13e2056e780b00baf86d4020c0974b6b05ce115b.1576861788.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:34 +0000 Subject: [PATCH 01/15] rebase: extend the options for handling of empty commits Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Extend the interactive machinery with the ability to handle the full spread of options for how to handle commits that either start or become empty (by "become empty" I mean the changes in a commit are a subset of changes that exist upstream, so the net effect of applying the commit is no changes). Introduce a new command line flag for selecting the desired behavior: --empty={drop,keep,ask} with the definitions: drop: drop empty commits keep: keep empty commits ask: provide the user a chance to interact and pick what to do with empty commits on a case-by-case basis Note that traditionally, am-based rebases have always dropped commits that either started or became empty, while interactive-based rebases have defaulted to ask (and provided an option to keep commits that started empty). This difference made sense since users of an am-based rebase just wanted to quickly batch apply a sequence of commits, while users editing a todo list will likely want the chance to interact and handle unusual cases on a case-by-case basis. However, not all rebases using the interactive machinery are explicitly interactive anymore. In particular --merge was always meant to behave more like --am: just rebase a batch of commits without popping up a todo list. If the --empty flag is not specified, pick defaults as follows: explicitly interactive: ask --exec: keep (exec is about checking existing commits, and often used without actually changing the base. Thus the expectation is that the user doesn't necessarily want anything to change; they just want to test). otherwise: drop Also, this commit makes --keep-empty just imply --empty=keep, and hides it from help so that we aren't confusing users with different ways to do the same thing. (I could have added a --drop-empty flag, but then that invites users to specify both --keep-empty and --drop-empty and we have to add sanity checking around that; it seems cleaner to have a single multi-valued option.) This actually fixes --keep-empty too; previously, it only meant to sometimes keep empty commits, in particular commits which started empty would be kept. But it would still error out and ask the user what to do with commits that became empty. Now it keeps empty commits, as instructed. Signed-off-by: Elijah Newren --- Documentation/git-rebase.txt | 35 ++++++------ builtin/rebase.c | 87 +++++++++++++++++++++++++++--- rebase-interactive.c | 4 +- rebase-interactive.h | 2 +- sequencer.c | 74 +++++++++++++++++++------ sequencer.h | 6 ++- t/t3421-rebase-topology-linear.sh | 4 +- t/t3424-rebase-empty.sh | 89 +++++++++++++++++++++++++++++++ t/t3427-rebase-subtree.sh | 16 +++--- 9 files changed, 267 insertions(+), 50 deletions(-) create mode 100755 t/t3424-rebase-empty.sh diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 1d0e2d27cc..ff32ca1080 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -258,9 +258,25 @@ See also INCOMPATIBLE OPTIONS below. original branch. The index and working tree are also left unchanged as a result. +--empty={drop,keep,ask}:: + How to handle commits that become empty (because they contain a + subset of already upstream changes) or start empty. With drop + (the default), commits that start or become empty are dropped. + With keep (implied by --exec), such commits are kept. With ask + (implied by --interactive), the rebase will halt when an empty + commit is applied allowing you to choose whether to drop it or + commit it. Also with ask, if the rebase is interactive then + commits which start empty will be commented out in the todo + action list (giving you a chance to uncomment). ++ +Note that this has no effect on commits which are already upstream (as +can be checked via `git log --cherry-mark ...`), which are always +dropped by rebase. ++ +See also INCOMPATIBLE OPTIONS below. + --keep-empty:: - Keep the commits that do not change anything from its - parents in the result. + Deprecated alias for what is now known as --empty=keep. + See also INCOMPATIBLE OPTIONS below. @@ -569,6 +585,7 @@ are incompatible with the following options: * --interactive * --exec * --keep-empty + * --empty= * --edit-todo * --root when used in combination with --onto @@ -580,6 +597,7 @@ In addition, the following pairs of options are incompatible: * --preserve-merges and --ignore-whitespace * --preserve-merges and --committer-date-is-author-date * --preserve-merges and --ignore-date + * --preserve-merges and --empty= * --keep-base and --onto * --keep-base and --root @@ -588,19 +606,6 @@ BEHAVIORAL DIFFERENCES There are some subtle differences how the backends behave. -Empty commits -~~~~~~~~~~~~~ - -The am backend drops any "empty" commits, regardless of whether the -commit started empty (had no changes relative to its parent to -start with) or ended empty (all changes were already applied -upstream in other commits). - -The interactive backend drops commits by default that -started empty and halts if it hits a commit that ended up empty. -The `--keep-empty` option exists for the interactive backend to allow -it to keep commits that started empty. - Directory rename detection ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/builtin/rebase.c b/builtin/rebase.c index ddf33bc9d4..96db10eaed 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -50,8 +50,16 @@ enum rebase_type { REBASE_PRESERVE_MERGES }; +enum empty_type { + EMPTY_UNSPECIFIED = -1, + EMPTY_DROP, + EMPTY_KEEP, + EMPTY_ASK +}; + struct rebase_options { enum rebase_type type; + enum empty_type empty; const char *state_dir; struct commit *upstream; const char *upstream_name; @@ -77,7 +85,6 @@ struct rebase_options { const char *action; int signoff; int allow_rerere_autoupdate; - int keep_empty; int autosquash; int ignore_whitespace; char *gpg_sign_opt; @@ -95,6 +102,7 @@ struct rebase_options { #define REBASE_OPTIONS_INIT { \ .type = REBASE_UNSPECIFIED, \ + .empty = EMPTY_UNSPECIFIED, \ .flags = REBASE_NO_QUIET, \ .git_am_opts = ARGV_ARRAY_INIT, \ .git_format_patch_opt = STRBUF_INIT \ @@ -114,6 +122,10 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts) replay.allow_rerere_auto = opts->allow_rerere_autoupdate; replay.allow_empty = 1; replay.allow_empty_message = opts->allow_empty_message; + replay.drop_redundant_commits = (opts->empty == EMPTY_DROP); + replay.keep_redundant_commits = (opts->empty == EMPTY_KEEP); + replay.ask_on_initially_empty = (opts->empty == EMPTY_ASK && + !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)); replay.verbose = opts->flags & REBASE_VERBOSE; replay.reschedule_failed_exec = opts->reschedule_failed_exec; replay.committer_date_is_author_date = @@ -389,7 +401,10 @@ static int run_rebase_interactive(struct rebase_options *opts, git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands); - flags |= opts->keep_empty ? TODO_LIST_KEEP_EMPTY : 0; + flags |= (opts->empty == EMPTY_DROP) ? TODO_LIST_DROP_EMPTY : 0; + flags |= (opts->empty == EMPTY_ASK && + opts->flags & REBASE_INTERACTIVE_EXPLICIT) ? + TODO_LIST_ASK_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; @@ -453,6 +468,19 @@ static int run_rebase_interactive(struct rebase_options *opts, return ret; } +static int parse_opt_keep_empty(const struct option *opt, const char *arg, + int unset) +{ + struct rebase_options *opts = opt->value; + + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); + + opts->empty = EMPTY_KEEP; + opts->type = REBASE_INTERACTIVE; + return 0; +} + static const char * const builtin_rebase_interactive_usage[] = { N_("git rebase--interactive []"), NULL @@ -466,7 +494,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_NEGBIT(0, "ff", &opts.flags, N_("allow fast-forward"), REBASE_FORCE), - OPT_BOOL(0, "keep-empty", &opts.keep_empty, N_("keep empty commits")), + { OPTION_CALLBACK, 'k', "keep-empty", &options, NULL, + N_("(DEPRECATED) keep empty commits"), + PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, + parse_opt_keep_empty }, OPT_BOOL(0, "allow-empty-message", &opts.allow_empty_message, N_("allow commits with empty messages")), OPT_BOOL(0, "rebase-merges", &opts.rebase_merges, N_("rebase merge commits")), @@ -1166,7 +1197,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, "empty", opts->empty == EMPTY_KEEP ? "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); @@ -1360,6 +1391,33 @@ static int parse_opt_interactive(const struct option *opt, const char *arg, return 0; } +static long parse_empty_value(const char *value) +{ + if (!value) + return EMPTY_UNSPECIFIED; + else if (!strcasecmp(value, "drop")) + return EMPTY_DROP; + else if (!strcasecmp(value, "keep")) + return EMPTY_KEEP; + else if (!strcasecmp(value, "ask")) + return EMPTY_ASK; + return EMPTY_UNSPECIFIED; +} + +static int parse_opt_empty(const struct option *opt, const char *arg, int unset) +{ + struct rebase_options *options = opt->value; + long value = parse_empty_value(arg); + + BUG_ON_OPT_NEG(unset); + if (value < 0) + return error(_("option empty accepts \"drop\", " + "\"keep\", and \"ask\"")); + + options->empty = value; + return 0; +} + static void NORETURN error_on_missing_default_upstream(void) { struct branch *current_branch = branch_get(NULL); @@ -1505,8 +1563,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) "ignoring them"), REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN), OPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate), - OPT_BOOL('k', "keep-empty", &options.keep_empty, - N_("preserve empty commits during rebase")), + OPT_CALLBACK_F(0, "empty", &options, N_("{drop,keep,ask}"), + N_("how to handle empty commits"), + PARSE_OPT_NONEG, parse_opt_empty), + { OPTION_CALLBACK, 'k', "keep-empty", &options, NULL, + N_("(DEPRECATED) keep empty commits"), + PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, + parse_opt_keep_empty }, OPT_BOOL(0, "autosquash", &options.autosquash, N_("move commits that begin with " "squash!/fixup! under -i")), @@ -1770,8 +1833,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (!(options.flags & REBASE_NO_QUIET)) argv_array_push(&options.git_am_opts, "-q"); - if (options.keep_empty) - imply_interactive(&options, "--keep-empty"); + if (options.empty != EMPTY_UNSPECIFIED) + imply_interactive(&options, "--empty"); if (gpg_sign) { free(options.gpg_sign_opt); @@ -1856,6 +1919,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) break; } + if (options.empty == EMPTY_UNSPECIFIED) { + if (options.flags & REBASE_INTERACTIVE_EXPLICIT) + options.empty = EMPTY_ASK; + else if (exec.nr > 0) + options.empty = EMPTY_KEEP; + else + options.empty = EMPTY_DROP; + } if (reschedule_failed_exec > 0 && !is_interactive(&options)) die(_("--reschedule-failed-exec requires " "--exec or --interactive")); diff --git a/rebase-interactive.c b/rebase-interactive.c index aa18ae82b7..ad82bf77df 100644 --- a/rebase-interactive.c +++ b/rebase-interactive.c @@ -28,7 +28,7 @@ static enum missing_commit_check_level get_missing_commit_check_level(void) return MISSING_COMMIT_CHECK_IGNORE; } -void append_todo_help(unsigned keep_empty, int command_count, +void append_todo_help(unsigned no_ask_empty, int command_count, const char *shortrevisions, const char *shortonto, struct strbuf *buf) { @@ -81,7 +81,7 @@ void append_todo_help(unsigned keep_empty, int command_count, strbuf_add_commented_lines(buf, msg, strlen(msg)); - if (!keep_empty) { + if (!no_ask_empty) { msg = _("Note that empty commits are commented out"); strbuf_add_commented_lines(buf, msg, strlen(msg)); } diff --git a/rebase-interactive.h b/rebase-interactive.h index 44dbb06311..f531e00ba7 100644 --- a/rebase-interactive.h +++ b/rebase-interactive.h @@ -5,7 +5,7 @@ struct strbuf; struct repository; struct todo_list; -void append_todo_help(unsigned keep_empty, int command_count, +void append_todo_help(unsigned no_ask_empty, int command_count, const char *shortrevisions, const char *shortonto, struct strbuf *buf); int edit_todo_list(struct repository *r, struct todo_list *todo_list, diff --git a/sequencer.c b/sequencer.c index 763ccbbc45..d2c11f34b7 100644 --- a/sequencer.c +++ b/sequencer.c @@ -160,6 +160,9 @@ 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_drop_redundant_commits, "rebase-merge/drop_redundant_commits") +static GIT_PATH_FUNC(rebase_path_keep_redundant_commits, "rebase-merge/keep_redundant_commits") +static GIT_PATH_FUNC(rebase_path_ask_on_initially_empty, "rebase-merge/ask_on_initially_empty") static int git_sequencer_config(const char *k, const char *v, void *cb) { @@ -1623,7 +1626,7 @@ static int allow_empty(struct repository *r, empty_commit = is_original_commit_empty(commit); if (empty_commit < 0) return empty_commit; - if (!empty_commit) + if (!empty_commit || opts->ask_on_initially_empty) return 0; else return 1; @@ -1837,7 +1840,7 @@ static int do_pick_commit(struct repository *r, char *author = NULL; struct commit_message msg = { NULL, NULL, NULL, NULL }; struct strbuf msgbuf = STRBUF_INIT; - int res, unborn = 0, reword = 0, allow; + int res, unborn = 0, reword = 0, allow, drop_commit; if (opts->no_commit) { /* @@ -2042,13 +2045,20 @@ static int do_pick_commit(struct repository *r, goto leave; } - allow = allow_empty(r, opts, commit); - if (allow < 0) { - res = allow; - goto leave; - } else if (allow) - flags |= ALLOW_EMPTY; - if (!opts->no_commit) { + drop_commit = 0; + if (opts->drop_redundant_commits && is_index_unchanged(r)) { + drop_commit = 1; + fprintf(stderr, _("No changes -- Patch already applied.")); + } else { + allow = allow_empty(r, opts, commit); + if (allow < 0) { + res = allow; + goto leave; + } else if (allow) { + flags |= ALLOW_EMPTY; + } + } + if (!opts->no_commit && !drop_commit) { if (author || command == TODO_REVERT || (flags & AMEND_MSG)) res = do_commit(r, msg_file, author, opts, flags); else @@ -2501,9 +2511,15 @@ static int populate_opts_cb(const char *key, const char *value, void *data) else if (!strcmp(key, "options.allow-empty-message")) opts->allow_empty_message = git_config_bool_or_int(key, value, &error_flag); + else if (!strcmp(key, "options.drop-redundant-commits")) + opts->drop_redundant_commits = + git_config_bool_or_int(key, value, &error_flag); else if (!strcmp(key, "options.keep-redundant-commits")) opts->keep_redundant_commits = git_config_bool_or_int(key, value, &error_flag); + else if (!strcmp(key, "options.ask_on_initially_empty")) + opts->ask_on_initially_empty = + git_config_bool_or_int(key, value, &error_flag); else if (!strcmp(key, "options.signoff")) opts->signoff = git_config_bool_or_int(key, value, &error_flag); else if (!strcmp(key, "options.record-origin")) @@ -2612,6 +2628,15 @@ static int read_populate_opts(struct replay_opts *opts) if (file_exists(rebase_path_reschedule_failed_exec())) opts->reschedule_failed_exec = 1; + if (file_exists(rebase_path_drop_redundant_commits())) + opts->drop_redundant_commits = 1; + + if (file_exists(rebase_path_keep_redundant_commits())) + opts->keep_redundant_commits = 1; + + if (file_exists(rebase_path_ask_on_initially_empty())) + opts->ask_on_initially_empty = 1; + read_strategy_opts(opts, &buf); strbuf_release(&buf); @@ -2695,6 +2720,12 @@ int write_basic_state(struct replay_opts *opts, const char *head_name, write_file(rebase_path_cdate_is_adate(), "%s", ""); if (opts->ignore_date) write_file(rebase_path_ignore_date(), "%s", ""); + if (opts->drop_redundant_commits) + write_file(rebase_path_drop_redundant_commits(), "%s", ""); + if (opts->keep_redundant_commits) + write_file(rebase_path_keep_redundant_commits(), "%s", ""); + if (opts->ask_on_initially_empty) + write_file(rebase_path_ask_on_initially_empty(), "%s", ""); if (opts->reschedule_failed_exec) write_file(rebase_path_reschedule_failed_exec(), "%s", ""); @@ -3033,9 +3064,15 @@ static int save_opts(struct replay_opts *opts) if (opts->allow_empty_message) res |= git_config_set_in_file_gently(opts_file, "options.allow-empty-message", "true"); + if (opts->drop_redundant_commits) + res |= git_config_set_in_file_gently(opts_file, + "options.drop-redundant-commits", "true"); if (opts->keep_redundant_commits) res |= git_config_set_in_file_gently(opts_file, "options.keep-redundant-commits", "true"); + if (opts->ask_on_initially_empty) + res |= git_config_set_in_file_gently(opts_file, + "options.ask_on_initially_empty", "true"); if (opts->signoff) res |= git_config_set_in_file_gently(opts_file, "options.signoff", "true"); @@ -4691,7 +4728,8 @@ static int make_script_with_merges(struct pretty_print_context *pp, struct rev_info *revs, struct strbuf *out, unsigned flags) { - int keep_empty = flags & TODO_LIST_KEEP_EMPTY; + int drop_empty = flags & TODO_LIST_DROP_EMPTY; + int ask_empty = flags & TODO_LIST_ASK_EMPTY; int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS; int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO; struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT; @@ -4746,6 +4784,8 @@ static int make_script_with_merges(struct pretty_print_context *pp, is_empty = is_original_commit_empty(commit); if (!is_empty && (commit->object.flags & PATCHSAME)) continue; + if (is_empty && drop_empty) + continue; strbuf_reset(&oneline); pretty_print_commit(pp, commit, &oneline); @@ -4754,7 +4794,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, if (!to_merge) { /* non-merge commit: easy case */ strbuf_reset(&buf); - if (!keep_empty && is_empty) + if (is_empty && ask_empty) strbuf_addf(&buf, "%c ", comment_line_char); strbuf_addf(&buf, "%s %s %s", cmd_pick, oid_to_hex(&commit->object.oid), @@ -4922,7 +4962,8 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, struct pretty_print_context pp = {0}; struct rev_info revs; struct commit *commit; - int keep_empty = flags & TODO_LIST_KEEP_EMPTY; + int drop_empty = flags & TODO_LIST_DROP_EMPTY; + int ask_empty = flags & TODO_LIST_ASK_EMPTY; const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick"; int rebase_merges = flags & TODO_LIST_REBASE_MERGES; @@ -4958,11 +4999,13 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, return make_script_with_merges(&pp, &revs, out, flags); while ((commit = get_revision(&revs))) { - int is_empty = is_original_commit_empty(commit); + int is_empty = is_original_commit_empty(commit); if (!is_empty && (commit->object.flags & PATCHSAME)) continue; - if (!keep_empty && is_empty) + if (is_empty && drop_empty) + continue; + if (is_empty && ask_empty) strbuf_addf(out, "%c ", comment_line_char); strbuf_addf(out, "%s %s ", insn, oid_to_hex(&commit->object.oid)); @@ -5100,7 +5143,8 @@ int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list, todo_list_to_strbuf(r, todo_list, &buf, num, flags); if (flags & TODO_LIST_APPEND_TODO_HELP) - append_todo_help(flags & TODO_LIST_KEEP_EMPTY, count_commands(todo_list), + append_todo_help(!(flags & TODO_LIST_ASK_EMPTY), + count_commands(todo_list), shortrevisions, shortonto, &buf); res = write_message(buf.buf, buf.len, file, 0); diff --git a/sequencer.h b/sequencer.h index e9a0e03ea2..1c3abb661c 100644 --- a/sequencer.h +++ b/sequencer.h @@ -39,7 +39,9 @@ struct replay_opts { int allow_rerere_auto; int allow_empty; int allow_empty_message; + int drop_redundant_commits; int keep_redundant_commits; + int ask_on_initially_empty; int verbose; int quiet; int reschedule_failed_exec; @@ -134,7 +136,7 @@ int sequencer_rollback(struct repository *repo, struct replay_opts *opts); int sequencer_skip(struct repository *repo, struct replay_opts *opts); int sequencer_remove_state(struct replay_opts *opts); -#define TODO_LIST_KEEP_EMPTY (1U << 0) +/* #define TODO_LIST_KEEP_EMPTY (1U << 0) */ /* No longer used */ #define TODO_LIST_SHORTEN_IDS (1U << 1) #define TODO_LIST_ABBREVIATE_CMDS (1U << 2) #define TODO_LIST_REBASE_MERGES (1U << 3) @@ -150,6 +152,8 @@ int sequencer_remove_state(struct replay_opts *opts); * `--onto`, we do not want to re-generate the root commits. */ #define TODO_LIST_ROOT_WITH_ONTO (1U << 6) +#define TODO_LIST_DROP_EMPTY (1U << 7) +#define TODO_LIST_ASK_EMPTY (1U << 8) int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 325072b0a3..d23e0bf778 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -230,7 +230,7 @@ test_run_rebase () { test_run_rebase success '' test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p +test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -245,7 +245,7 @@ test_run_rebase () { test_run_rebase success '' test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p +test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase success --rebase-merges # m diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh new file mode 100755 index 0000000000..9d52e1417f --- /dev/null +++ b/t/t3424-rebase-empty.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +test_description='git rebase of commits that start or become empty' + +. ./test-lib.sh + +test_expect_success 'setup test repository' ' + test_write_lines 1 2 3 4 5 6 7 8 9 10 >numbers && + test_write_lines A B C D E F G H I J >letters && + git add numbers letters && + git commit -m A && + + git branch upstream && + git branch localmods && + + git checkout upstream && + test_write_lines A B C D E >letters && + git add letters && + git commit -m B && + + test_write_lines 1 2 3 4 five 6 7 8 9 ten >numbers && + git add numbers && + git commit -m C && + + git checkout localmods && + test_write_lines 1 2 3 4 five 6 7 8 9 10 >numbers && + git add numbers && + git commit -m C2 && + + git commit --allow-empty -m D && + + test_write_lines A B C D E >letters && + git add letters && + git commit -m "Five letters ought to be enough for anybody" +' + +test_expect_success 'rebase --merge --empty=drop' ' + git checkout -B testing localmods && + git rebase --merge --empty=drop upstream && + + test_write_lines C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge --empty=keep' ' + git checkout -B testing localmods && + git rebase --merge --empty=keep upstream && + + test_write_lines D C2 C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge --empty=ask' ' + git checkout -B testing localmods && + test_must_fail git rebase --merge --empty=ask upstream && + + test_must_fail git rebase --skip && + git commit --allow-empty && + git rebase --continue && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR + +test_expect_success 'rebase --interactive --empty=drop' ' + git checkout -B testing localmods && + git rebase --interactive --empty=drop upstream && + + test_write_lines C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --interactive --empty=keep' ' + git checkout -B testing localmods && + git rebase --interactive --empty=keep upstream && + + test_write_lines D C2 C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + + +test_done diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh index bec48e6a1f..468ebc1bef 100755 --- a/t/t3427-rebase-subtree.sh +++ b/t/t3427-rebase-subtree.sh @@ -85,23 +85,27 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges -- verbose test "$(commit_message HEAD)" = "Empty commit" ' -test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' ' +test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' ' reset_rebase && git checkout -b rebase-onto to-rebase && - test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master && + test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --onto files-master master && : first pick results in no changes && - git rebase --continue && + test_must_fail git rebase --skip && + : last pick was an empty commit that has no changes, but we want to keep it && + git commit --allow-empty && verbose test "$(commit_message HEAD~2)" = "master4" && verbose test "$(commit_message HEAD~)" = "files_subtree/master5" && verbose test "$(commit_message HEAD)" = "Empty commit" ' -test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' ' +test_expect_success 'Rebase -Xsubtree --empty=ask --rebase-merges --onto commit' ' reset_rebase && git checkout -b rebase-merges-onto to-rebase && - test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root && + test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --rebase-merges --onto files-master --root && : first pick results in no changes && - git rebase --continue && + test_must_fail git rebase --skip && + : last pick was an empty commit that has no changes, but we want to keep it && + git commit --allow-empty && verbose test "$(commit_message HEAD~2)" = "master4" && verbose test "$(commit_message HEAD~)" = "files_subtree/master5" && verbose test "$(commit_message HEAD)" = "Empty commit" From patchwork Fri Dec 20 17:09:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11305997 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 02D63139A for ; Fri, 20 Dec 2019 17:09:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D4FC92467F for ; Fri, 20 Dec 2019 17:09:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TKEREr/i" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727437AbfLTRJx (ORCPT ); Fri, 20 Dec 2019 12:09:53 -0500 Received: from mail-ed1-f66.google.com ([209.85.208.66]:36879 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727421AbfLTRJx (ORCPT ); Fri, 20 Dec 2019 12:09:53 -0500 Received: by mail-ed1-f66.google.com with SMTP id cy15so8948721edb.4 for ; Fri, 20 Dec 2019 09:09:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=3muzs1s8jPipA1T8GQk7Xh/VUjMuS5qZYkTINqYuvjk=; b=TKEREr/i6PY0Bb2s6ZsMzIUq7GDxNevRsFKK1zeNSdXGOEeisFiFTHoiQJd1DR4VyB brCauJaGRCjhA2ZrEDlRhoC9wUMJdmgA3d/p+4ztwbQzo4ydolapNhfSrvm6/rsAjDJv aJ30XmCYR178NeMWWa+vtZf0HuVIiYdKuIFWPYo/7AKVpjbRWep9WfOGH3FDEcsbpmxy ovRqTQ/4gkHyfysr8dqX1FwIxCYE5izbQz/pH/HpSvsdj+z0MR4pjHfC3dWto7Q2x3L1 vwcGpEPPVp13e+B4D2lyoYt3CEwCYkNsBsRZZD+HO/zFmCFM+HKwDB2r35cvR0oW4x2d KmDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=3muzs1s8jPipA1T8GQk7Xh/VUjMuS5qZYkTINqYuvjk=; b=f4/gxnI/MY/pOeUbU+HDHgbV0pchNdBl4PBTddFRl3DJtlg8A5Phg3xOMEBwLvwlks 8yuBNssJuyBD+SJjjzeujIyHq1tgeNtBgX/5lcvirHawgo7PwaBjFjGPCGl9rWopB2cA PJQOHpJFhTCrqOVcTkbhEsOwXNJ04fQjDdG1fmgRo46oK4D25VVYUInbi5J9n5kiJBGe +1l6WLBMtqPphlrsC8TaE2Rs7hOUdRknJKoCzQWYj6fZIuHIqIlO5XMtDj1mxKw1fPnH CwerHp/w0GvB/3dju3MXrVTvORIzyCz8JEVFjG3yn5mOoE3wGLobN2JpYPCyv12yH6yv vLvA== X-Gm-Message-State: APjAAAUf7bwYiKIGVqVMI9tK/COSDe8UBNh/CyOLJo9a68iyso0wG0jp QPOrKR3ljmLVmqp2VuiV/wioGjCZ X-Google-Smtp-Source: APXvYqytqjjP+eaXv5DH94Yb3AzbFAfhKws6XQsEgOngdBa1UHeD0WYCJoVBzMtMWzC0ouMtYO/jQw== X-Received: by 2002:a05:6402:64a:: with SMTP id u10mr17444994edx.147.1576861791249; Fri, 20 Dec 2019 09:09:51 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k6sm990777edi.68.2019.12.20.09.09.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:50 -0800 (PST) Message-Id: <47ea99fb30190b96b05f90735335424f7a37a95e.1576861788.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:35 +0000 Subject: [PATCH 02/15] t3406: simplify an already simple test Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren When the merge backend was re-implemented on top of the interactive backend, the output of rebase --merge changed a little. This change allowed this test to be simplified, though it wasn't noticed until now. Simplify the testcase a little. Signed-off-by: Elijah Newren --- t/t3406-rebase-message.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index b393e1e9fe..0c2c569f95 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -18,11 +18,8 @@ test_expect_success 'setup' ' ' test_expect_success 'rebase -m' ' - git rebase -m master >report && - >expect && - sed -n -e "/^Already applied: /p" \ - -e "/^Committed: /p" report >actual && - test_cmp expect actual + git rebase -m master >actual && + test_must_be_empty actual ' test_expect_success 'rebase against master twice' ' From patchwork Fri Dec 20 17:09:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11305999 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DFC78139A for ; Fri, 20 Dec 2019 17:09:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BD4EB21D7D for ; Fri, 20 Dec 2019 17:09:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qlq82HI8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727441AbfLTRJy (ORCPT ); Fri, 20 Dec 2019 12:09:54 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:40009 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727362AbfLTRJx (ORCPT ); Fri, 20 Dec 2019 12:09:53 -0500 Received: by mail-ed1-f68.google.com with SMTP id b8so8931988edx.7 for ; Fri, 20 Dec 2019 09:09:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=sbz/M1G+Dovu//rMHWIDkWAtQWzxcUarJfEHZJZENho=; b=qlq82HI8CrQCiyW9d/YntpGvANg2/ta82+iyPNJkeJcSzl/86MSZq08P1IkkHfhLCZ XmRrp/H8sMN440U2bHhnjCHqL2cbbzTe6OEOjMn/jzsNBEZwhOxkSqzMGIJu0S69NbQE uA5KZD8AatAHF5cHtn+2PoeCV57yiUMMMXPWEePpVXra4nZ2BZBen3HUK5j8F0mGS8Rn nbJ96BQQjGmVHz6SgUdIzjbacFqaKrowG2+y8Xyf12gV7HITuU1hPZavML5R1FzYJRv6 f2ScuMBWsWiRZ7fe+gNGQO/yz6MezXc8UBcGj55BiAh/762w32OhUOqcbLc8sJrMfMHo E4fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=sbz/M1G+Dovu//rMHWIDkWAtQWzxcUarJfEHZJZENho=; b=jZf6z8oAbBbpb0zBlZTz4CXkwht+tWGB60HL+v05/QoGHDtHZFFpbqfPMETZPl/w8s Aw2ouZ2Q4MaTZhuZGJ2S6OXLn0xq4HmJeSUW1A9rT8Ppwhmx99MsEPNqfiX+WM62F6aQ SxhlZAL53cNr6Bt0WcCKXgFzM6r6B7PWoszuoymOOs/wMllgYz7NNqhdEijyMP5UcnSD ecVeRY/n4sU0X2uFLAt1eIS2mbj/xx1ROr2PIdQOB1hp84akxPNmACh8WvIlX6xx0XQp KRm0a+svFcYOEtlkvU2iUjP4GFonbrI2eSauFemHvWLjd2dexbOLzod9fAUAppF8WGaZ zAig== X-Gm-Message-State: APjAAAUfdFsC4nZcKsCKuIWV/afy9f0OTEmdiaTOOV/Kk9k8++oy94Ou N52RELGvnb0qoBGBQK9BwZI58IkB X-Google-Smtp-Source: APXvYqwTefvzla67MvY5Jvoee/47TonBUBEJ9xnMSqohRXRSmdVqmQv94sx+zlk19jI24+jmLGiQfw== X-Received: by 2002:a17:906:86d7:: with SMTP id j23mr17238478ejy.89.1576861791996; Fri, 20 Dec 2019 09:09:51 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id f3sm1017682edw.80.2019.12.20.09.09.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:51 -0800 (PST) Message-Id: In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:36 +0000 Subject: [PATCH 03/15] rebase, sequencer: remove the broken GIT_QUIET handling Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren The GIT_QUIET environment variable was used to signal the non-am backends that the rebase should perform quietly. The preserve-merges backend does not make use of the quiet flag anywhere (other than to write out its state whenever it writes state), and this mechanism was broken in the conversion from shell to C. Since this environment variable was specifically designed for scripts and the only backend that would still use it is no longer a script, just gut this code. A subsequent commit will fix --quiet for the interactive/merge backend in a different way. Signed-off-by: Elijah Newren --- builtin/rebase.c | 6 ++---- sequencer.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index 96db10eaed..c71d169688 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -718,8 +718,8 @@ static int rebase_write_basic_state(struct rebase_options *opts) opts->onto ? oid_to_hex(&opts->onto->object.oid) : ""); write_file(state_dir_path("orig-head", opts), "%s", oid_to_hex(&opts->orig_head)); - write_file(state_dir_path("quiet", opts), "%s", - opts->flags & REBASE_NO_QUIET ? "" : "t"); + if (!(opts->flags & REBASE_NO_QUIET)) + write_file(state_dir_path("quiet", opts), "%s", ""); if (opts->flags & REBASE_VERBOSE) write_file(state_dir_path("verbose", opts), "%s", ""); if (opts->strategy) @@ -1178,8 +1178,6 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action) add_var(&script_snippet, "revisions", opts->revisions); add_var(&script_snippet, "restrict_revision", opts->restrict_revision ? oid_to_hex(&opts->restrict_revision->object.oid) : NULL); - add_var(&script_snippet, "GIT_QUIET", - opts->flags & REBASE_NO_QUIET ? "" : "t"); sq_quote_argv_pretty(&buf, opts->git_am_opts.argv); add_var(&script_snippet, "git_am_opt", buf.buf); strbuf_release(&buf); diff --git a/sequencer.c b/sequencer.c index d2c11f34b7..71062212a5 100644 --- a/sequencer.c +++ b/sequencer.c @@ -2688,8 +2688,6 @@ static void write_strategy_opts(struct replay_opts *opts) int write_basic_state(struct replay_opts *opts, const char *head_name, struct commit *onto, const char *orig_head) { - const char *quiet = getenv("GIT_QUIET"); - if (head_name) write_file(rebase_path_head_name(), "%s\n", head_name); if (onto) @@ -2698,8 +2696,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name, if (orig_head) write_file(rebase_path_orig_head(), "%s\n", orig_head); - if (quiet) - write_file(rebase_path_quiet(), "%s\n", quiet); + if (opts->quiet) + write_file(rebase_path_quiet(), "%s", ""); if (opts->verbose) write_file(rebase_path_verbose(), "%s", ""); if (opts->strategy) From patchwork Fri Dec 20 17:09:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306005 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 87C0F139A for ; Fri, 20 Dec 2019 17:09:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6641821D7E for ; Fri, 20 Dec 2019 17:09:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hqtoum5V" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727460AbfLTRJ5 (ORCPT ); Fri, 20 Dec 2019 12:09:57 -0500 Received: from mail-ed1-f65.google.com ([209.85.208.65]:36884 "EHLO mail-ed1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727421AbfLTRJz (ORCPT ); Fri, 20 Dec 2019 12:09:55 -0500 Received: by mail-ed1-f65.google.com with SMTP id cy15so8948852edb.4 for ; Fri, 20 Dec 2019 09:09:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=LYw++dU8UaeUfbRm94CZWxP7yRgnSdg8gaKNkRp7iC4=; b=hqtoum5VRsZbsILlUL2JyXlCFWwacqipxZuHhsb/3KX0b7QU9f6Y/kcW7oI14yr5xM cvMcx3Q7IRMPRvsE9tImCDG6H+iibV5KnP9OZ6XbIJ8/yMCSEcb2dvxBGYeZpk9hKMw5 BSJzN3GLhw8Dtx2ga9p7p1b7ZbeJJY6LwFuDXyUN95uAzKPeAFbMtblk6aN3j6AbWtdf IsvyzrXmFMio3+D9q0uWqsGEsvEi5xvR8dxoK+DsduSwrfbSsSBgJyjNZ5GkfTyTG9w/ 0LjSv8MmNT7Su1O4wy/i8hAVV4BVmcOseENPW0yXM7tMfwhkeDuhcrHUUN4j6JAOmDMK Sm4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=LYw++dU8UaeUfbRm94CZWxP7yRgnSdg8gaKNkRp7iC4=; b=EKyIiYPodqnxfe+F91VWEsJxslDeHUQimYIcczRR4T7VFTwd3uCa59BYH14athcuwp p6Q2ffz+Lh9fETGVPhPmLsRJldzTDh3oOHQOWEYFekknxVOpHgCWPvdvgDh6e+Ybl+fb pakNXNQKhn8YwewnCPuJNVRVEbQ9YR+76CKVTDtfGan2DrKCQ1kQvRmW4tMTOfgpvSr1 xieWpZeSjADCYZkoZpwOvqBHJAPEDab81vQCSYWGseBXL+c2mgcX9TICGNf2PD6w+wDo 6Zl/qp5a4ay7xI9xFOEvqcoZbLlZdn2/ey6I8tZBgtgkyG65ljYNS13Hpu/lSrnJP9bu wV7g== X-Gm-Message-State: APjAAAXs/Y1PspIOrYqQGBRHyippiaTzJTINHuXqFekOg0cl/8zZ2zTA +pcQaMQsjTRQV3J0apWCmowtwBb/ X-Google-Smtp-Source: APXvYqzQorgf994DsPyyQv3peNL7TL0Ll8x6YQvl0u1hrUDMvsT5ytdXzwzjJXwMR/hlg0yVOGGZpA== X-Received: by 2002:a05:6402:545:: with SMTP id i5mr16763116edx.11.1576861793199; Fri, 20 Dec 2019 09:09:53 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p6sm1188581eja.63.2019.12.20.09.09.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:52 -0800 (PST) Message-Id: <66bee10d1ca45548cf9b5a5bc2e17703ed54a82f.1576861788.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:37 +0000 Subject: [PATCH 04/15] rebase: make sure to pass along the quiet flag to the sequencer Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Signed-off-by: Elijah Newren --- builtin/rebase.c | 3 ++- t/t3400-rebase.sh | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index c71d169688..cc8f3f008f 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -126,6 +126,7 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts) replay.keep_redundant_commits = (opts->empty == EMPTY_KEEP); replay.ask_on_initially_empty = (opts->empty == EMPTY_ASK && !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)); + replay.quiet = !(opts->flags & REBASE_NO_QUIET); replay.verbose = opts->flags & REBASE_VERBOSE; replay.reschedule_failed_exec = opts->reschedule_failed_exec; replay.committer_date_is_author_date = @@ -1506,7 +1507,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) N_("allow pre-rebase hook to run")), OPT_NEGBIT('q', "quiet", &options.flags, N_("be quiet. implies --no-stat"), - REBASE_NO_QUIET| REBASE_VERBOSE | REBASE_DIFFSTAT), + REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT), OPT_BIT('v', "verbose", &options.flags, N_("display a diffstat of what changed upstream"), REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT), diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 221b35f2df..79762b989a 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -206,12 +206,18 @@ test_expect_success 'cherry-picked commits and fork-point work together' ' test_cmp expect D ' -test_expect_success 'rebase -q is quiet' ' +test_expect_success 'rebase --am -q is quiet' ' git checkout -b quiet topic && git rebase -q master >output.out 2>&1 && test_must_be_empty output.out ' +test_expect_success 'rebase --merge -q is quiet' ' + git checkout -B quiet topic && + git rebase --merge -q master >output.out 2>&1 && + test_must_be_empty output.out +' + test_expect_success 'Rebase a commit that sprinkles CRs in' ' ( echo "One" && From patchwork Fri Dec 20 17:09:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306021 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1AF21580 for ; Fri, 20 Dec 2019 17:10:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D06DE21D7D for ; Fri, 20 Dec 2019 17:10:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IBlgkbnW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727458AbfLTRJ5 (ORCPT ); Fri, 20 Dec 2019 12:09:57 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:42333 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727442AbfLTRJz (ORCPT ); Fri, 20 Dec 2019 12:09:55 -0500 Received: by mail-ed1-f68.google.com with SMTP id e10so8935142edv.9 for ; Fri, 20 Dec 2019 09:09:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=8CBJvG4wzRLjfBCPon2U1WRggvX4ia5WDIt+aDz58W8=; b=IBlgkbnWv2Xj88MPi1Vp5K2N2uxHpft7EMQs8wXJF/sgXriRdbXNZvKC4QK1Z4FlHv DZeBGZbK+6gPusPQwrFPhd2dKEaSF6cfsJ5S6PwzG+z4giYTIBr/JB9fra8zIw8WAmM2 0LB/WkNXWwzoQyZ5zqAQ+jcKWnaxJEKj+rUoceqp5OUiNosdM4bsy3YvHkoItQB5vAOx CPakAUujGSjfsBCMpmeZBYofG4IsSF8SAyVziSrXNkSUCmKKiMoWo8kiusXbSRwUocgG h1AL9JP5TPYZJkfOz0p9n64/W1g0G7PxePUh705rhXVOnjhU6us2/jQDoCJ7gqyBJmZ9 Tq7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=8CBJvG4wzRLjfBCPon2U1WRggvX4ia5WDIt+aDz58W8=; b=fkK9RTxxl5K9G1LDZhx8Yv1hMWgTKCbKL8M7qKPbyaa3sDE6Ts4bDpPnid2qtyoMNm LK9TlL4vZFr7Da214aUL2Ni/vv/1/aymX2oU92/F2ecMMJ0tSWUtXBJkzeIkoag9Zhjb bByXfBoxWkwsxvn5IoSm7CRqXCbil5J8BcLc4GDJH+vjtUqNzMCtysneJH9HMGagqvs3 pIjzPS9lT3DscAP/1crMMDF2StLOre1q40vVq6PwHuz6SqeV72/VivmzHA8Sm+kZ1cqS z94xPvL1Lk9RElnCXWxF+D867F4kCrYggd5Ct/ynPlVU3IzCZlb/54Rc2PqIofDZqbve WY0g== X-Gm-Message-State: APjAAAXcF0s1pepo12MjkiexMubaPV1hGCGb2OhKGcG6vbh4zpS3iITm dHjmRYRI36UR2FlCDEqQ7qoUtoRO X-Google-Smtp-Source: APXvYqxzhaJhrm5lR07XgBRqWGZdrHkfyLwll7TkZwU0g4ke4nUY/alGFrTnifdxDpFrF9CXBmjUvg== X-Received: by 2002:aa7:d343:: with SMTP id m3mr17154480edr.285.1576861793976; Fri, 20 Dec 2019 09:09:53 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id y11sm1020978edw.73.2019.12.20.09.09.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:53 -0800 (PST) Message-Id: In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:38 +0000 Subject: [PATCH 05/15] rebase: fix handling of restrict_revision Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren restrict_revision in the original shell script was an excluded revision range. It is also treated that way by the am-backend. In the conversion from shell to C (see commit 6ab54d17be3f ("rebase -i: implement the logic to initialize $revisions in C", 2018-08-28)), the interactive-backend accidentally treated it as a positive revision rather than a negated one. This was missed as there were no tests in the testsuite that tested an interactive rebase with fork-point behavior. Signed-off-by: Elijah Newren --- builtin/rebase.c | 4 ++-- t/t3400-rebase.sh | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index cc8f3f008f..b320bb3a30 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -364,8 +364,8 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) argv_array_pushl(&make_script_args, "", revisions, NULL); if (opts->restrict_revision) - argv_array_push(&make_script_args, - oid_to_hex(&opts->restrict_revision->object.oid)); + argv_array_pushf(&make_script_args, "^%s", + oid_to_hex(&opts->restrict_revision->object.oid)); ret = sequencer_make_script(the_repository, &todo_list.buf, make_script_args.argc, make_script_args.argv, diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 79762b989a..71fd6396cd 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -165,11 +165,29 @@ test_expect_success 'rebase works with format.useAutoBase' ' git rebase master ' -test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' ' +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--merge)' ' git checkout -b default-base master && git checkout -b default topic && git config branch.default.remote . && git config branch.default.merge refs/heads/default-base && + git rebase --merge && + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual && + git checkout default-base && + git reset --hard HEAD^ && + git checkout default && + git rebase --merge && + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual +' + +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' ' + git checkout -B default-base master && + git checkout -B default topic && + git config branch.default.remote . && + git config branch.default.merge refs/heads/default-base && git rebase && git rev-parse --verify default-base >expect && git rev-parse default~1 >actual && From patchwork Fri Dec 20 17:09:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306003 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 09B491580 for ; Fri, 20 Dec 2019 17:09:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D22D421D7E for ; Fri, 20 Dec 2019 17:09:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UcDRHNxb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727464AbfLTRJ6 (ORCPT ); Fri, 20 Dec 2019 12:09:58 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:39237 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727406AbfLTRJ4 (ORCPT ); Fri, 20 Dec 2019 12:09:56 -0500 Received: by mail-ed1-f68.google.com with SMTP id t17so8937260eds.6 for ; Fri, 20 Dec 2019 09:09:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=mETJKZCWTZRi4+3xkXNP6NhsWJqh1Sg8aoa0G2CeAOc=; b=UcDRHNxb/cRxhVscuWkrSHejTas73OcovE4UBoVD3tEAl2TVWl3o679WClSC4/Pr2D gxQBeMSkddvre5Qw/X5OwsfifbBWfPh8olB3lXKWrQ/Othn15RRFRs5OyuSeuFdGei/P u22q/Fv7gwG88Qpg0WEUdYKbyllaDalw5XGChtUh7rAVI1u2Pr3xt5tNnEyoftcVnvJi Eb+VTjDsHJRtTq60wF9p0NwU0seb4CbxKuW+2h6wGBpPDgSepIdabEDJRz/1/bMppjdD UiEmTZWIxRTJ8ilrS7Z6+rZq7t3lYYoDqhoDOci2Pp/XgA0E6vj4TUkoftoA0wv0DEyL XRrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=mETJKZCWTZRi4+3xkXNP6NhsWJqh1Sg8aoa0G2CeAOc=; b=CsQaY45T2mFV43OmFms/QMcs7sbKUBg7zqTk+TgdHMFljfPePrDTXTxb2cYDF2fchU XHGc6gy8ThJLr5J0jsN51YkwJUYcLkfoMDbbQZjjfPa9+u9iQOZml1+bOtejGMeaMn7u /eRCVPmTKZvUr4RCSezg2MdDMoF26SY/O2Tw0YodGxClSreVCgHkE3VAzWtl68SCa1Me Ux4rjFuMJyIVZuC0IcWkcSdoLvJAg70lQKXSSpy8iihFw9CeJRu13uAQgxkJ6EgrQsnP FEEPW0Ra8nqiKSDnw8LN0ClrFzFaycAhRgqnP7e85GRnIjWYyHdu/WHPDdF28x/9MhDG 2TUg== X-Gm-Message-State: APjAAAWDubhD5GVosdTv68Q6T8fmO+P7dOOir/NJrmU3rAvmmJavokNt h4bM9rGUqExOMpvf7ddNte8B8P+G X-Google-Smtp-Source: APXvYqzjGHk7ZP2G+MvDY8VykU9irzyX/wEy4X9Q8eQ+GuN7BdRB65y5ogSXS8Sc4KoTUM8yQb49VA== X-Received: by 2002:aa7:da13:: with SMTP id r19mr17051561eds.188.1576861794668; Fri, 20 Dec 2019 09:09:54 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id w12sm1017209edq.94.2019.12.20.09.09.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:54 -0800 (PST) Message-Id: <9b1ad46c58b7f8397acbf2a8339e150dfb04c956.1576861788.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:39 +0000 Subject: [PATCH 06/15] t3432: make these tests work with either am or merge backends Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren t3432 had several stress tests for can_fast_forward(), whose intent was to ensure we were using the optimization of just fast forwarding when possible. However, these tests verified that fast forwards had happened based on the output that rebase printed to the terminal. We can instead test more directly that we actually fast-forwarded by checking the reflog, which also has the side effect of making the tests applicable for the merge/interactive backend. This change does lose the distinction between "noop" and "noop-force", but as stated in commit c9efc216830f ("t3432: test for --no-ff's interaction with fast-forward", 2019-08-27) which introduced that distinction: "These tests aren't supposed to endorse the status quo, just test for what we're currently doing.". This change does not actually run these tests with the merge/interactive backend; instead this is just a preparatory commit. A subsequent commit which fixes can_fast_forward() to work with that backend will then also change t3432 to add tests of that backend as well. Signed-off-by: Elijah Newren --- t/t3432-rebase-fast-forward.sh | 53 ++++++++++++++++------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 92f95b57da..3879a43fa0 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -44,19 +44,16 @@ test_rebase_same_head_ () { test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" " oldhead=\$(git rev-parse HEAD) && test_when_finished 'git reset --hard \$oldhead' && + cp .git/logs/HEAD expect && git rebase$flag $* >stdout && if test $what = work then - # Must check this case first, for 'is up to - # date, rebase forced[...]rewinding head' cases - test_i18ngrep 'rewinding head' stdout + wc -l .git/logs/HEAD >old && + wc -l .git/logs/HEAD >new && + test_line_count '-gt' $(($old + 2)) .git/logs/HEAD elif test $what = noop then - test_i18ngrep 'is up to date' stdout && - test_i18ngrep ! 'rebase forced' stdout - elif test $what = noop-force - then - test_i18ngrep 'is up to date, rebase forced' stdout + test_cmp expect .git/logs/HEAD fi && newhead=\$(git rev-parse HEAD) && if test $cmp = same @@ -71,14 +68,14 @@ test_rebase_same_head_ () { changes='no changes' test_rebase_same_head success noop same success work same -test_rebase_same_head success noop same success noop-force same master -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B -test_rebase_same_head success noop same success noop-force same --onto master... master -test_rebase_same_head success noop same success noop-force same --keep-base master -test_rebase_same_head success noop same success noop-force same --keep-base -test_rebase_same_head success noop same success noop-force same --no-fork-point -test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point +test_rebase_same_head success noop same success work same master +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B +test_rebase_same_head success noop same success work same --onto master... master +test_rebase_same_head success noop same success work same --keep-base master +test_rebase_same_head success noop same success work same --keep-base +test_rebase_same_head success noop same success work same --no-fork-point +test_rebase_same_head success noop same success work same --keep-base --no-fork-point test_rebase_same_head success noop same success work same --fork-point master test_rebase_same_head success noop same success work diff --fork-point --onto B B test_rebase_same_head success noop same success work diff --fork-point --onto B... B @@ -91,14 +88,14 @@ test_expect_success 'add work same to side' ' changes='our changes' test_rebase_same_head success noop same success work same -test_rebase_same_head success noop same success noop-force same master -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B -test_rebase_same_head success noop same success noop-force same --onto master... master -test_rebase_same_head success noop same success noop-force same --keep-base master -test_rebase_same_head success noop same success noop-force same --keep-base -test_rebase_same_head success noop same success noop-force same --no-fork-point -test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point +test_rebase_same_head success noop same success work same master +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B +test_rebase_same_head success noop same success work same --onto master... master +test_rebase_same_head success noop same success work same --keep-base master +test_rebase_same_head success noop same success work same --keep-base +test_rebase_same_head success noop same success work same --no-fork-point +test_rebase_same_head success noop same success work same --keep-base --no-fork-point test_rebase_same_head success noop same success work same --fork-point master test_rebase_same_head success noop same success work diff --fork-point --onto B B test_rebase_same_head success noop same success work diff --fork-point --onto B... B @@ -112,13 +109,13 @@ test_expect_success 'add work same to upstream' ' ' changes='our and their changes' -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B test_rebase_same_head success noop same success work diff --onto master... master test_rebase_same_head success noop same success work diff --keep-base master test_rebase_same_head success noop same success work diff --keep-base -test_rebase_same_head failure work same success work diff --fork-point --onto B B -test_rebase_same_head failure work same success work diff --fork-point --onto B... B +test_rebase_same_head success work same success work diff --fork-point --onto B B +test_rebase_same_head success work same success work diff --fork-point --onto B... B test_rebase_same_head success noop same success work diff --fork-point --onto master... master test_rebase_same_head success noop same success work diff --fork-point --keep-base master From patchwork Fri Dec 20 17:09:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306009 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 71B981580 for ; Fri, 20 Dec 2019 17:10:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4F13D21D7D for ; Fri, 20 Dec 2019 17:10:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DhgCEbrJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727472AbfLTRKA (ORCPT ); Fri, 20 Dec 2019 12:10:00 -0500 Received: from mail-ed1-f67.google.com ([209.85.208.67]:40013 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727419AbfLTRJ5 (ORCPT ); Fri, 20 Dec 2019 12:09:57 -0500 Received: by mail-ed1-f67.google.com with SMTP id b8so8932190edx.7 for ; Fri, 20 Dec 2019 09:09:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=Jo5b/Q7DfXWd7kPKZgbR5K0YKULNIodOCBlnoUrwzRk=; b=DhgCEbrJApYFj1e8C+IRD7ox741q1zR7NCXwaVqYWBdHAKIAmOscw8aEAZjLD00Qh+ W3MIe7uPEkugAJbpFITgYgUSq+aidmyFH83EVUVbBK5KtOdsirgbS5c06PmuZaywqOnN 0RZBKPVt8PIYIweWEdGtTOcsUqKbQcfomMHlDHjlrz7WVhwH5AeAQ15bjYzpKe7+GRtm F15nH3lE6RvHTimEbmU5wxRxUJkDV60fCk+tNcyP/BXvTYaNKMq1ba9NQ9CHdR6cUFiC OROUhCDv/VeYc5g+WADBqrFMQha6gL4hPAx+6KgntSm0B7XSVYT1FiWaQh3o81OZJOhn qugg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=Jo5b/Q7DfXWd7kPKZgbR5K0YKULNIodOCBlnoUrwzRk=; b=WkI7yOt8q8EGaqAdZ/NZeFH3RFvsAONs9+BwS8fRk72QSBEqmuH43CetRTCnKtZ0ba Vj3oOxk08F/121mnILjMTTLD5PyMa339pPtSBAmlxBWuw2jRgf+p4bwv7MsQ6RJ+KUQb zwnrU00fxDh7DCWNQLAgviCvPSvalPN5ZCwMcS2I69kCGtmC1rJQV1yujbhZkR4FuD4d vo8c8LaJinY0hZhWrdLEIvHcwQyFqKdMMonvrpX+xPbIDCQhjCOQx0XaQSRhAp3nW5gJ 5iGqvucpKlkaEszN61zpmWIsjP/Trgm8SzNzIAhcgT9FuKJhlu1PNvi5HtlDR+kjLklF iU/A== X-Gm-Message-State: APjAAAUFJbMiSv4AeUWauUdo6O60BufFGC6Zgl6XBxgzCemLpIjIoDcE CVbkEuAF3Kx0jmYS9hLtIGFj9i1P X-Google-Smtp-Source: APXvYqwseB5Qo3nfKQJLhB4YqVkU7GMkWpcZA8tV1G1SrcSYYmLA35zoRZwLvovDhB0qkow1knaPKw== X-Received: by 2002:a17:906:2db1:: with SMTP id g17mr17238103eji.240.1576861795421; Fri, 20 Dec 2019 09:09:55 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id e1sm1029849edn.86.2019.12.20.09.09.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:55 -0800 (PST) Message-Id: In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:40 +0000 Subject: [PATCH 07/15] rebase: allow more types of rebases to fast-forward Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren In the past, we dis-allowed rebases using the interactive backend from performing a fast-forward to short-circuit the rebase operation. This made sense for explicitly interactive rebases and some implicitly interactive rebases, but certainly became overly stringent when the merge backend was re-implemented via the interactive backend. Just as the am-based rebase has always had to disable the fast-forward based on a variety of conditions or flags (e.g. --signoff, --whitespace, etc.), we need to do the same but now with a few more options. However, continuing to use REBASE_FORCE for tracking this is problematic because the interactive backend used it for a different purpose. (When REBASE_FORCE wasn't set, the interactive backend would not fast-forward the whole series but would fast-forward individual "pick" commits at the beginning of the todo list, and then a squash or something would cause it to start generating new commits.) So, introduce a new allow_preemptive_ff flag contained within cmd_rebase() and use it to track whether we are going to allow a pre-emptive fast-forward that short-circuits the whole rebase. Signed-off-by: Elijah Newren --- builtin/rebase.c | 18 ++++++++++++++---- t/t3432-rebase-fast-forward.sh | 2 ++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index b320bb3a30..67bccd876f 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1497,6 +1497,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) struct object_id squash_onto; char *squash_onto_name = NULL; int reschedule_failed_exec = -1; + int allow_preemptive_ff = 1; struct option builtin_rebase_options[] = { OPT_STRING(0, "onto", &options.onto_name, N_("revision"), @@ -1808,11 +1809,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) options.ignore_date) options.flags |= REBASE_FORCE; + if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) || + (action != ACTION_NONE) || + (exec.nr > 0) || + options.autosquash) { + allow_preemptive_ff = 0; + } + for (i = 0; i < options.git_am_opts.argc; i++) { const char *option = options.git_am_opts.argv[i], *p; if (!strcmp(option, "--whitespace=fix") || !strcmp(option, "--whitespace=strip")) - options.flags |= REBASE_FORCE; + allow_preemptive_ff = 0; else if (skip_prefix(option, "-C", &p)) { while (*p) if (!isdigit(*(p++))) @@ -2148,12 +2156,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) /* * Check if we are already based on onto with linear history, * in which case we could fast-forward without replacing the commits - * with new commits recreated by replaying their changes. This - * optimization must not be done if this is an interactive rebase. + * with new commits recreated by replaying their changes. + * + * Note that can_fast_forward() initializes merge_base, so we have to + * call it before checking allow_preemptive_ff. */ if (can_fast_forward(options.onto, options.upstream, options.restrict_revision, &options.orig_head, &merge_base) && - !is_interactive(&options)) { + allow_preemptive_ff) { int flag; if (!(options.flags & REBASE_FORCE)) { diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 3879a43fa0..58c91c6899 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -30,6 +30,8 @@ test_rebase_same_head () { shift && test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" && test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*" + test_rebase_same_head_ $status_n $what_n $cmp_n " --merge" "$*" && + test_rebase_same_head_ $status_f $what_f $cmp_f " --merge --no-ff" "$*" } test_rebase_same_head_ () { From patchwork Fri Dec 20 17:09:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin via GitGitGadget X-Patchwork-Id: 11306011 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 95D111580 for ; Fri, 20 Dec 2019 17:10:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 68DB3206D3 for ; Fri, 20 Dec 2019 17:10:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nw/Q6lyY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727483AbfLTRKC (ORCPT ); Fri, 20 Dec 2019 12:10:02 -0500 Received: from mail-ed1-f66.google.com ([209.85.208.66]:44837 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727451AbfLTRJ7 (ORCPT ); Fri, 20 Dec 2019 12:09:59 -0500 Received: by mail-ed1-f66.google.com with SMTP id bx28so8914761edb.11 for ; Fri, 20 Dec 2019 09:09:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=lhCCZYi0B8Y5DKm/BdvSQpxajRpqO1GMbHDyvaMtn7g=; b=nw/Q6lyY14VJROzlHwg9VglcoKVdVTycNI48EH/hpBfeUDLTxffz689vJuIbwz7ILc GIDm2B5pHWi4OPvlpvK5ryC9z2R5224NNCMxGyxdSIjgzGxYWFbOXVdS28DaVDlW+/Xd jwDaWJkZINtbnNxp2tUXQadEUr3XsLQxqlW1vffvhhwRQgeUh3gNhVrWcxqYd+Kn0OsJ Cz2Z27hYp4yk3rj0J2F0nXQYlJFAQ60N3Y1AVpoLS8oN51ThWyLbNEXWns7kJr6cA+em HWFzbfgAlb18pkVAn3/ds2jICTsAhV3XItxdZjf9iF+E/pszdi7JD46gir7sXYv9fIVR gmkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=lhCCZYi0B8Y5DKm/BdvSQpxajRpqO1GMbHDyvaMtn7g=; b=Z7wqcTXBGft+YwvT3+q/HWX0XmMz70L6Pm7BYlyeww2T5UQQg7RHxXCrJqB/hPBmFh 0EuLOgrJEvamLQ5gzVIN5QnNVulRQVL2th3MyS7kRvfsTS4v8O1IVOH3keRLm2tgyWNd h97PXW1QdOCez3yuyS3X05ASCgM8K6gFe+gXhrty8yqzG1Ou+Vy11CdDi3mVT8IZGw8Q /fyz6RkX4KcyXQCx99N/TBwzYDfa6V4+NIZNOGDHZaxmHGtHwBmPUnZ77dW2L3RQunWT G8cz+SQDFtMqYSX8F+ORU0KR3mFyRtMaajn56IDfh0nn7Rhxx/Qohb5GXL3C+6XTXJxE sTFg== X-Gm-Message-State: APjAAAVu4O1R4fcaeL+n913iJgFZGC8dhGl3SRQTnNvS+WMNyEos2/tj /u6xQ2ETE9kasItVTryckUICTYrV X-Google-Smtp-Source: APXvYqwsrqx+PrVxy2uthwu0ls6yyPcoXjIdq0zjHB4FmOnViALg4L0Cg4dJsHHcR6LTQ46QlRw8Cw== X-Received: by 2002:a17:906:3149:: with SMTP id e9mr16781836eje.292.1576861796161; Fri, 20 Dec 2019 09:09:56 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j21sm1014551eds.8.2019.12.20.09.09.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Dec 2019 09:09:55 -0800 (PST) Message-Id: <90e8927ea0533a078fe7fade9264f798bcdaa6ad.1576861788.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Elijah Newren via GitGitGadget" Date: Fri, 20 Dec 2019 17:09:41 +0000 Subject: [PATCH 08/15] git-rebase.txt: add more details about behavioral differences of backends Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes.Schindelin@gmx.de, phillip.wood@dunelm.org.uk, liu.denton@gmail.com, gitster@pobox.com, plroskin@gmail.com, Junio C Hamano , Elijah Newren Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Signed-off-by: Elijah Newren --- Documentation/git-rebase.txt | 102 +++++++++++++++++++++--- t/t3433-rebase-options-compatibility.sh | 5 +- 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index ff32ca1080..f1ace07c38 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -409,13 +409,10 @@ your branch contains commits which were dropped, this option can be used with `--keep-base` in order to drop those commits from your branch. --ignore-whitespace:: - Behaves differently depending on which backend is selected. -+ -'am' backend: When applying a patch, ignore changes in whitespace in -context lines if necessary. -+ -'interactive' backend: Treat lines with only whitespace changes as -unchanged for the sake of a three-way merge. + Ignore whitespace-only changes in the commits being rebased, + which may avoid "unnecessary" conflicts. (Both backends + currently have differing edgecase bugs with this option; see + BEHAVIORAL DIFFERENCES.) --whitespace=