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

Re: cherry picking and merge

From
Sam Vilain <sam@vilain.net>
Date
Aug 1, 2014, 20:12 UTC
Message-ID
<53DBF4C9.2090905@vilain.net>
In-Reply-To
<5AF18A76-DD3B-4B9A-BF70-EFE4BB852C3D@comcast.net>
On 08/01/2014 10:48 AM, Mike Stump wrote:
>> There is also git-imerge, third party tool that is intended to help
>> merging changes (and make it possible to do it in incremental way).
> Then remove git merge and replace it with git-imerge.  :-)  Anyway, I read that, and I can see some beauty of that that might be nice in complex merges.  The problem is, I want git merge to work.

Git merge has a notion of discrete "merge strategies". The default, "recursive" merge strategy isn't completely oblivious to history; in the event that the two branches don't have a single merge bases, it performs 3-way merges (strangely enough) recursively, with the merge bases of the branch you're trying to merge until it completes. In general, this works pretty well. Some systems even simpler than that (eg, github's green merge button) work acceptably as well.

There's no particular reason that you couldn't implement a merge strategy which works more like SVN's approach, which essentially does an internal rebase and then commits the result. The advantages of a rebase in this situation is that you get to eliminate changes which don't need to be applied, either because (in SVN's case), it had some metadata/hearsay information that told it that it could skip that change, or (in git's case), because it found content/facts that the change already was applied on one side.

However, there are corresponding disadvantages to this strategy. It's just as easy to contrive a situation where this "internal rebasing" doesn't do the right thing, even without cheating by getting the metadata wrong. And besides, there's already a way to do this: do an actual rebase. You could also do a rebase, and then if, say, the original branch you're rebasing is published and you don't want to rewrite, then you can easily enough use squash merging, merge -s ours, etc to make it look like the strategy you wanted was a built-in git merge strategy. Or, in the spirit of open source, you could contribute the code required to make 'imerge' a built-in strategy.

> I was curious if svn handles this better the same or worse, and it did it just fine.  I know that a while ago, svn could not handle this, it would do what git does currently.  Apparently they figured out it was a bug and fixed it.  Have you guys figured out it is a bug yet?  The first step in solving a problem, is admitting you have a problem.

So, I have to chuckle when I read this indignant comment. There's a funny story to the "while ago" you refer to. This refers to the time period during which SVN was relevant; about versions 1.4 and earlier (being generous). Back in those days, SVN projects for the most part avoided merging, because it was so problematic and not tracked at all. As one core SVN developer said to me, they found "teams collaborate more closely if they're all working on the same branch". Sure, you could do it, and I even know of a few communities who did, but by and large, it was avoided. Then, the new wave of version control systems including Git, bzr and Mercurial were cropping up, and their merges were actually good enough that you could practically use them.

The SVN core team had to keep pace to match. So, in 1.5 the "merge tracking" system, previously only supplied as a "contrib" script, became core. This is ironic, because the version control system which SVN imitated poorly--Perforce--had a very sophisticated, if over-complicated, merge tracking system which was also based on metadata. Per-branch, per-patch, per-file entries for whether or not a patch had been "integrated" into the target branch. I can only guess that the reason they didn't implement this in the original SVN version was that it was something of a pain point for users in Perforce. Possibly something to do with the way that Perforce would store double entries for each merge (yes: two rows in a relational store, one representing the mirror image of the other), and differentiated between many different forms of "integrated" (ie, 2 rows and 4 states instead of, say, a single bit). So the underlying data model wasn't as simple as it could have been, and this was reflected in the difficult to use command-line tools. Plus, they were using BerkeleyDB for metadata instead of the relational ISAM library, and debugging a rabbit's nest of merge record as Perforce used would have been a nightmare. They didn't go there. And besides, they found that often, detecting patches as already applied based on content, like 'patch' did, worked.

Prior to 1.5, the Perl community developed SVK, an offline version of SVN, and this had a far simpler model for merge tracking, more similar to git's: just tracking whole-branch merges rather than individual files, patches, and branches. SVN eventually added two separate ways of tracking merges: either a per-file, per-branch, per-commit or a per-branch, per-commit model.

Anyway, I'm not sure where I'm going with this, but I guess a little extra perspective would be useful!

Sam
Previous: Philip OakleyNext: Mike Stump
Message 9 of 43 in “cherry picking and merge”
  1. Mike StumpAug 1, 2014
  2. brian m. carlsonAug 1, 2014
  3. Jakub NarębskiAug 1, 2014
  4. Mike StumpAug 1, 2014
  5. Philip OakleyAug 1, 2014
  6. Mike StumpAug 1, 2014
  7. Philip OakleyAug 2, 2014
  8. Philip OakleyAug 2, 2014
  9. Sam VilainAug 1, 2014
  10. Mike StumpAug 1, 2014
  11. Nico WilliamsAug 1, 2014
  12. Alex DavidsonAug 2, 2014
  13. Mike StumpAug 6, 2014
  14. Rebase safely (Re: cherry picking and merge)Nico Williams, Aug 6, 2014
  15. Nico WilliamsAug 6, 2014
  16. Mike StumpAug 1, 2014
  17. Keller, Jacob EAug 21, 2014
  18. Keller, Jacob EAug 21, 2014
  19. Nico WilliamsAug 1, 2014
  20. Mike StumpAug 1, 2014
  21. Nico WilliamsAug 1, 2014
  22. Jonathan NiederAug 1, 2014
  23. Jonathan NiederAug 1, 2014
  24. Nico WilliamsAug 1, 2014
  25. Junio C HamanoAug 1, 2014
  26. Nico WilliamsAug 1, 2014
  27. Junio C HamanoAug 1, 2014
  28. Jakub NarębskiAug 6, 2014
  29. Nico WilliamsAug 6, 2014
  30. Junio C HamanoAug 6, 2014
  31. Junio C HamanoAug 6, 2014
  32. Mike StumpAug 1, 2014
  33. Mike StumpAug 1, 2014
  34. Jonathan NiederAug 1, 2014
  35. Fwd: cherry picking and mergeJakub Narębski, Aug 1, 2014
  36. Mike StumpAug 1, 2014
  37. Philip OakleyAug 2, 2014
  38. Jakub NarębskiAug 6, 2014
  39. Mike StumpAug 6, 2014
  40. Nico WilliamsAug 7, 2014
  41. Mike StumpAug 8, 2014
  42. Nico WilliamsAug 8, 2014
  43. Fwd: Rebase safely (Re: cherry picking and merge)Mike Stump, Aug 8, 2014

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.