# Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits

8 messages from 2016-08-10 to 2016-08-18. Participants: Stephen Morton, Christian Couder, Remi Galan Alfonso, Johannes Schindelin, Junio C Hamano.
Thread: https://gitlist.dev/t/43045

## Stephen Morton, 2016-08-10 19:21

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <09d485df-7d14-97f8-9db9-e3db7512bd68@nokia.com>
URL: https://gitlist.dev/e/09d485df-7d14-97f8-9db9-e3db7512bd68%40nokia.com

```
On Mon, Aug 1, 2016 at 5:12 AM, Johannes Schindelin 
<Johannes.Schindelin@gmx.de> wrote:
> Hi Stephen,
>
> On Wed, 27 Jul  2016, Stephen Morton wrote:
>
>> On Wed, Jul  27, 2016 at 11:03 AM, Johannes Schindelin
>>  <Johannes.Schindelin@gmx.de> wrote:
>> >
>> > On Wed,  27 Jul 2016, Stephen Morton wrote:
>> >
>> >>  diff --git a/sequencer.c b/sequencer.c
>> >>  index cdfac82..ce06876 100644
>> >> ---  a/sequencer.c
>> >> +++  b/sequencer.c
>> >> @@  -176,7 +176,8 @@ static void print_advice(int show_hint, struct
>> >>  replay_opts *opts)
>> >>             else
>> >>                     advise(_("after resolving the conflicts, mark
>> >> the  corrected paths\n"
>> >>                              "with 'git add <paths>' or 'git rm <paths>'\n"
>> >> -                              "and commit the result with 'git commit'"));
>> >> +                              "then continue the %s with 'git %s
>> >>  --continue'\n"
>> >> +                              "or cancel the %s operation with 'git
>> >> %s  --abort'" ),  action_name(opts), action_name(opts),
>> >>  action_name(opts), action_name(opts));
>> >
>> > That is  an awful lot of repetition right there, with an added
>> >  inconsistency that the action is referred to by its name alone in the
>> >  "--continue" case, but with "operation" added in the "--abort" case.
>> >
>> > And  additionally, in the most common case (one commit to cherry-pick), the
>> > advice  now suggests a more complicated operation than necessary: a simply
>> > `git  commit` would be enough, then.
>> >
>> > Can't  we have a test whether this is the last of the commits to be
>> >  cherry-picked, and if so, have the simpler advice again?
>>
>> Ok, knowing  that I'm not on the last element of the sequencer is
>> beyond my  git code knowledge.
>
> Oh, my mistake:  I meant to say that this information could be easily
> provided by  `pick_commits()` if it passed it to `print_advice()` via
>  `do_pick_commit()`.
>
> Ciao,
> Johannes

Formatting on previous email was terrible, plus the diff wasn't 
performed against origin. Re-sending.

(Finally getting back to this.)

Something like the diff below, then Johannes?

(I intentionally print the '--continue' hint even in the case whereit's 
last of n commits that fails.)


Stephen

~/ws/extern/git (maint *%>) > git diff @{u}
diff --git a/sequencer.c b/sequencer.c
index c6362d6..e0071aa 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -154,7 +154,7 @@ static void free_message(struct commit *commit, 
struct commit_message *msg)
         unuse_commit_buffer(commit, msg->message);
  }

-static void print_advice(int show_hint, struct replay_opts *opts)
+static void print_advice(int show_hint, int multiple_commits, struct 
replay_opts *opts)
  {
         char *msg = getenv("GIT_CHERRY_PICK_HELP");

@@ -174,9 +174,14 @@ static void print_advice(int show_hint, struct 
replay_opts *opts)
                         advise(_("after resolving the conflicts, mark 
the corrected paths\n"
                                  "with 'git add <paths>' or 'git rm 
<paths>'"));
                 else
-                       advise(_("after resolving the conflicts, mark 
the corrected paths\n"
-                                "with 'git add <paths>' or 'git rm 
<paths>'\n"
-                                "and commit the result with 'git 
commit'"));
+                        if  (multiple_commits)
+                               advise(_("after resolving the conflicts, 
mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
+                                        "then continue with 'git %s 
--continue'\n"
+                                        "or cancel with 'git %s 
--abort'" ), action_name(opts), action_name(opts));
+                        else
+                                advise(_("after resolving the 
conflicts, mark the corrected paths\n"
+                                        "with 'git add <paths>' or 'git 
rm <paths>'\n"
+                                        "and commit the result with 
'git commit'"));
         }
  }

@@ -440,7 +445,7 @@ static int allow_empty(struct replay_opts *opts, 
struct commit *commit)
                 return 1;
  }

-static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
+static int do_pick_commit(struct commit *commit, struct replay_opts 
*opts, int multiple_commits)
  {
         unsigned char head[20];
         struct commit *base, *next, *parent;
@@ -595,7 +600,7 @@ static int do_pick_commit(struct commit *commit, 
struct replay_opts *opts)
                       : _("could not apply %s... %s"),
                       find_unique_abbrev(commit->object.oid.hash, 
DEFAULT_ABBREV),
                       msg.subject);
-               print_advice(res == 1, opts);
+               print_advice(res == 1, multiple_commits, opts);
                 rerere(opts->allow_rerere_auto);
                 goto leave;
         }
@@ -959,6 +964,7 @@ static int pick_commits(struct commit_list 
*todo_list, struct replay_opts *opts)
  {
         struct commit_list *cur;
         int res;
+    int multiple_commits = (todo_list->next) != NULL;

         setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
         if (opts->allow_ff)
@@ -968,7 +974,7 @@ static int pick_commits(struct commit_list 
*todo_list, struct replay_opts *opts)

         for (cur = todo_list; cur; cur = cur->next) {
                 save_todo(cur, opts);
-               res = do_pick_commit(cur->item, opts);
+               res = do_pick_commit(cur->item, opts, multiple_commits);
                 if (res)
                         return res;
         }
@@ -1016,7 +1022,7 @@ static int sequencer_continue(struct replay_opts 
*opts)
  static int single_pick(struct commit *cmit, struct replay_opts *opts)
  {
         setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
-       return do_pick_commit(cmit, opts);
+       return do_pick_commit(cmit, opts, 0);
  }

  int sequencer_pick_revisions(struct replay_opts *opts)



-- 
Stephen Morton, 7750 SR Product Group, SW Development Tools/DevOps
w: +1-613-784-6026 (int: 2-825-6026) m: +1-613-302-2589 | EST Time Zone


```

