All of lore.kernel.org
 help / color / mirror / Atom feed
From: ZheNing Hu <adlternative@gmail.com>
To: Elijah Newren <newren@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
	Christian Couder <christian.couder@gmail.com>,
	Git List <git@vger.kernel.org>,
	vascomalmeida@sapo.pt
Subject: Re: Question about pre-merge and git merge octopus strategy
Date: Thu, 19 May 2022 21:15:19 +0800	[thread overview]
Message-ID: <CAOLTT8TDomk9zUg49yrhpu1T776FKrnu7RGJ_bx9iaYKUEvvTg@mail.gmail.com> (raw)
In-Reply-To: <CABPp-BGOGLUPOn20yWzCrBYCykiet0=5UfbkuGC78f-QoWVvYg@mail.gmail.com>

Elijah Newren <newren@gmail.com> 于2022年5月13日周五 13:16写道:
>
> On Thu, May 12, 2022 at 8:39 AM Junio C Hamano <gitster@pobox.com> wrote:
> >
> > Elijah Newren <newren@gmail.com> writes:
> >
> > >     Merge with strategy octopus failed.
> > >
> > > Also, if we check `git status`:
> > >
> > >     $ git status
> > >     On branch main
> > >     Unmerged paths:
> > >       (use "git restore --staged <file>..." to unstage)
> > >       (use "git add <file>..." to mark resolution)
> > >     both modified:   base
> > >
> > >     no changes added to commit (use "git add" and/or "git commit -a")
> > >
> > > And in git-merge-octopus.sh we see:
> > >
> > >     case "$OCTOPUS_FAILURE" in
> > >     1)
> > >     # We allow only last one to have a hand-resolvable
> > >     # conflicts.  Last round failed and we still had
> > >     # a head to merge.
> > >     gettextln "Automated merge did not work."
> > >     gettextln "Should not be doing an octopus."
> > >     exit 2
> > >     esac
> > >
> > > and in builtin/merge.c, we see:
> > >
> > >     /*
> > >      * The backend exits with 1 when conflicts are
> > >      * left to be resolved, with 2 when it does not
> > >      * handle the given merge at all.
> > >      */
> > >
> > > Which means git-merge-octopus.sh is claiming it can't handle this type
> > > of merge, and some other merge strategy should be tried, and
> > > implicitly that it didn't leave any conflicts to be resolved because
> > > it can't handle this merge.
> >
> > Correct.  Near the beginning of the loop you found the above
> > comment, there is this code:
> >
> >         if (use_strategies_nr == 1 ||
> >             /*
> >              * Stash away the local changes so that we can try more than one.
> >              */
> >             save_state(&stash))
> >                 oidclr(&stash);
> >
> >         for (i = 0; !merge_was_ok && i < use_strategies_nr; i++) {
> >                 int ret, cnt;
> >                 if (i) {
> >                         printf(_("Rewinding the tree to pristine...\n"));
> >                         restore_state(&head_commit->object.oid, &stash);
> >                 }
>
> Side-comment, which becomes important below: The save/restore code in
> builtin/merge.c appears to be broken to me.  As noted in the code
> above, stash will be set to null_oid() if save_state() returns
> non-zero (which happens when "stash create" has no output, which
> happens if there is _initially_ no state to save, i.e. if there are no
> local changes before the merge started).  restore_state() is a no-op
> whenever stash is the null_oid, meaning in that case it won't actually
> rewind the tree to a pristine state to undo the changes of the
> previous merge attempt.  So, if:
>
> * The user had no local changes before starting the merge
> * Multiple merge strategies are applicable
> * The first merge strategy makes index/working-tree changes, but
> returns with exit status 2
>
> Then the restore_state() called before the second merge strategy will
> do nothing, and the second merge strategy will be working on an index
> and working tree with garbage leftover from the first merge strategy.
> While this may have never been triggered (in what case do we have
> multiple merge strategies that all return an exit status of 2?), I
> suspect we want to fix this problem with something like this:
>
> diff --git a/builtin/merge.c b/builtin/merge.c
> index f178f5a3ee..7f3650fb09 100644
> --- a/builtin/merge.c
> +++ b/builtin/merge.c
> @@ -378,11 +378,11 @@ static void restore_state(const struct object_id *head,
>         struct strbuf sb = STRBUF_INIT;
>         const char *args[] = { "stash", "apply", NULL, NULL };
>
> +       reset_hard(head, 1);
> +
>         if (is_null_oid(stash))
>                 return;
>
> -       reset_hard(head, 1);
> -
>         args[2] = oid_to_hex(stash);
>
>         /*
>

It looks like this code can go back to the old state now?

I think if we can handle it as special case when:

1. Use octopus merge without other strategies (no friend).
2. Merge failed, so we don't have the best strategy.

Then we force restore the original state?

  parent reply	other threads:[~2022-05-19 13:15 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-06  8:14 Question about pre-merge and git merge octopus strategy ZheNing Hu
2022-05-06 17:23 ` Christian Couder
2022-05-07  4:09   ` Elijah Newren
2022-05-07 18:37     ` Junio C Hamano
2022-05-08 14:44     ` ZheNing Hu
2022-05-10  7:07       ` Elijah Newren
2022-05-11 11:21         ` ZheNing Hu
2022-05-12 15:04           ` Elijah Newren
2022-05-12 15:39             ` Junio C Hamano
2022-05-13  5:15               ` Elijah Newren
2022-05-13 12:56                 ` Junio C Hamano
2022-05-19 13:15                 ` ZheNing Hu [this message]
2022-05-19 14:46                   ` Elijah Newren
2022-05-08 14:13   ` ZheNing Hu
2022-05-08 15:01 ` Carlo Marcelo Arenas Belón

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=CAOLTT8TDomk9zUg49yrhpu1T776FKrnu7RGJ_bx9iaYKUEvvTg@mail.gmail.com \
    --to=adlternative@gmail.com \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=newren@gmail.com \
    --cc=vascomalmeida@sapo.pt \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.