Re: [PATCH v2 9/9] [RFC] rebase -i: leave CHERRY_PICK_HEAD when there are conflicts
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Dec 18, 2019, 14:35 UTC
- Message-ID
- <7e1b92f5-48df-e202-ebcc-5b15987a7d63@gmail.com>
- In-Reply-To
- <20191206160614.631724-10-phillip.wood123@gmail.com>
On 06/12/2019 16:06, Phillip Wood wrote:
Show 10 quoted lines
> From: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> Since the inception of CHERRY_PICK_HEAD in d7e5c0cbfb ("Introduce
> CHERRY_PICK_HEAD", 2011-02-19) 'rebase -i' has removed it when there are
> conflicts. The rationale for this was that the rebase wanted to handle
> the conflicts itself. However sometimes (e.g. after an edit command) the
> user wants to commit the conflict resolution before making some other
> changes or running some tests. Without CHERRY_PICK_HEAD the authorship
> information is lost when the user makes the commit. Fix this by leaving
> CHERRY_PICK_HEAD when we're not amending.I'm not so sure about this approach as it wont work with 'merge' commands when rebasing. I wonder if it would be better to add a new file COMMIT_AUTHOR (or maybe MERGE_AUTHOR) that can be parsed by split_ident() and sets the authorship for a commit. The file would override $GIT_AUTHOR_NAME/EMAIL/DATE but could be overridden on the commandline by --author/date/reset-author
Best Wishes
Phillip
Show 202 quoted lines
> Note that this changes the output of `git status`. The advice to run
> `git reset` is not appropriate for rebase as we do not allow partial
> commits.
>
> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> ---
>
> Notes:
> This has semantic conflicts with ra/rebase-i-more-options as it does not
> respect the options passed to rebase when the user commits
>
> I haven't checked how this affects the shell prompt in contrib yet, I
> suspect it may need changing to cope the presence of CHERRY_PICK_HEAD
> during a rebase.
>
> I'd like to change the existing authorship tests to rely on the "Original
> Author" changes here, but they are a web of hidden interdependencies which is
> hard to untangle.
>
> sequencer.c | 12 ++--
> t/t3404-rebase-interactive.sh | 104 +++++++++++++++++++++++++---------
> t/t7512-status-help.sh | 2 -
> 3 files changed, 85 insertions(+), 33 deletions(-)
>
> diff --git a/sequencer.c b/sequencer.c
> index 64242f4ce7..624e96c930 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -372,11 +372,15 @@ static void print_advice(struct repository *r, int show_hint,
> if (msg) {
> fprintf(stderr, "%s\n", msg);
> /*
> - * A conflict has occurred but the porcelain
> - * (typically rebase --interactive) wants to take care
> - * of the commit itself so remove CHERRY_PICK_HEAD
> + * A conflict has occurred but the porcelain wants to take care
> + * of the commit itself so remove CHERRY_PICK_HEAD. Note that we
> + * do not do this for interactive rebases anymore in order to
> + * preserve the author identity when the user runs 'git commit'
> + * to commit the conflict resolution rather than relying on
> + * 'rebase --continue' to do it for them.
> */
> - unlink(git_path_cherry_pick_head(r));
> + if (!is_rebase_i(opts))
> + unlink(git_path_cherry_pick_head(r));
> return;
> }
>
> diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
> index 5afa6f28cd..5cd7db18f8 100755
> --- a/t/t3404-rebase-interactive.sh
> +++ b/t/t3404-rebase-interactive.sh
> @@ -33,31 +33,35 @@ Initial setup:
> # in the expect2 file for the 'stop on conflicting pick' test.
>
> test_expect_success 'setup' '
> - test_commit A file1 &&
> - test_commit B file1 &&
> - test_commit C file2 &&
> - test_commit D file1 &&
> - test_commit E file3 &&
> - git checkout -b branch1 A &&
> - test_commit F file4 &&
> - test_commit G file1 &&
> - test_commit H file5 &&
> - git checkout -b branch2 F &&
> - test_commit I file6 &&
> - git checkout -b conflict-branch A &&
> - test_commit one conflict &&
> - test_commit two conflict &&
> - test_commit three conflict &&
> - test_commit four conflict &&
> - git checkout -b no-conflict-branch A &&
> - test_commit J fileJ &&
> - test_commit K fileK &&
> - test_commit L fileL &&
> - test_commit M fileM &&
> - git checkout -b no-ff-branch A &&
> - test_commit N fileN &&
> - test_commit O fileO &&
> - test_commit P fileP
> + (
> + GIT_AUTHOR_NAME="Original Author" &&
> + GIT_AUTHOR_EMAIL="original.author@example.com" &&
> + test_commit A file1 &&
> + test_commit B file1 &&
> + test_commit C file2 &&
> + test_commit D file1 &&
> + test_commit E file3 &&
> + git checkout -b branch1 A &&
> + test_commit F file4 &&
> + test_commit G file1 &&
> + test_commit H file5 &&
> + git checkout -b branch2 F &&
> + test_commit I file6 &&
> + git checkout -b conflict-branch A &&
> + test_commit one conflict &&
> + test_commit two conflict &&
> + test_commit three conflict &&
> + test_commit four conflict &&
> + git checkout -b no-conflict-branch A &&
> + test_commit J fileJ &&
> + test_commit K fileK &&
> + test_commit L fileL &&
> + test_commit M fileM &&
> + git checkout -b no-ff-branch A &&
> + test_commit N fileN &&
> + test_commit O fileO &&
> + test_commit P fileP
> + )
> '
>
> # "exec" commands are run with the user shell by default, but this may
> @@ -252,12 +256,12 @@ test_expect_success 'stop on conflicting pick' '
> -A
> +G
> EOF
> - cat >expect2 <<-\EOF &&
> + cat >expect2 <<-EOF &&
> <<<<<<< HEAD
> D
> =======
> G
> - >>>>>>> 5d18e54... G
> + >>>>>>> $(git rev-parse --short HEAD)... G
> EOF
> git tag new-branch1 &&
> test_must_fail git rebase -i master &&
> @@ -1628,6 +1632,52 @@ test_expect_success 'correct error message for commit --amend after empty pick'
> test_i18ngrep "middle of a rebase -- cannot amend." err
> '
>
> +test_expect_success 'correct error message for partial commit after confilct' '
> + test_when_finished "git rebase --abort" &&
> + git checkout D &&
> + (
> + set_fake_editor &&
> + FAKE_LINES="2 3" &&
> + export FAKE_LINES &&
> + test_must_fail git rebase -i A
> + ) &&
> + echo x >file1 &&
> + echo y >file2 &&
> + git add file1 file2 &&
> + test_must_fail git commit file1 2>err &&
> + test_i18ngrep "cannot do a partial commit during a rebase." err
> +'
> +
> +test_expect_success 'correct error message for commit --amend after conflict' '
> + test_when_finished "git rebase --abort" &&
> + git checkout D &&
> + (
> + set_fake_editor &&
> + FAKE_LINES=3 &&
> + export FAKE_LINES &&
> + test_must_fail git rebase -i A
> + ) &&
> + echo x>file1 &&
> + test_must_fail git commit -a --amend 2>err &&
> + test_i18ngrep "middle of a rebase -- cannot amend." err
> +'
> +
> +test_expect_success 'correct authorship and message after conflict' '
> + git checkout D &&
> + (
> + set_fake_editor &&
> + FAKE_LINES=3 &&
> + export FAKE_LINES &&
> + test_must_fail git rebase -i A
> + ) &&
> + echo x >file1 &&
> + git commit -a &&
> + git log --pretty=format:"%an <%ae>%n%ad%n%B" -1 D >expect &&
> + git log --pretty=format:"%an <%ae>%n%ad%n%B" -1 HEAD >actual &&
> + test_cmp expect actual &&
> + git rebase --continue
> +'
> +
> # This must be the last test in this file
> test_expect_success '$EDITOR and friends are unchanged' '
> test_editor_unchanged
> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
> index c1eb72555d..2adceb35e2 100755
> --- a/t/t7512-status-help.sh
> +++ b/t/t7512-status-help.sh
> @@ -148,7 +148,6 @@ You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO
> (use "git rebase --abort" to check out the original branch)
>
> Unmerged paths:
> - (use "git reset HEAD <file>..." to unstage)
> (use "git add <file>..." to mark resolution)
>
> both modified: main.txt
> @@ -176,7 +175,6 @@ You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO
> (all conflicts fixed: run "git rebase --continue")
>
> Changes to be committed:
> - (use "git reset HEAD <file>..." to unstage)
>
> modified: main.txt
>
>