## Christian Couder, 2016-08-14 11:44

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <CAP8UFD04Z7JpoAA1kXkYFk5LD-GngbUDkbnpCEc3DNDXUgetEA@mail.gmail.com>
URL: https://gitlist.dev/e/CAP8UFD04Z7JpoAA1kXkYFk5LD-GngbUDkbnpCEc3DNDXUgetEA%40mail.gmail.com
In-Reply-To: <09d485df-7d14-97f8-9db9-e3db7512bd68@nokia.com>

```
Hi Stephen,

On Wed, Aug 10, 2016 at 9:21 PM, Stephen Morton
<stephen.morton@nokia.com> wrote:
>
> Formatting on previous email was terrible, plus the diff wasn't performed
> against origin. Re-sending.

Thanks for working on this...

> (Finally getting back to this.)
>
> Something like the diff below, then Johannes?

...but please try to send a real patch.

There is https://github.com/git/git/blob/master/Documentation/SubmittingPatches
and also SubmitGit that can help you do that.

> (I intentionally print the '--continue' hint even in the case whereit's last
> of n commits that fails.)
>
>
> Stephen
>
>
> ~/ws/extern/git (maint *%>) > git diff @{u}
> diff --git a/sequencer.c b/sequencer.c
> index c6362d6..e0071aa 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -154,7 +154,7 @@ static void free_message(struct commit *commit, struct
> commit_message *msg)
>         unuse_commit_buffer(commit, msg->message);
>  }
>
> -static void print_advice(int show_hint, struct replay_opts *opts)
> +static void print_advice(int show_hint, int multiple_commits, struct
> replay_opts *opts)

Here multiple_commits is not the last argument...

>  {
>         char *msg = getenv("GIT_CHERRY_PICK_HELP");
>
> @@ -174,9 +174,14 @@ static void print_advice(int show_hint, struct
> replay_opts *opts)
>                         advise(_("after resolving the conflicts, mark the
> corrected paths\n"
>                                  "with 'git add <paths>' or 'git rm
> <paths>'"));
>                 else
> -                       advise(_("after resolving the conflicts, mark the
> corrected paths\n"
> -                                "with 'git add <paths>' or 'git rm
> <paths>'\n"
> -                                "and commit the result with 'git
> commit'"));
> +                        if  (multiple_commits)
> +                               advise(_("after resolving the conflicts,
> mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
> +                                        "then continue with 'git %s
> --continue'\n"
> +                                        "or cancel with 'git %s --abort'"
> ), action_name(opts), action_name(opts));
> +                        else
> +                                advise(_("after resolving the conflicts,
> mark the corrected paths\n"
> +                                        "with 'git add <paths>' or 'git rm
> <paths>'\n"
> +                                        "and commit the result with 'git
> commit'"));
>         }
>  }
>
> @@ -440,7 +445,7 @@ static int allow_empty(struct replay_opts *opts, struct
> commit *commit)
>                 return 1;
>  }
>
> -static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
> +static int do_pick_commit(struct commit *commit, struct replay_opts *opts,
> int multiple_commits)

... but here multiple_commits is the last argument.
It would be better if it was more consistent.

>  {
>         unsigned char head[20];
>         struct commit *base, *next, *parent;
> @@ -595,7 +600,7 @@ static int do_pick_commit(struct commit *commit, struct
> replay_opts *opts)
>                       : _("could not apply %s... %s"),
>                       find_unique_abbrev(commit->object.oid.hash,
> DEFAULT_ABBREV),
>                       msg.subject);
> -               print_advice(res == 1, opts);
> +               print_advice(res == 1, multiple_commits, opts);
>                 rerere(opts->allow_rerere_auto);
>                 goto leave;
>         }
> @@ -959,6 +964,7 @@ static int pick_commits(struct commit_list *todo_list,
> struct replay_opts *opts)
>  {
>         struct commit_list *cur;
>         int res;
> +    int multiple_commits = (todo_list->next) != NULL;

Why not "last_commit" instead of "multiple_commits"?

Thanks,
Christian.

```

