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

Re: [PATCH v2 08/11] merge-ort: add implementation of rename collisions

From
Elijah Newren <newren@gmail.com>
Date
Dec 15, 2020, 16:56 UTC
Message-ID
<CABPp-BHiwFgTT+y35WEo3v44y6Ypo49di1P6+6A9DaLMTFK7yg@mail.gmail.com>
In-Reply-To
<48fc65a5-12ba-be67-2908-27a446b1f813@gmail.com>
On Tue, Dec 15, 2020 at 6:09 AM Derrick Stolee <stolee@gmail.com> wrote:
Show 74 quoted lines
>
> On 12/14/2020 11:21 AM, Elijah Newren via GitGitGadget wrote:
> > From: Elijah Newren <newren@gmail.com>
> >
> > Implement rename/rename(2to1) and rename/add handling, i.e. a file is
> > renamed into a location where another file is added (with that other
> > file either being a plain add or itself coming from a rename).  Note
> > that rename collisions can also have a special case stacked on top: the
> > file being renamed on one side of history is deleted on the other
> > (yielding either a rename/add/delete conflict or perhaps a
> > rename/rename(2to1)/delete[/delete]) conflict.
> >
> > One thing to note here is that when there is a double rename, the code
> > in question only handles one of them at a time; a later iteration
> > through the loop will handle the other.  After they've both been
> > handled, process_entry()'s normal add/add code can handle the collision.
> >
> > This code replaces the following from merge-recurisve.c:
> >
> >   * all the 2to1 code in process_renames()
> >   * the RENAME_TWO_FILES_TO_ONE case of process_entry()
> >   * handle_rename_rename_2to1()
> >   * handle_rename_add()
> >
> > Also, there is some shared code from merge-recursive.c for multiple
> > different rename cases which we will no longer need for this case (or
> > other rename cases):
> >
> >   * handle_file_collision()
> >   * setup_rename_conflict_info()
> >
> > The consolidation of six separate codepaths into one is made possible
> > by a change in design: process_renames() tweaks the conflict_info
> > entries within opt->priv->paths such that process_entry() can then
> > handle all the non-rename conflict types (directory/file, modify/delete,
> > etc.) orthogonally.  This means we're much less likely to miss special
> > implementation of some kind of combination of conflict types (see
> > commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'",
> > 2020-11-18), especially commit ef52778708 ("merge tests: expect improved
> > directory/file conflict handling in ort", 2020-10-26) for more details).
> > That, together with letting worktree/index updating be handled
> > orthogonally in the merge_switch_to_result() function, dramatically
> > simplifies the code for various special rename cases.
>
> I'm really happy that you broke out the cases earlier, and describe
> them so well in the message. It makes this hunk of code really easy
> to understand:
>
> > +                     const char *pathnames[3];
> > +                     struct version_info merged;
> > +
> > +                     struct conflict_info *base, *side1, *side2;
> > +                     unsigned clean;
> > +
> > +                     pathnames[0] = oldpath;
> > +                     pathnames[other_source_index] = oldpath;
> > +                     pathnames[target_index] = newpath;
> > +
> > +                     base = strmap_get(&opt->priv->paths, pathnames[0]);
> > +                     side1 = strmap_get(&opt->priv->paths, pathnames[1]);
> > +                     side2 = strmap_get(&opt->priv->paths, pathnames[2]);
> > +
> > +                     VERIFY_CI(base);
> > +                     VERIFY_CI(side1);
> > +                     VERIFY_CI(side2);
> > +
> > +                     clean = handle_content_merge(opt, pair->one->path,
> > +                                                  &base->stages[0],
> > +                                                  &side1->stages[1],
> > +                                                  &side2->stages[2],
> > +                                                  pathnames,
> > +                                                  1 + 2*opt->priv->call_depth,
>
> nit: " * "
Will fix.
Show 38 quoted lines
> > +                                                  &merged);
> > +
> > +                     memcpy(&newinfo->stages[target_index], &merged,
> > +                            sizeof(merged));
> > +                     if (!clean) {
> > +                             path_msg(opt, newpath, 0,
> > +                                      _("CONFLICT (rename involved in "
> > +                                        "collision): rename of %s -> %s has "
> > +                                        "content conflicts AND collides "
> > +                                        "with another path; this may result "
> > +                                        "in nested conflict markers."),
> > +                                      oldpath, newpath);
>
> I was briefly taken aback by "AND collides with another path" wondering if
> that wording helps users understand the type of conflict here. But I can't
> think of anything better, so *shrug*.
>
> > +                     }
> >               } else if (collision && source_deleted) {
> > -                     /* rename/add/delete or rename/rename(2to1)/delete */
> > -                     die("Not yet implemented");
> > +                     /*
> > +                      * rename/add/delete or rename/rename(2to1)/delete:
> > +                      * since oldpath was deleted on the side that didn't
> > +                      * do the rename, there's not much of a content merge
> > +                      * we can do for the rename.  oldinfo->merged.is_null
> > +                      * was already set, so we just leave things as-is so
> > +                      * they look like an add/add conflict.
> > +                      */
> > +
> > +                     newinfo->path_conflict = 1;
> > +                     path_msg(opt, newpath, 0,
> > +                              _("CONFLICT (rename/delete): %s renamed "
> > +                                "to %s in %s, but deleted in %s."),
> > +                              oldpath, newpath, rename_branch, delete_branch);
>
> I think this branch is added in the wrong patch. My compiler is complaining
> that 'rename_branch' and 'delete_branch' are not declared (yet).

Whoops. This used to be separate patches, with the second half coming after one of the later patches in the series. But in the commit message seemed most natural to talk about "rename collisions" which then means both types of conflicts here. So I squashed them...and broke the build. I'll rearrange this one to come after the rename/delete patch so that rename_branch and delete_branch will be defined.

Previous: Derrick StoleeNext: Elijah Newren via GitGitGadget
Message 39 of 65 in “merge-ort: add basic rename detection”
  1. 00/11 merge-ort: add basic rename detectionElijah Newren via GitGitGadget, Dec 9, 2020
  2. 04/11 merge-ort: implement compare_pairs() and collect_renames()Elijah Newren via GitGitGadget, Dec 9, 2020
  3. Derrick StoleeDec 11, 2020
  4. Elijah NewrenDec 11, 2020
  5. 03/11 merge-ort: implement detect_regular_renames()Elijah Newren via GitGitGadget, Dec 9, 2020
  6. Derrick StoleeDec 11, 2020
  7. Elijah NewrenDec 11, 2020
  8. 02/11 merge-ort: add initial outline for basic rename detectionElijah Newren via GitGitGadget, Dec 9, 2020
  9. Derrick StoleeDec 11, 2020
  10. Elijah NewrenDec 11, 2020
  11. Elijah NewrenDec 13, 2020
  12. Derrick StoleeDec 14, 2020
  13. Johannes SchindelinDec 14, 2020
  14. Elijah NewrenDec 14, 2020
  15. Johannes SchindelinDec 14, 2020
  16. Elijah NewrenDec 14, 2020
  17. 05/11 merge-ort: add basic outline for process_renames()Elijah Newren via GitGitGadget, Dec 9, 2020
  18. Derrick StoleeDec 11, 2020
  19. Elijah NewrenDec 11, 2020
  20. 06/11 merge-ort: add implementation of both sides renaming identicallyElijah Newren via GitGitGadget, Dec 9, 2020
  21. Derrick StoleeDec 11, 2020
  22. 10/11 merge-ort: add implementation of normal rename handlingElijah Newren via GitGitGadget, Dec 9, 2020
  23. 09/11 merge-ort: add implementation of rename/delete conflictsElijah Newren via GitGitGadget, Dec 9, 2020
  24. 01/11 merge-ort: add basic data structures for handling renamesElijah Newren via GitGitGadget, Dec 9, 2020
  25. Derrick StoleeDec 11, 2020
  26. Elijah NewrenDec 11, 2020
  27. 08/11 merge-ort: add implementation of rename collisionsElijah Newren via GitGitGadget, Dec 9, 2020
  28. 11/11 merge-ort: add implementation of type-changed rename handlingElijah Newren via GitGitGadget, Dec 9, 2020
  29. 07/11 merge-ort: add implementation of both sides renaming differentlyElijah Newren via GitGitGadget, Dec 9, 2020
  30. Derrick StoleeDec 11, 2020
  31. Elijah NewrenDec 11, 2020
  32. 00/11 merge-ort: add basic rename detectionElijah Newren via GitGitGadget, Dec 14, 2020
  33. 01/11 merge-ort: add basic data structures for handling renamesElijah Newren via GitGitGadget, Dec 14, 2020
  34. 03/11 merge-ort: implement detect_regular_renames()Elijah Newren via GitGitGadget, Dec 14, 2020
  35. 02/11 merge-ort: add initial outline for basic rename detectionElijah Newren via GitGitGadget, Dec 14, 2020
  36. 04/11 merge-ort: implement compare_pairs() and collect_renames()Elijah Newren via GitGitGadget, Dec 14, 2020
  37. 08/11 merge-ort: add implementation of rename collisionsElijah Newren via GitGitGadget, Dec 14, 2020
  38. Derrick StoleeDec 15, 2020
  39. Elijah NewrenDec 15, 2020
  40. 10/11 merge-ort: add implementation of normal rename handlingElijah Newren via GitGitGadget, Dec 14, 2020
  41. Derrick StoleeDec 15, 2020
  42. 06/11 merge-ort: add implementation of both sides renaming identicallyElijah Newren via GitGitGadget, Dec 14, 2020
  43. 05/11 merge-ort: add basic outline for process_renames()Elijah Newren via GitGitGadget, Dec 14, 2020
  44. 09/11 merge-ort: add implementation of rename/delete conflictsElijah Newren via GitGitGadget, Dec 14, 2020
  45. Derrick StoleeDec 15, 2020
  46. Elijah NewrenDec 15, 2020
  47. Derrick StoleeDec 15, 2020
  48. 11/11 merge-ort: add implementation of type-changed rename handlingElijah Newren via GitGitGadget, Dec 14, 2020
  49. Derrick StoleeDec 15, 2020
  50. Elijah NewrenDec 15, 2020
  51. 07/11 merge-ort: add implementation of both sides renaming differentlyElijah Newren via GitGitGadget, Dec 14, 2020
  52. Derrick StoleeDec 15, 2020
  53. Junio C HamanoDec 15, 2020
  54. 00/11 merge-ort: add basic rename detectionElijah Newren via GitGitGadget, Dec 15, 2020
  55. 01/11 merge-ort: add basic data structures for handling renamesElijah Newren via GitGitGadget, Dec 15, 2020
  56. 02/11 merge-ort: add initial outline for basic rename detectionElijah Newren via GitGitGadget, Dec 15, 2020
  57. 03/11 merge-ort: implement detect_regular_renames()Elijah Newren via GitGitGadget, Dec 15, 2020
  58. 05/11 merge-ort: add basic outline for process_renames()Elijah Newren via GitGitGadget, Dec 15, 2020
  59. 04/11 merge-ort: implement compare_pairs() and collect_renames()Elijah Newren via GitGitGadget, Dec 15, 2020
  60. 11/11 merge-ort: add implementation of type-changed rename handlingElijah Newren via GitGitGadget, Dec 15, 2020
  61. 10/11 merge-ort: add implementation of normal rename handlingElijah Newren via GitGitGadget, Dec 15, 2020
  62. 09/11 merge-ort: add implementation of rename collisionsElijah Newren via GitGitGadget, Dec 15, 2020
  63. 07/11 merge-ort: add implementation of both sides renaming differentlyElijah Newren via GitGitGadget, Dec 15, 2020
  64. 08/11 merge-ort: add implementation of rename/delete conflictsElijah Newren via GitGitGadget, Dec 15, 2020
  65. 06/11 merge-ort: add implementation of both sides renaming identicallyElijah Newren via GitGitGadget, Dec 15, 2020

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.