git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v6] submodule merge: update conflict error message

From
Calvin Wan <calvinwan@google.com>
Date
Jul 27, 2022, 22:00 UTC
Message-ID
<CAFySSZB6bB0qqCv5EPmJBJY9RbDRFv8JDYj89W+ND_Jw6Ys1kA@mail.gmail.com>
In-Reply-To
<CABPp-BGvDLvmj720PFzsjrZrYuYauprL6JeOQhiQ4BjtfjF7Dg@mail.gmail.com>
Show 6 quoted lines
> Well explained.  One very minor suggestion: perhaps change "id of the
> commit" to "id of the submodule commit" just to make it slightly
> clearer that this information would take work for the user to discover
> on their own?  (When I first read it, I was thinking, "but they have
> the commit, it's what they passed to merge", before I realized my
> error.)
ack
Show 5 quoted lines
> Sorry for not catching this in an earlier round, but merge_submodule()
> has four "return 0" cases, for particular types of conflicts.  Those
> should probably be switched to "goto cleanup" or something like that,
> so that these messages you are adding are also provided if one of
> those conflict cases are hit.

I didn't send these four "return 0" cases to cleanup because I thought the error message wouldn't accurately reflect the resolution steps. Is merging or updating the submodule still the correct resolution? The first three cases are for a null o/a/b, and the fourth case is for a missing local submodule. Also in cleanup, the subrepo is cleared but the subrepo hasn't been initialized/failed to initialize in these four cases.