## Remi Galan Alfonso, 2016-08-16 08:44

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <968827697.1226723.1471337060482.JavaMail.zimbra@ensimag.grenoble-inp.fr>
URL: https://gitlist.dev/e/968827697.1226723.1471337060482.JavaMail.zimbra%40ensimag.grenoble-inp.fr
In-Reply-To: <09d485df-7d14-97f8-9db9-e3db7512bd68@nokia.com>

```
Hi Stephen,

Stephen Morton <stephen.morton@nokia.com> writes:
> +                        if  (multiple_commits)
> +                               advise(_("after resolving the conflicts,
> mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
> +                                        "then continue with 'git %s
> --continue'\n"
> +                                        "or cancel with 'git %s
> --abort'" ), action_name(opts), action_name(opts));
> +                        else
> +                                advise(_("after resolving the
> conflicts, mark the corrected paths\n"
> +                                        "with 'git add <paths>' or 'git
> rm <paths>'\n"
> +                                        "and commit the result with
> 'git commit'"));

In both cases (multiple_commits or not), the beginning of the advise
is nearly the same, with only a '\n' in the middle being the
difference:

multiple_commits:
 "after resolving the conflicts, mark the corrected paths with 'git
 add <paths>' or 'git rm <paths>'\n"

!multiple_commits:
 "after resolving the conflicts, mark the corrected paths\n with 'git
 add <paths>' or 'git rm <paths>'\n"
                                                  ~~~~~~~^

In 'multiple_commits' case the advise is more than 80 characters long,
did you forget the '\n' in that case?

If you end up using the same beginning of advice, maybe it's possible
to give it before the 'if(multiple_commits)' and avoid duplication of
the lines.

Thanks,
Rémi

```

## Johannes Schindelin, 2016-08-17 09:13

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <alpine.DEB.2.20.1608171112580.4924@virtualbox>
URL: https://gitlist.dev/e/alpine.DEB.2.20.1608171112580.4924%40virtualbox
In-Reply-To: <968827697.1226723.1471337060482.JavaMail.zimbra@ensimag.grenoble-inp.fr>

