Re: [PATCH] revert.c: defer writing CHERRY_PICK_HEAD till it is safe to do so
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Oct 6, 2011, 17:02 UTC
- Message-ID
- <7vty7m12b2.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <1317911641-47660-1-git-send-email-jaysoffian@gmail.com>
Jay Soffian <jaysoffian@gmail.com> writes:
Show 10 quoted lines
> do_pick_commit() writes out CHERRY_PICK_HEAD before invoking merge (either > via do_recursive_merge() or try_merge_command()) on the assumption that if > the merge fails it is due to conflict. However, if the tree is dirty, the > merge may not even start, aborting before do_pick_commit() can remove > CHERRY_PICK_HEAD. > > Instead, defer writing CHERRY_PICK_HEAD till after merge has returned. > At this point we know the merge has either succeeded or failed due > to conflict. In either case, we want CHERRY_PICK_HEAD to be written > so that it may be picked up by the subsequent invocation of commit.
I think do_recursive_merge() would die() when the merge cannot even start (i.e. the local changes after the cherry-pick exits are the ones from the time before such a failed cherry-pick started), but I suspect that the other codepath uses try_merge_command() to drive strategies other than recursive and it does not die() there in such a case. Can you make sure this patch is sufficient in such a case as well?
Other than that I think this is better than the previous rounds.
Thanks.
Show 55 quoted lines
> Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
> ---
> builtin/revert.c | 6 +++++-
> t/t3507-cherry-pick-conflict.sh | 7 +++++++
> 2 files changed, 12 insertions(+), 1 deletions(-)
>
> diff --git a/builtin/revert.c b/builtin/revert.c
> index 3117776c2c..48526e1ef1 100644
> --- a/builtin/revert.c
> +++ b/builtin/revert.c
> @@ -384,6 +384,7 @@ static int do_pick_commit(void)
> char *defmsg = NULL;
> struct strbuf msgbuf = STRBUF_INIT;
> int res;
> + int record_cherry_pick_head = 0;
>
> if (no_commit) {
> /*
> @@ -477,7 +478,7 @@ static int do_pick_commit(void)
> strbuf_addstr(&msgbuf, ")\n");
> }
> if (!no_commit)
> - write_cherry_pick_head();
> + record_cherry_pick_head = 1;
> }
>
> if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) {
> @@ -498,6 +499,9 @@ static int do_pick_commit(void)
> free_commit_list(remotes);
> }
>
> + if (record_cherry_pick_head)
> + write_cherry_pick_head();
> +
> if (res) {
> error(action == REVERT
> ? _("could not revert %s... %s")
> diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
> index 212ec54aaf..29890bf5ac 100755
> --- a/t/t3507-cherry-pick-conflict.sh
> +++ b/t/t3507-cherry-pick-conflict.sh
> @@ -77,6 +77,13 @@ test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
> test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
> '
>
> +test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
> + pristine_detach initial &&
> + echo foo > foo &&
> + test_must_fail git cherry-pick base &&
> + test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
> +'
> +
> test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
> pristine_detach initial &&
> (