From: Phillip Wood <phillip.wood123@gmail.com> To: Elijah Newren <newren@gmail.com>, Phillip Wood <phillip.wood@dunelm.org.uk> Cc: "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com>, "Git Mailing List" <git@vger.kernel.org>, "Johannes Schindelin" <Johannes.Schindelin@gmx.de>, "Denton Liu" <liu.denton@gmail.com>, "Junio C Hamano" <gitster@pobox.com>, "Pavel Roskin" <plroskin@gmail.com>, "Alban Gruin" <alban.gruin@gmail.com>, "SZEDER Gábor" <szeder.dev@gmail.com>, "Jonathan Nieder" <jrnieder@gmail.com>, "Emily Shaffer" <emilyshaffer@google.com> Subject: Re: [PATCH v4 04/19] rebase (interactive-backend): fix handling of commits that become empty Date: Sun, 16 Feb 2020 14:46:41 +0000 Message-ID: <f93b9f73-10c5-b94b-df4e-bfdb05a9723a@gmail.com> (raw) In-Reply-To: <CABPp-BGRGkjBk9aY8DUXJY52e5u_aAVd8-dspEcW6Se3v-G4-Q@mail.gmail.com> Hi Elijah On 13/02/2020 18:54, Elijah Newren wrote: > On Mon, Feb 10, 2020 at 6:27 AM Phillip Wood <phillip.wood123@gmail.com> wrote: >> >> Hi Elijah >> >> On 16/01/2020 06:14, Elijah Newren via GitGitGadget wrote: >>> From: Elijah Newren <newren@gmail.com> >>> >>> As established in the previous commit and commit b00bf1c9a8dd >>> (git-rebase: make --allow-empty-message the default, 2018-06-27), the >>> behavior for rebase with different backends in various edge or corner >>> cases is often more happenstance than design. This commit addresses >>> another such corner case: commits which "become empty". >>> >>> A careful reader may note that there are two types of commits which would >>> become empty due to a rebase: >>> >>> * [clean cherry-pick] Commits which are clean cherry-picks of upstream >>> commits, as determined by `git log --cherry-mark ...`. Re-applying >>> these commits would result in an empty set of changes and a >>> duplicative commit message; i.e. these are commits that have >>> "already been applied" upstream. >>> >>> * [become empty] Commits which are not empty to start, are not clean >>> cherry-picks of upstream commits, but which still become empty after >>> being rebased. This happens e.g. when a commit has changes which >>> are a strict subset of the changes in an upstream commit, or when >>> the changes of a commit can be found spread across or among several >>> upstream commits. >>> >>> Clearly, in both cases the changes in the commit in question are found >>> upstream already, but the commit message may not be in the latter case. >>> >>> When cherry-mark can determine a commit is already upstream, then >>> because of how cherry-mark works this means the upstream commit message >>> was about the *exact* same set of changes. Thus, the commit messages >>> can be assumed to be fully interchangeable (and are in fact likely to be >>> completely identical). As such, the clean cherry-pick case represents a >>> case when there is no information to be gained by keeping the extra >>> commit around. All rebase types have always dropped these commits, and >>> no one to my knowledge has ever requested that we do otherwise. >>> >>> For many of the become empty cases (and likely even most), we will also >>> be able to drop the commit without loss of information -- but this isn't >>> quite always the case. Since these commits represent cases that were >>> not clean cherry-picks, there is no upstream commit message explaining >>> the same set of changes. Projects with good commit message hygiene will >>> likely have the explanation from our commit message contained within or >>> spread among the relevant upstream commits, but not all projects run >>> that way. As such, the commit message of the commit being rebased may >>> have reasoning that suggests additional changes that should be made to >>> adapt to the new base, or it may have information that someone wants to >>> add as a note to another commit, or perhaps someone even wants to create >>> an empty commit with the commit message as-is. >>> >>> Junio commented on the "become-empty" types of commits as follows[1]: >>> >>> WRT a change that ends up being empty (as opposed to a change that >>> is empty from the beginning), I'd think that the current behaviour >>> is desireable one. "am" based rebase is solely to transplant an >>> existing history and want to stop much less than "interactive" one >>> whose purpose is to polish a series before making it publishable, >>> and asking for confirmation ("this has become empty--do you want to >>> drop it?") is more appropriate from the workflow point of view. >>> >>> [1] https://lore.kernel.org/git/xmqqfu1fswdh.fsf@gitster-ct.c.googlers.com/ >>> >>> I would simply add that his arguments for "am"-based rebases actually >>> apply to all non-explicitly-interactive rebases. Also, since we are >>> stating that different cases should have different defaults, it may be >>> worth providing a flag to allow users to select which behavior they want >>> for these commits. >>> >>> Introduce a new command line flag for selecting the desired behavior: >>> --empty={drop,keep,ask} >>> with the definitions: >>> drop: drop commits which become empty >>> keep: keep commits which become empty >>> ask: provide the user a chance to interact and pick what to do with >>> commits which become empty on a case-by-case basis >>> >>> In line with Junio's suggestion, if the --empty flag is not specified, >>> pick defaults as follows: >>> explicitly interactive: ask >>> otherwise: drop >> >> Looking at the implementation there is a third option - if `--exec` is >> given without `-i` then the default is "keep". I'm not sure if having >> different defaults is convenient or confusing but don't feel that >> strongly about it. > > Heh, in https://lore.kernel.org/git/404424d7-f520-8f89-efef-ca03e66fcd43@gmail.com/ > you argued that having different defaults was confusing and sounded > like you felt strongly about it. Granted, there has been a lot of > simplification to the implementation (and description) since then but > I'm still inclined to go with the simpler and more easily explained > behavior for the defaults based on what you said there. I would still prefer a common default but I can see the logic to the defaults you are proposing I just think it makes it hard to explain and it'll end up surprising someone who was expecting a different default. When I said I didn't feel that strongly I meant that it wasn't worth holding up this just for this. Best Wishes Phillip >> I've got a few minor comments below (the mains ones >> are saying which commit has been dropped and testing the default >> behavior when --empty is not given) but basically I like the new patch. >> Thanks for working on this, the commit message does a good job of >> explaining the changes. > > :-) > >>> Signed-off-by: Elijah Newren <newren@gmail.com> >>> --- >>> Documentation/git-rebase.txt | 27 ++++++++++++++++--- >>> builtin/rebase.c | 52 ++++++++++++++++++++++++++++++++++++ >>> sequencer.c | 48 +++++++++++++++++++++++++-------- >>> sequencer.h | 1 + >>> t/t3424-rebase-empty.sh | 50 +++++++++++++++++++++++++++++----- >>> t/t3427-rebase-subtree.sh | 8 +++--- >>> 6 files changed, 161 insertions(+), 25 deletions(-) >>> >>> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt >>> index 1d19542d79..551a91d764 100644 >>> --- a/Documentation/git-rebase.txt >>> +++ b/Documentation/git-rebase.txt >>> @@ -258,6 +258,22 @@ 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 are not empty to start and are not >>> + clean cherry-picks of any upstream commit, but which become >>> + empty after rebasing (because they contain a subset of already >>> + upstream changes). With drop (the default), commits that >>> + become empty are dropped. With keep, 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, edit files more, or just commit the empty changes. >> >> We should probably document the default for --exec without -i > > I did, but I guess it wasn't clear enough. Maybe I should add "Note > that other options like --exec will use the default of drop unless > -i/--interactive is specified."? > >>> +Note that commits which start empty are kept, and commits which are >>> +clean cherry-picks (as determined by `git log --cherry-mark ...`) are >>> +always dropped. >>> ++ >>> +See also INCOMPATIBLE OPTIONS below. >>> + >>> --keep-empty:: >>> No-op. Rebasing commits that started empty (had no change >>> relative to their parent) used to fail and this option would >>> @@ -561,6 +577,7 @@ are incompatible with the following options: >>> * --interactive >>> * --exec >>> * --keep-empty >>> + * --empty= >>> * --edit-todo >>> * --root when used in combination with --onto >>> >>> @@ -569,6 +586,7 @@ In addition, the following pairs of options are incompatible: >>> * --preserve-merges and --interactive >>> * --preserve-merges and --signoff >>> * --preserve-merges and --rebase-merges >>> + * --preserve-merges and --empty= >>> * --keep-base and --onto >>> * --keep-base and --root >>> >>> @@ -585,9 +603,12 @@ commits that started empty, though these are rare in practice. It >>> also drops commits that become empty and has no option for controlling >>> this behavior. >>> >>> -The interactive backend keeps intentionally empty commits. >>> -Unfortunately, it always halts whenever it runs across a commit that >>> -becomes empty, even when the rebase is not explicitly interactive. >>> +The interactive backend keeps intentionally empty commits. Similar to >>> +the am backend, by default the interactive backend drops commits that >>> +become empty unless -i/--interactive is specified (in which case it >>> +stops and asks the user what to do). The interactive backend also has >>> +an --empty={drop,keep,ask} option for changing the behavior of >>> +handling commits that become empty. >>> >>> Directory rename detection >>> ~~~~~~~~~~~~~~~~~~~~~~~~~~ >>> diff --git a/builtin/rebase.c b/builtin/rebase.c >>> index 537b3241ce..c299869e7b 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; >>> @@ -91,6 +99,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 \ >>> @@ -109,6 +118,8 @@ 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.verbose = opts->flags & REBASE_VERBOSE; >>> replay.reschedule_failed_exec = opts->reschedule_failed_exec; >>> replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt); >>> @@ -444,6 +455,10 @@ 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; >>> + */ >>> opts->type = REBASE_INTERACTIVE; >>> return 0; >>> } >>> @@ -1350,6 +1365,29 @@ static int parse_opt_interactive(const struct option *opt, const char *arg, >>> return 0; >>> } >>> >>> +static enum empty_type parse_empty_value(const char *value) >>> +{ >>> + if (!strcasecmp(value, "drop")) >>> + return EMPTY_DROP; >>> + else if (!strcasecmp(value, "keep")) >>> + return EMPTY_KEEP; >>> + else if (!strcasecmp(value, "ask")) >>> + return EMPTY_ASK; >>> + >>> + die(_("unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask\"."), value); >>> +} >>> + >>> +static int parse_opt_empty(const struct option *opt, const char *arg, int unset) >>> +{ >>> + struct rebase_options *options = opt->value; >>> + enum empty_type value = parse_empty_value(arg); >>> + >>> + BUG_ON_OPT_NEG(unset); >>> + >>> + options->empty = value; >>> + return 0; >>> +} >>> + >>> static void NORETURN error_on_missing_default_upstream(void) >>> { >>> struct branch *current_branch = branch_get(NULL); >>> @@ -1494,6 +1532,9 @@ 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_CALLBACK_F(0, "empty", &options, N_("{drop,keep,ask}"), >>> + N_("how to handle empty commits"), >> >> Maybe we should say "how to handle commits that become empty" to >> distinguish them from commits that start empty which we always keep > > Ooh, good catch; will fix. > >>> + PARSE_OPT_NONEG, parse_opt_empty), >>> { OPTION_CALLBACK, 'k', "keep-empty", &options, NULL, >>> N_("(DEPRECATED) keep empty commits"), >>> PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, >>> @@ -1760,6 +1801,9 @@ 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.empty != EMPTY_UNSPECIFIED) >>> + imply_interactive(&options, "--empty"); >>> + >>> if (gpg_sign) { >>> free(options.gpg_sign_opt); >>> options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign); >>> @@ -1843,6 +1887,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/sequencer.c b/sequencer.c >>> index c21fc202b1..354d0b5a38 100644 >>> --- a/sequencer.c >>> +++ b/sequencer.c >>> @@ -158,6 +158,8 @@ 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 int git_sequencer_config(const char *k, const char *v, void *cb) >>> { >>> @@ -1483,7 +1485,11 @@ static int is_original_commit_empty(struct commit *commit) >>> } >>> >>> /* >>> - * Do we run "git commit" with "--allow-empty"? >>> + * Should empty commits be allowed? Return status: >>> + * <0: Error in is_index_unchanged(r) or is_original_commit_empty(commit) >>> + * 0: Halt on empty commit >>> + * 1: Allow empty commit >>> + * 2: Drop empty commit >>> */ >>> static int allow_empty(struct repository *r, >>> struct replay_opts *opts, >>> @@ -1492,14 +1498,17 @@ static int allow_empty(struct repository *r, >>> int index_unchanged, originally_empty; >>> >>> /* >>> - * Three cases: >>> + * Four cases: >>> * >>> * (1) we do not allow empty at all and error out. >>> * >>> - * (2) we allow ones that were initially empty, but >>> - * forbid the ones that become empty; >>> + * (2) we allow ones that were initially empty, and >>> + * just drop the ones that become empty >>> * >>> - * (3) we allow both. >>> + * (3) we allow ones that were initially empty, but >>> + * halt for the ones that become empty; >>> + * >>> + * (4) we allow both. >>> */ >>> if (!opts->allow_empty) >>> return 0; /* let "git commit" barf as necessary */ >>> @@ -1516,10 +1525,12 @@ static int allow_empty(struct repository *r, >>> originally_empty = is_original_commit_empty(commit); >>> if (originally_empty < 0) >>> return originally_empty; >>> - if (!originally_empty) >>> - return 0; >>> - else >>> + if (originally_empty) >>> return 1; >>> + else if (opts->drop_redundant_commits) >>> + return 2; >>> + else >>> + return 0; >>> } >>> >>> static struct { >>> @@ -1730,7 +1741,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) { >>> /* >>> @@ -1935,13 +1946,18 @@ static int do_pick_commit(struct repository *r, >>> goto leave; >>> } >>> >>> + drop_commit = 0; >>> allow = allow_empty(r, opts, commit); >>> if (allow < 0) { >>> res = allow; >>> goto leave; >>> - } else if (allow) >>> + } else if (allow == 1) { >>> flags |= ALLOW_EMPTY; >>> - if (!opts->no_commit) { >>> + } else if (allow == 2) { >>> + drop_commit = 1; >>> + fprintf(stderr, _("No changes -- Patch already applied.\n")); >> >> nit pick - usually messages start with a lowercase letter. Would it be >> helpful to explicitly state which commit is being dropped as well as >> why? Something like >> dropping <oid> <subject> - patch contents already upstream > > I was actually just trying to mimic the am-backend here, and copied > its message verbatim for this case (see am_run() in builtin/am.c). > However, your version does seem more helpful and informative. I'll > look into it implementing it here. > >> >>> + } // else allow == 0 and there's nothing special to do >> >> We don't use // for comments > > Oops, sorry. Will fix. > >> >>> + if (!opts->no_commit && !drop_commit) { >>> if (author || command == TODO_REVERT || (flags & AMEND_MSG)) >>> res = do_commit(r, msg_file, author, opts, flags); >>> else >>> @@ -2495,6 +2511,12 @@ 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; >>> + >>> read_strategy_opts(opts, &buf); >>> strbuf_release(&buf); >>> >>> @@ -2574,6 +2596,10 @@ int write_basic_state(struct replay_opts *opts, const char *head_name, >>> write_file(rebase_path_gpg_sign_opt(), "-S%s\n", opts->gpg_sign); >>> if (opts->signoff) >>> write_file(rebase_path_signoff(), "--signoff\n"); >>> + 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->reschedule_failed_exec) >>> write_file(rebase_path_reschedule_failed_exec(), "%s", ""); >>> >>> diff --git a/sequencer.h b/sequencer.h >>> index c165e0ff25..3b0ab9141f 100644 >>> --- a/sequencer.h >>> +++ b/sequencer.h >>> @@ -39,6 +39,7 @@ struct replay_opts { >>> int allow_rerere_auto; >>> int allow_empty; >>> int allow_empty_message; >>> + int drop_redundant_commits; >>> int keep_redundant_commits; >>> int verbose; >>> int quiet; >>> diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh >>> index 22d97e143b..dcb4cb4751 100755 >>> --- a/t/t3424-rebase-empty.sh >>> +++ b/t/t3424-rebase-empty.sh >>> @@ -34,7 +34,7 @@ test_expect_success 'setup test repository' ' >>> git commit -m "Five letters ought to be enough for anybody" >>> ' >>> >>> -test_expect_failure 'rebase (am-backend) with a variety of empty commits' ' >>> +test_expect_failure 'rebase (am-backend)' ' >>> test_when_finished "git rebase --abort" && >>> git checkout -B testing localmods && >>> # rebase (--am) should not drop commits that start empty >>> @@ -45,11 +45,29 @@ test_expect_failure 'rebase (am-backend) with a variety of empty commits' ' >>> test_cmp expect actual >>> ' >>> >>> -test_expect_failure 'rebase --merge with a variety of empty commits' ' >>> - test_when_finished "git rebase --abort" && >>> +test_expect_success 'rebase --merge --empty=drop' ' >>> git checkout -B testing localmods && >>> - # rebase --merge should not halt on the commit that becomes empty >>> - git rebase --merge upstream && >>> + git rebase --merge --empty=drop upstream && >>> + >>> + test_write_lines D 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 && >>> + >>> + git rebase --skip && >>> >>> test_write_lines D C B A >expect && >>> git log --format=%s >actual && >>> @@ -58,9 +76,27 @@ test_expect_failure 'rebase --merge with a variety of empty commits' ' >>> >>> GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR >>> >>> -test_expect_success 'rebase --interactive with a variety of empty commits' ' >>> +test_expect_success 'rebase --interactive --empty=drop' ' >>> + git checkout -B testing localmods && >>> + git rebase --interactive --empty=drop upstream && >>> + >>> + test_write_lines D 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_expect_success 'rebase --interactive --empty=ask' ' >>> git checkout -B testing localmods && >>> - test_must_fail git rebase --interactive upstream && >>> + test_must_fail git rebase --interactive --empty=ask upstream && >>> >>> git rebase --skip && >> >> As the default if --empty is not given is supposed to vary depending on >> the other options given it would be good to test that I think > > I'll add some tests. > > > Thanks for the thorough review! > Elijah >
next prev parent reply index Thread overview: 161+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-12-20 17:09 [PATCH 00/15] rebase: make the default backend configurable Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 01/15] rebase: extend the options for handling of empty commits Elijah Newren via GitGitGadget 2019-12-20 21:29 ` Junio C Hamano 2019-12-21 0:32 ` Elijah Newren 2019-12-21 18:52 ` Elijah Newren 2019-12-21 23:49 ` Junio C Hamano 2019-12-20 17:09 ` [PATCH 02/15] t3406: simplify an already simple test Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 03/15] rebase, sequencer: remove the broken GIT_QUIET handling Elijah Newren via GitGitGadget 2019-12-20 21:34 ` Junio C Hamano 2019-12-20 17:09 ` [PATCH 04/15] rebase: make sure to pass along the quiet flag to the sequencer Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 05/15] rebase: fix handling of restrict_revision Elijah Newren via GitGitGadget 2019-12-20 21:37 ` Junio C Hamano 2019-12-20 17:09 ` [PATCH 06/15] t3432: make these tests work with either am or merge backends Elijah Newren via GitGitGadget 2019-12-22 5:11 ` Denton Liu 2019-12-23 17:17 ` Elijah Newren 2019-12-20 17:09 ` [PATCH 07/15] rebase: allow more types of rebases to fast-forward Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 08/15] git-rebase.txt: add more details about behavioral differences of backends Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 09/15] rebase: move incompatibility checks between backend options a bit earlier Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 10/15] rebase: add an --am option Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 11/15] contrib: change the prompt for am-based rebases Elijah Newren via GitGitGadget 2019-12-20 23:07 ` SZEDER Gábor 2019-12-21 0:17 ` Elijah Newren 2019-12-20 17:09 ` [PATCH 12/15] rebase tests: mark tests specific to the am-backend with --am Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 13/15] rebase tests: repeat some tests using the merge backend instead of am Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 14/15] rebase: make the backend configurable via config setting Elijah Newren via GitGitGadget 2019-12-20 17:09 ` [PATCH 15/15] rebase: change the default backend from "am" to "merge" Elijah Newren via GitGitGadget 2019-12-20 18:51 ` [PATCH 00/15] rebase: make the default backend configurable Alban Gruin 2019-12-20 18:55 ` Elijah Newren 2019-12-23 18:49 ` [PATCH v2 " Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 01/15] rebase: extend the options for handling of empty commits Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 02/15] t3406: simplify an already simple test Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 03/15] rebase, sequencer: remove the broken GIT_QUIET handling Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 04/15] rebase: make sure to pass along the quiet flag to the sequencer Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 05/15] rebase: fix handling of restrict_revision Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 06/15] t3432: make these tests work with either am or merge backends Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 07/15] rebase: allow more types of rebases to fast-forward Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 08/15] git-rebase.txt: add more details about behavioral differences of backends Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 09/15] rebase: move incompatibility checks between backend options a bit earlier Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 10/15] rebase: add an --am option Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 11/15] contrib: change the prompt for interactive-based rebases Elijah Newren via GitGitGadget 2019-12-23 22:00 ` Denton Liu 2019-12-23 18:49 ` [PATCH v2 12/15] rebase tests: mark tests specific to the am-backend with --am Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 13/15] rebase tests: repeat some tests using the merge backend instead of am Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 14/15] rebase: make the backend configurable via config setting Elijah Newren via GitGitGadget 2019-12-23 18:49 ` [PATCH v2 15/15] rebase: change the default backend from "am" to "merge" Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 00/15] rebase: make the default backend configurable Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 01/15] rebase: extend the options for handling of empty commits Elijah Newren via GitGitGadget 2020-01-07 14:37 ` Phillip Wood 2020-01-07 19:15 ` Elijah Newren 2020-01-08 14:27 ` Phillip Wood 2020-01-09 21:32 ` Johannes Schindelin 2019-12-24 19:54 ` [PATCH v3 02/15] t3406: simplify an already simple test Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 03/15] rebase, sequencer: remove the broken GIT_QUIET handling Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 04/15] rebase: make sure to pass along the quiet flag to the sequencer Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 05/15] rebase: fix handling of restrict_revision Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 06/15] t3432: make these tests work with either am or merge backends Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 07/15] rebase: allow more types of rebases to fast-forward Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 08/15] git-rebase.txt: add more details about behavioral differences of backends Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 09/15] rebase: move incompatibility checks between backend options a bit earlier Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 10/15] rebase: add an --am option Elijah Newren via GitGitGadget 2020-01-07 14:43 ` Phillip Wood 2020-01-07 19:26 ` Elijah Newren 2020-01-07 20:11 ` Junio C Hamano 2020-01-08 14:32 ` Phillip Wood 2020-01-08 17:18 ` Junio C Hamano 2020-01-08 18:55 ` Phillip Wood 2019-12-24 19:54 ` [PATCH v3 11/15] git-prompt: change the prompt for interactive-based rebases Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 12/15] rebase tests: mark tests specific to the am-backend with --am Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 13/15] rebase tests: repeat some tests using the merge backend instead of am Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 14/15] rebase: make the backend configurable via config setting Elijah Newren via GitGitGadget 2019-12-24 19:54 ` [PATCH v3 15/15] rebase: change the default backend from "am" to "merge" Elijah Newren via GitGitGadget 2020-01-10 23:14 ` Jonathan Nieder 2020-01-11 1:16 ` Elijah Newren 2020-01-11 14:41 ` Phillip Wood 2020-01-12 17:59 ` Johannes Schindelin 2020-01-16 6:32 ` Elijah Newren 2020-01-16 7:58 ` Jonathan Nieder 2020-01-16 8:06 ` Jonathan Nieder 2020-01-16 16:18 ` Elijah Newren 2020-01-16 20:35 ` Jonathan Nieder 2020-01-16 21:30 ` Elijah Newren 2020-01-16 22:39 ` Jonathan Nieder 2020-01-16 23:19 ` Elijah Newren 2020-01-16 23:25 ` Junio C Hamano 2020-01-17 0:51 ` Elijah Newren 2020-01-16 15:35 ` Elijah Newren 2020-01-16 20:05 ` Junio C Hamano 2020-01-16 10:48 ` Johannes Schindelin 2020-01-12 21:23 ` Junio C Hamano 2020-01-15 19:50 ` Jonathan Nieder 2020-01-15 21:59 ` Emily Shaffer 2020-01-16 6:14 ` [PATCH v4 00/19] rebase: make the default backend configurable Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 01/19] git-rebase.txt: update description of --allow-empty-message Elijah Newren via GitGitGadget 2020-02-09 15:59 ` Phillip Wood 2020-02-13 18:35 ` Elijah Newren 2020-01-16 6:14 ` [PATCH v4 02/19] t3404: directly test the behavior of interest Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 03/19] rebase (interactive-backend): make --keep-empty the default Elijah Newren via GitGitGadget 2020-02-09 15:59 ` Phillip Wood 2020-02-13 18:52 ` Elijah Newren 2020-01-16 6:14 ` [PATCH v4 04/19] rebase (interactive-backend): fix handling of commits that become empty Elijah Newren via GitGitGadget 2020-02-10 14:27 ` Phillip Wood 2020-02-13 18:54 ` Elijah Newren 2020-02-16 14:46 ` Phillip Wood [this message] 2020-01-16 6:14 ` [PATCH v4 05/19] t3406: simplify an already simple test Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 06/19] rebase, sequencer: remove the broken GIT_QUIET handling Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 07/19] rebase: make sure to pass along the quiet flag to the sequencer Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 08/19] rebase: fix handling of restrict_revision Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 09/19] t3432: make these tests work with either am or merge backends Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 10/19] rebase: allow more types of rebases to fast-forward Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 11/19] git-rebase.txt: add more details about behavioral differences of backends Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 12/19] rebase: move incompatibility checks between backend options a bit earlier Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 13/19] rebase: add an --am option Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 14/19] git-prompt: change the prompt for interactive-based rebases Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 15/19] rebase: drop '-i' from the reflog " Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 16/19] rebase tests: mark tests specific to the am-backend with --am Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 17/19] rebase tests: repeat some tests using the merge backend instead of am Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 18/19] rebase: make the backend configurable via config setting Elijah Newren via GitGitGadget 2020-01-16 6:14 ` [PATCH v4 19/19] rebase: change the default backend from "am" to "merge" Elijah Newren via GitGitGadget 2020-01-17 16:58 ` [PATCH v4 00/19] rebase: make the default backend configurable Phillip Wood 2020-02-05 21:06 ` Junio C Hamano 2020-02-05 22:38 ` Elijah Newren 2020-02-15 21:36 ` [PATCH v5 00/20] rebase: make the default backend configurable and change the default Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 01/20] git-rebase.txt: update description of --allow-empty-message Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 02/20] t3404: directly test the behavior of interest Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 03/20] rebase (interactive-backend): make --keep-empty the default Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 04/20] rebase (interactive-backend): fix handling of commits that become empty Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 05/20] t3406: simplify an already simple test Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 06/20] rebase, sequencer: remove the broken GIT_QUIET handling Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 07/20] rebase: make sure to pass along the quiet flag to the sequencer Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 08/20] rebase: fix handling of restrict_revision Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 09/20] t3432: make these tests work with either am or merge backends Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 10/20] rebase: allow more types of rebases to fast-forward Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 11/20] git-rebase.txt: add more details about behavioral differences of backends Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 12/20] rebase: move incompatibility checks between backend options a bit earlier Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 13/20] rebase: add an --am option Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 14/20] git-prompt: change the prompt for interactive-based rebases Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 15/20] rebase: drop '-i' from the reflog " Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 16/20] rebase tests: mark tests specific to the am-backend with --am Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 17/20] rebase tests: repeat some tests using the merge backend instead of am Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 18/20] rebase: make the backend configurable via config setting Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 19/20] rebase: change the default backend from "am" to "merge" Elijah Newren via GitGitGadget 2020-02-15 21:36 ` [PATCH v5 20/20] rebase: rename the two primary rebase backends Elijah Newren via GitGitGadget 2020-03-12 15:13 ` Emily Shaffer 2020-03-12 16:33 ` Elijah Newren 2020-03-12 17:55 ` Jonathan Nieder 2020-03-12 18:39 ` Elijah Newren 2020-03-12 18:46 ` Jonathan Nieder 2020-03-12 19:31 ` Elijah Newren 2020-03-17 2:58 ` Jonathan Nieder 2020-03-17 4:45 ` Elijah Newren 2020-03-12 19:54 ` Junio C Hamano 2020-03-12 19:07 ` Junio C Hamano 2020-03-12 19:12 ` Jonathan Nieder 2020-03-12 19:12 ` Junio C Hamano 2020-03-12 19:29 ` Elijah Newren 2020-03-12 20:37 ` Jeff King 2020-03-12 21:27 ` Junio C Hamano 2020-03-12 22:06 ` Elijah Newren 2020-03-13 0:04 ` Junio C Hamano 2020-03-12 23:30 ` Jonathan Nieder 2020-02-16 15:01 ` [PATCH v5 00/20] rebase: make the default backend configurable and change the default Phillip Wood
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=f93b9f73-10c5-b94b-df4e-bfdb05a9723a@gmail.com \ --to=phillip.wood123@gmail.com \ --cc=Johannes.Schindelin@gmx.de \ --cc=alban.gruin@gmail.com \ --cc=emilyshaffer@google.com \ --cc=git@vger.kernel.org \ --cc=gitgitgadget@gmail.com \ --cc=gitster@pobox.com \ --cc=jrnieder@gmail.com \ --cc=liu.denton@gmail.com \ --cc=newren@gmail.com \ --cc=phillip.wood@dunelm.org.uk \ --cc=plroskin@gmail.com \ --cc=szeder.dev@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Mailing List Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/git/0 git/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 git git/ https://lore.kernel.org/git \ git@vger.kernel.org public-inbox-index git Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.git AGPL code for this site: git clone https://public-inbox.org/public-inbox.git