```
Hi,

On Tue, 16 Aug 2016, Remi Galan Alfonso wrote:

> Stephen Morton <stephen.morton@nokia.com> writes:
> > +                        if  (multiple_commits)
> > +                               advise(_("after resolving the conflicts,
> > mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
> > +                                        "then continue with 'git %s
> > --continue'\n"
> > +                                        "or cancel with 'git %s
> > --abort'" ), action_name(opts), action_name(opts));
> > +                        else
> > +                                advise(_("after resolving the
> > conflicts, mark the corrected paths\n"
> > +                                        "with 'git add <paths>' or 'git
> > rm <paths>'\n"
> > +                                        "and commit the result with
> > 'git commit'"));
> 
> In both cases (multiple_commits or not), the beginning of the advise
> is nearly the same, with only a '\n' in the middle being the
> difference:
> 
> multiple_commits:
>  "after resolving the conflicts, mark the corrected paths with 'git
>  add <paths>' or 'git rm <paths>'\n"
> 
> !multiple_commits:
>  "after resolving the conflicts, mark the corrected paths\n with 'git
>  add <paths>' or 'git rm <paths>'\n"
>                                                   ~~~~~~~^
> 
> In 'multiple_commits' case the advise is more than 80 characters long,
> did you forget the '\n' in that case?
> 
> If you end up using the same beginning of advice, maybe it's possible
> to give it before the 'if(multiple_commits)' and avoid duplication of
> the lines.

I concur with this, and also with Christian's advice to append the
parameter consistently as last one, and also with renaming it to
"last_commit".

Ciao,
Johannes

```

## Stephen Morton, 2016-08-17 13:42

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <f58933df-352a-9d2b-a35a-9c48cb2d958e@nokia.com>
URL: https://gitlist.dev/e/f58933df-352a-9d2b-a35a-9c48cb2d958e%40nokia.com
In-Reply-To: <CAP8UFD04Z7JpoAA1kXkYFk5LD-GngbUDkbnpCEc3DNDXUgetEA@mail.gmail.com>

```
Responding to a few comments...

On 2016-08-14 7:44 AM, Christian Couder wrote:
> multiple_commits)
> ... but here multiple_commits is the last argument.
> It would be better if it was more consistent.
(Johannes made the same comment.)
Yes. Will do.


>
> multiple_commits = (todo_list->next) != NULL;
> Why not "last_commit" instead of "multiple_commits"?
>

Because it *isn't*. You can see that in pick_commits(), I set 
multiple_commits outside of the `for todo_list` loop. It is not 
re-evaluated at every iteration of the loop. As per my comment when 
emailing the patch "I intentionally print the '--continue' hint even in 
the case where it's last of n commits that fails. " I think it makes 
much more sense that "this is the message you always get when 
cherry-picking multiple commits as opposed to "this is the message you 
sometimes get, except when it's the last one". (Yes, the careful 
observer will realize that if when cherry-picking multiple commits, 
there are conflicts in the second-last and last then the --continue  
from the second-last will result in multiple_commits being set to 0. I 
can live with that.)


On 2016-08-16 4:44 AM, Remi Galan Alfonso wrote:
> Hi Stephen,
>
> Stephen Morton <stephen.morton@nokia.com> writes:
>> +                        if  (multiple_commits)
>> +                               advise(_("after resolving the conflicts,
>> mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
>> +                                        "then continue with 'git %s
>> --continue'\n"
>> +                                        "or cancel with 'git %s
>> --abort'" ), action_name(opts), action_name(opts));
>> +                        else
>> +                                advise(_("after resolving the
>> conflicts, mark the corrected paths\n"
>> +                                        "with 'git add <paths>' or 'git
>> rm <paths>'\n"
>> +                                        "and commit the result with
>> 'git commit'"));
> In both cases (multiple_commits or not), the beginning of the advise
> is nearly the same, with only a '\n' in the middle being the
> difference:
>
> multiple_commits:
>   "after resolving the conflicts, mark the corrected paths with 'git
>   add <paths>' or 'git rm <paths>'\n"
>
> !multiple_commits:
>   "after resolving the conflicts, mark the corrected paths\n with 'git
>   add <paths>' or 'git rm <paths>'\n"
>                                                    ~~~~~~~^
>
> In 'multiple_commits' case the advise is more than 80 characters long,
> did you forget the '\n' in that case?
A previous comment had indicated that having 4 lines was too many. And I 
tend to agree. So I tried to squash it into 3. Back in xterm days, 80 
characters was sacrosanct, but is it really a big deal to exceed it now?


On 2016-08-14 7:44 AM, Christian Couder wrote:
> ...but please try to send a real patch.
>
> There is https://github.com/git/git/blob/master/Documentation/SubmittingPatches
> and also SubmitGit that can help you do that.
Agreed. I just want to send a patch that stands a reasonable chance of 
getting accepted.

Stephen


-- 
Stephen Morton, 7750 SR Product Group, SW Development Tools/DevOps
w: +1-613-784-6026 (int: 2-825-6026) m: +1-613-302-2589 | EST Time Zone


```