Show 17 quoted lines
> >         object_array_clear(&merges);
> >  cleanup:
> > +       if (!ret) {
>
> And here's another item I have to apologize for not catching in an
> earlier round.  We should also require !opt->priv->call_depth as well
> in this if-condition.  If merging of merge bases produced a submodule
> conflict, but the outer merge involves two sides that resolved the
> inner conflict the exact same way, then there's no conflict at the
> outer level and nothing for the user to resolve.  If users don't have
> any conflicts to resolve, we don't want to print messages telling them
> how to resolve their non-existent conflicts.  And if there is still a
> conflict in the submodule for the outer merge as well as in the
> recursive merge(s), we don't want to list the module twice (or more)
> when we tell the user to fix conflicts in their submodules (especially
> since that means we'd be telling them to merge multiple different
> commits for the single submodule, which could get confusing).
ack.
> > +               for_each_string_list_item(item, csub) {
> > +            const char *abbrev= item->util;
>
> Messed up indent here?

Looks like going from my editor to `git format-patch` messed something up here.

Show 11 quoted lines
> > +               for_each_string_list_item(item, csub)
> > +                       /*
> > +                        * TRANSLATORS: This is a line of a recommended `git add` command
> > +                        * with multiple lines of submodule folders.
> > +                        * E.g.:     git add sub \
> > +                        *                   sub2 \
> > +                        *                   sub3
>
> Why does such a message need to be translated?  It's literal text the
> user should type, right?  I'm not sure what a translator would do with
> the message other than regurgitate it.

It doesn't. My point was to let the translator know that the only text in this print is for a git command. I should probably add that context to the comment though.

Show 6 quoted lines
> > +                        */
> > +                       if (first) {
> > +                               printf("       git add %s", item->string);
>
> But if you did mean for there to be a translation and a TRANSLATORS
> note, then did you forget to translate it by calling _()?
Same reasoning as above.
Show 21 quoted lines
> > +                               first = 0;
> > +                       } else {
> > +                               printf(" \\\n               %s", item->string);
> > +                       }
>
> Can we put braces around this for_each_string_list_item() block?  Or,
> as an alternative to the whole block, do you want to consider:
>
>    strub strbuf tmp = STRBUF_INIT;
>    strbuf_add_separated_string_list(&tmp, ' ', csub);
>    printf(_("    git add %s"), tmp.buf);   /* or maybe remove the
> translation; not sure what the point is */
>    strbuf_release(&tmp);
> ?  It is likely easier to copy & paste, and might be understood by
> more users (I'm not sure how many are aware that command lines can use
> backslashes for line continuation), but on the negative side, if you
> have a lot of submodules it might make it harder to read.  Even if you
> don't like space separated, though, you could still use this strategy
> by changing the second line to
>
>     strbuf_add_separated_string_list(&tmp, " \\\n               ", csub);

This is a much cleaner implementation, thanks! If my goal is to make submodule merging easier for newer submodule users, then I think it's a good assumption to remove any additional possible points of confusion, aka with the "command lines can use backslashes for line continuation", so I'll swap over to spaces.

Show 9 quoted lines
> > +       print_submodule_conflict_suggestion(&opti->conflicted_submodules);
> > +       string_list_clear(&opti->conflicted_submodules, 1);
> > +
>
> It would be more consistent to have things allocated in merge_start()
> continue to be cleared out in clear_or_reinit_internal_opts().  This
> kind of breaks that pairing, and you're already making sure to clear
> it there, so I'd rather remove this duplicate string_list_clear()
> call.
ack.
Show 23 quoted lines
> >         /* Also include needed rename limit adjustment now */
> >         diff_warn_rename_limit("merge.renamelimit",
> >                                opti->renames.needed_limit, 0);
> > @@ -4657,6 +4717,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
> >         trace2_region_enter("merge", "allocate/init", opt->repo);
> >         if (opt->priv) {
> >                 clear_or_reinit_internal_opts(opt->priv, 1);
> > +               string_list_init_dup(&opt->priv->conflicted_submodules);
>
> This works, but there is a minor optimization available here if you're
> interested (I understand if you're not since you're already at v6).
> Assuming you make the important opt->priv->call_depth fix, you can
> replace string_list_init_dup() with string_list_init_nodup() here.
> The paths aren't freed until clear_or_reinit_internal_opts() which
> (under the assumption previously stated) isn't called until
> merge_finalize(), which comes after the call to
> merge_display_update_messages(), which is where you use the data.
>
> (As repository paths are used all over merge-ort.c, the optimization
> to store them in one place (opt->priv->paths) and avoid duplicating
> them is used pretty heavily.  It's more important for a lot of the
> other strmaps since they'll have a lot more paths in them, but it is
> kind of nice to use this optimization where possible.)

Thanks for all the context of this one. I agree it's minor, but any place we can provide a better example to future contributors seems like a more than worthy reason to make this change :)

Previous: Elijah NewrenNext: Elijah Newren
Message 42 of 60 in “submodule merge: update conflict error message”
  1. submodule merge: update conflict error messageCalvin Wan, Jun 6, 2022
  2. Junio C HamanoJun 7, 2022
  3. Calvin WanJun 8, 2022
  4. Glen ChooJun 8, 2022
  5. Calvin WanJun 8, 2022
  6. Junio C HamanoJun 8, 2022
  7. submodule merge: update conflict error messageCalvin Wan, Jun 10, 2022
  8. Elijah NewrenJun 11, 2022
  9. Philippe BlainJun 11, 2022
  10. Elijah NewrenJun 12, 2022
  11. Calvin WanJun 13, 2022
  12. Junio C HamanoJun 12, 2022
  13. Calvin WanJun 13, 2022
  14. submodule merge: update conflict error messageCalvin Wan, Jun 29, 2022
  15. Elijah NewrenJun 30, 2022
  16. Calvin WanJun 30, 2022
  17. Elijah NewrenJul 1, 2022
  18. Glen ChooJun 30, 2022
  19. Glen ChooJun 30, 2022
  20. Calvin WanJun 30, 2022
  21. submodule merge: update conflict error messageCalvin Wan, Jul 12, 2022
  22. Junio C HamanoJul 13, 2022
  23. Elijah NewrenJul 17, 2022
  24. Johannes SchindelinJul 15, 2022
  25. Junio C HamanoJul 16, 2022
  26. Elijah NewrenJul 17, 2022
  27. Calvin WanJul 18, 2022
  28. submodule merge: update conflict error messageCalvin Wan, Jul 18, 2022
  29. Junio C HamanoJul 19, 2022
  30. Calvin WanJul 19, 2022
  31. Junio C HamanoJul 19, 2022
  32. Junio C HamanoJul 19, 2022
  33. Calvin WanJul 19, 2022
  34. Junio C HamanoJul 19, 2022
  35. Ævar Arnfjörð BjarmasonJul 25, 2022
  36. Ævar Arnfjörð BjarmasonJul 25, 2022
  37. Calvin WanJul 25, 2022
  38. Ævar Arnfjörð BjarmasonJul 25, 2022
  39. Calvin WanJul 25, 2022
  40. submodule merge: update conflict error messageCalvin Wan, Jul 26, 2022
  41. Elijah NewrenJul 27, 2022
  42. Calvin WanJul 27, 2022
  43. Elijah NewrenJul 28, 2022
  44. Calvin WanJul 28, 2022
  45. Ævar Arnfjörð BjarmasonJul 27, 2022
  46. submodule merge: update conflict error messageCalvin Wan, Jul 28, 2022
  47. Ævar Arnfjörð BjarmasonJul 28, 2022
  48. Elijah NewrenJul 29, 2022
  49. Calvin WanAug 1, 2022
  50. Ævar Arnfjörð BjarmasonAug 1, 2022
  51. Junio C HamanoAug 2, 2022
  52. Calvin WanAug 2, 2022
  53. Junio C HamanoAug 2, 2022
  54. Calvin WanAug 2, 2022
  55. Junio C HamanoAug 2, 2022
  56. submodule merge: update conflict error messageCalvin Wan, Aug 4, 2022
  57. Junio C HamanoAug 16, 2022
  58. Junio C HamanoAug 16, 2022
  59. Calvin WanAug 16, 2022
  60. Junio C HamanoAug 16, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.