git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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	[thread overview]
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
> 

  reply	other threads:[~2020-02-16 14:46 UTC|newest]

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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).