## Remi Galan Alfonso, 2016-08-17 14:24

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <1592315356.1230893.1471443850115.JavaMail.zimbra@ensimag.grenoble-inp.fr>
URL: https://gitlist.dev/e/1592315356.1230893.1471443850115.JavaMail.zimbra%40ensimag.grenoble-inp.fr
In-Reply-To: <f58933df-352a-9d2b-a35a-9c48cb2d958e@nokia.com>

```
Stephen Morton <stephen.morton@nokia.com> writes:
> [snip]
> On 2016-08-16 4:44 AM, Remi Galan Alfonso wrote:
>> Hi Stephen,
>>
>> Stephen Morton <stephen.morton@nokia.com> writes:
>>> +                        if  (multiple_commits)
>>> +                               advise(_("after resolving the conflicts,
>>> mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
>>> +                                        "then continue with 'git %s
>>> --continue'\n"
>>> +                                        "or cancel with 'git %s
>>> --abort'" ), action_name(opts), action_name(opts));
>>> +                        else
>>> +                                advise(_("after resolving the
>>> conflicts, mark the corrected paths\n"
>>> +                                        "with 'git add <paths>' or 'git
>>> rm <paths>'\n"
>>> +                                        "and commit the result with
>>> 'git commit'"));
>> In both cases (multiple_commits or not), the beginning of the advise
>> is nearly the same, with only a '\n' in the middle being the
>> difference:
>>
>> multiple_commits:
>>   "after resolving the conflicts, mark the corrected paths with 'git
>>   add <paths>' or 'git rm <paths>'\n"
>>
>> !multiple_commits:
>>   "after resolving the conflicts, mark the corrected paths\n with 'git
>>   add <paths>' or 'git rm <paths>'\n"
>>                                                    ~~~~~~~^
>>
>> In 'multiple_commits' case the advise is more than 80 characters long,
>> did you forget the '\n' in that case?
> A previous comment had indicated that having 4 lines was too many. And I
> tend to agree. So I tried to squash it into 3. Back in xterm days, 80
> characters was sacrosanct, but is it really a big deal to exceed it now?

Either way (3 or 4 lines) I find it strange to have both advices
start in the same way except that one is split and not the other.

I cannot tell if it's a big deal or not to exceed 80 characters
but FWIW most of my stuff (terminal and emacs) is 80 columns
long, and I haven't known the "xterm days".

Thanks,
Rémi

```

## Junio C Hamano, 2016-08-17 15:31

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <xmqqa8gbbee8.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqqa8gbbee8.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <1592315356.1230893.1471443850115.JavaMail.zimbra@ensimag.grenoble-inp.fr>

```
Remi Galan Alfonso <remi.galan-alfonso@ensimag.grenoble-inp.fr>
writes:

> Either way (3 or 4 lines) I find it strange to have both advices
> start in the same way except that one is split and not the other.

True.

```

## Johannes Schindelin, 2016-08-18 14:15

Subject: Re: git cherry-pick conflict error message is deceptive when cherry-picking multiple commits
Message-ID: <alpine.DEB.2.20.1608181612340.4924@virtualbox>
URL: https://gitlist.dev/e/alpine.DEB.2.20.1608181612340.4924%40virtualbox
In-Reply-To: <f58933df-352a-9d2b-a35a-9c48cb2d958e@nokia.com>

```
Hi Stephen,

On Wed, 17 Aug 2016, Stephen Morton wrote:

> > multiple_commits = (todo_list->next) != NULL;
> > Why not "last_commit" instead of "multiple_commits"?
> 
> Because it *isn't*.

Personally, I do prefer to have the simpler instruction if the commit
happens to be the last one cherry-picked.

I do not follow your argument that it makes sense to decide based on the
total number of commits that were to be cherry-picked whether to use the
more cumbersome or the easier command.

Instead, I think the user should be given the simplest advice that gets
them out of the fix most quickly. And if `git commit --amend` is good
enough, we should not advise to use `git cherry-pick --continue`, and that
is that.

Ciao,
Johannes

```
