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

Re: [PATCH (1b)] merge-recursive.c: Add more generic merge_recursive_generic()

From
Daniel Barkalow <barkalow@iabervon.org>
Date
Aug 13, 2008, 20:36 UTC
Message-ID
<alpine.LNX.1.00.0808131559060.19665@iabervon.org>
In-Reply-To
<7v3al8ofjw.fsf@gitster.siamese.dyndns.org>
On Wed, 13 Aug 2008, Junio C Hamano wrote:
Show 24 quoted lines
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> >> Puhh, I've not dug into merging stuff that deep, but for me it does not
> >> look that this can be done in a useful way, i.e. merge_working_tree()
> >> does not do a recursive merge.
> >
> > Ah, true. It's actually doing a single merge in the way that 
> > merge_recursive would do a single merge. I think it ought to be doing 
> > a recursive merge, but that's probably a change for later, anyway. (This 
> > is for -m, which essentially picks the uncommited changes versus the old 
> > branch, applied to the new branch uncommitted)
> 
> Why would you think it should be doing a recursive merge?  It shouldn't.
> 
> Think of builtin-merge-recursive.c::merge_trees() as a fancier version of
> 3-tree variant of "unpack_trees()", with -m and -u option.
> 
> When you want to perform an exact three-way merge (i.e. you have two
> states O and B, and you want to apply changes between O and B to your
> state A, and you _precisely_ know what O is) that's the interface you
> would want to use, not the recursive one.  The recursive behaviour is
> desirable only when you have A and B and need to infer where O should be,
> and/or there are multiple O's to deal with (i.e. running "git-merge B"
> when you are at A).

I understand that you know exactly what the change is, but I'm not convinced that you don't want to consider how O is related to A in determining who to apply that change to A. My naive impression was:

 - the difference between O and B is to change X to Y, and we can 
   determine this exactly
 - we need to find X' in A to change it to Y'
 - we can more accurately find X' in A if we find Z in the common 
   ancestors of O and A such that X in O corresponds to Z in the
   ancestors, and we get similar benefits in determining the right Y'

That is, we care about the common ancestor not only for finding the relevant change in the near side to apply, but also for finding how to apply it to the far side.

Show 5 quoted lines
> In all the potential users of merge-recursive machinery, namely, "revert",
> "cherry-pick", "stash apply", "am -3", and "checkout -m", you know what
> single common tree to use for your three-way merge.  These operations,
> when done with direct C call into merge machinery, should NOT be using the
> "recursive" one.

I agree that they should all be using the same mechanism, but I'm not sure it shouldn't be recursive or take history into account.

And I'd certainly believe that just running our merge-recursive won't actually do anything clever with the rest of the history, and that merge_trees() is the most suitable method currently available (which is essentially why I ended up using it in checkout -m, not entirely realizing that I'd removed the "recursive" aspect in the process of skipping parts of merge_recursive that weren't relevant).

Maybe merge_trees should get the two sides as structs with a struct tree * and a char * branch name, and the struct could someday get optional struct commit *s for the lineage of the side if somebody comes up with a method for merging that makes use of the component changes.

	-Daniel
*This .sig left intentionally blank*
Previous: Stephan BeyerNext: Junio C Hamano
Message 36 of 38 in “Avoid run_command() for recursive in builtin-merge”
  1. 0/2 Avoid run_command() for recursive in builtin-mergeMiklos Vajna, Aug 10, 2008
  2. 1/2 merge-recursive: prepare merge_recursive() to be called from builtinsMiklos Vajna, Aug 10, 2008
  3. 2/2 builtin-merge: avoid run_command_v_opt() for recursiveMiklos Vajna, Aug 10, 2008
  4. Junio C HamanoAug 11, 2008
  5. Miklos VajnaAug 11, 2008
  6. Junio C HamanoAug 11, 2008
  7. Miklos VajnaAug 11, 2008
  8. Add a new test to ensure merging a submodule is handled properly.Miklos Vajna, Aug 11, 2008
  9. Stephan BeyerAug 11, 2008
  10. Miklos VajnaAug 11, 2008
  11. Junio C HamanoAug 11, 2008
  12. Stephan BeyerAug 11, 2008
  13. builtin-revert.c: Make use of merge_recursive()Stephan Beyer, Aug 11, 2008
  14. Johannes SchindelinAug 11, 2008
  15. Stephan BeyerAug 11, 2008
  16. Miklos VajnaAug 11, 2008
  17. builtin-revert: Make use of merge_recursive()Stephan Beyer, Aug 11, 2008
  18. Stephan BeyerAug 11, 2008
  19. Junio C HamanoAug 11, 2008
  20. Junio C HamanoAug 11, 2008
  21. Stephan BeyerAug 11, 2008
  22. Junio C HamanoAug 11, 2008
  23. Split out merge_recursive() to merge-recursive.cMiklos Vajna, Aug 12, 2008
  24. Stephan BeyerAug 12, 2008
  25. Miklos VajnaAug 12, 2008
  26. merge-recursive.c: Add more generic merge_recursive_generic()Stephan Beyer, Aug 12, 2008
  27. Make builtin-revert.c use merge_recursive_generic()Stephan Beyer, Aug 12, 2008
  28. Miklos VajnaAug 12, 2008
  29. Stephan BeyerAug 13, 2008
  30. Miklos VajnaAug 13, 2008
  31. Daniel BarkalowAug 13, 2008
  32. Stephan BeyerAug 13, 2008
  33. Daniel BarkalowAug 13, 2008
  34. Junio C HamanoAug 13, 2008
  35. Stephan BeyerAug 13, 2008
  36. Daniel BarkalowAug 13, 2008
  37. Junio C HamanoAug 13, 2008
  38. Junio C HamanoAug 14, 2008

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.