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

Re: Converting to Git using svn-fe (Was: Speeding up the initial git-svn fetch)

From
Jakub Narebski <jnareb@gmail.com>
Date
Oct 21, 2010, 18:37 UTC
Message-ID
<201010212037.09618.jnareb@gmail.com>
In-Reply-To
<4424833.537061.1287669604786.JavaMail.root@mail.hq.genarts.com>
On Thu, 21 Oct 2010, Stephen Bash wrote:
> Will Palmer <wmpalmer@gmail.com> wrote:
> > Of course, "ignoring merges" is temporary and a total cop-out
> 
> This is still bugging me...  Even with svn mergeinfo (which I think
> is a small percentage of the SVN revisions in the world),
>From what I understand to have svn:mergeinfo you have to have version >= 

1.5 of Subversion installed on server, and to use it also >= 1.5 client.

Show 7 quoted lines
> IMO an SVN merge is *not* a Git merge.  I think of it as a git
> cherry-pick (someone correct me if this mental model is wrong).
> The key point in my mind is SVN merge doesn't have to merge the entire
> branch history.  Perhaps some heuristics can be applied in Git to
> decide if an SVN merge is a "true merge" or a cherry-pick?  But I have
> a nagging feeling that in the end the model mismatch is going to be
> very hard to overcome.        

Hopefully in most common situations (i.e. SVN repository is not mishandled) the svn:mergeinfo would be _only_ on branch folders ("branches/<branchname>") and inherited downwards. This should be fairly easy, I think, to translate to git merges (merge commits).

But because Subversion doesn't impose strict separation between branch namespace and in-repository paths, somebody somewhere would certainly at some time screw this up. And only then we would have to rely on subtree merge / git-subtree split similarity detection.

BTW. Subversion doesn't have "svn cherry-pick", nor equivalent to "git reset" == "git cherry-pick -R"... well, at least I don't think it has.

......................................................................
Warning! Rant ahead!
<rant skip="if needed">
I have read some documentation about svn:mergeinfo property:
  http://svnbook.red-bean.com/en/1.5/svn.branchmerge.basicmerging.html
  http://www.collab.net/community/subversion/articles/merge-info.html

I see how "branches are folders" model, without a concept of version included in (belonging to) some branch and without the concept of 'previous version in the same line of development' leads to such strange, bizzare things.

First, svn:mergeinfo is not about tracking which commits (which parents) were involved in creating given version, like in Git (where merge commit that was result of merging branch 'bar' into 'foo' has commits which were then tips of 'bar' and of 'foo' as two parents of commit representing result of merge).

No, svn:mergeinfo is ass-backwards solution to the problem that "merge tracking" solves, namely that of repeated merging. Let's take a look at the following situation:

   ---1---B---2---3---M1--4---5---M2   <-- foo
           \         /           /
            \-a---b-/-----c---d-/      <-- bar
B is branching point, M1 and M2 are merge commits.

In Git, and I assume that also in Subversion, when doing merge M1, the VCS notices that from revision B branches 'foo' and 'bar' have common commits (in git we say that merge base of 'foo' and 'bar' at the point of doing merge M1 is commit B). VCS it know then that it has to integrate changes that were made on branch 'bar' since cleft point B, i.e. changes brought by revisions 'a' and 'b', with changes made on branch 'foo' since B, i.e. changes brought by revisions '2' and '3'. Git does that by running 3-way merge (same as rcsmerge / diff3 merge) with '3' as ours aka mine version, 'b' as theirs aka yours version, and 'B' as ancestor aka older version; I assume that Subversion does the same thing, or equivalent.

Now here is where things begin to be different in Git and in Subversion. In Git, commit 'M1' with merge resolution has simply two parents: '3' and 'b'.

In Subversion there is no such thing like parent of revision. Instead of this SVN records that it integrated changes brought by revisions 'a' and 'b' into 'M1', which means that from revision 'M1' the branch folder ("project/branches/foo") acquires svn:mergeinfo property with the contents '/branches/bar:B-b' (B-b is a:b, i.e. range from B to b, excluding B). PLEASE CORRECT ME IF I AM MISTAKEN.

Note branch info in svn:mergeinfo property. Note the revision range instead of just its endpoint 'b'. Note lack of reference to what would be first parent in git merge commit, i.e. '3'.

Let's take a look what happens at point M2 (i.e. second merge) in Git and in Subversion.

In Git it is easy. Git calculates merge base by travelling parentage links (which include all parents of merge commits), and notices that at point 'M2' merge base, i.e. first common ancestor of branches 'foo' and 'bar' is commit 'b'. It then runs 3-way merge with '5' as ours, 'd' as theirs, and 'b' as ancestor, and records merge commit with parents '5' and 'd'.

Subversion instead examines svn:mergeinfo property to check what it already merged in, and somehow notices that it has to integrate changes c+d made on branch 'bar' (but not a+b+c+d, as a+b were already integrated) with changes 4+5 on branch 'foo'. Probably it somehow notices that 'b' is common ancestor. But you can see how this mechanism is fraught with peril and can break easily in more complex situations ("The 1.5 release of merge tracking has basic support for common scenarios; we will be extending the feature in upcoming releases."... they hope!).

Subversion then updates svn:mergeinfo property at branch 'foo'. </rant>

-- 
Jakub Narebski
Poland
Previous: Stephen BashNext: Stephen Bash
Message 43 of 52 in “Speeding up the initial git-svn fetch”
  1. Matt StumpOct 13, 2010
  2. Stephen BashOct 13, 2010
  3. Matt StumpOct 13, 2010
  4. Stephen BashOct 13, 2010
  5. Converting to Git using svn-fe (Was: Speeding up the initial git-svn fetch)Stephen Bash, Oct 14, 2010
  6. Jonathan NiederOct 14, 2010
  7. Sverre RabbelierOct 14, 2010
  8. Stephen BashOct 15, 2010
  9. Sverre RabbelierOct 15, 2010
  10. Stephen BashOct 16, 2010
  11. Sverre RabbelierOct 17, 2010
  12. David Michael BarrOct 17, 2010
  13. Ramkumar RamachandraOct 18, 2010
  14. Jonathan NiederOct 18, 2010
  15. Ramkumar RamachandraOct 18, 2010
  16. Sverre RabbelierOct 18, 2010
  17. Jonathan NiederOct 18, 2010
  18. Ramkumar RamachandraOct 18, 2010
  19. Sverre RabbelierOct 18, 2010
  20. Jonathan NiederOct 18, 2010
  21. Sverre RabbelierOct 18, 2010
  22. Jonathan NiederOct 18, 2010
  23. Sverre RabbelierOct 18, 2010
  24. Jonathan NiederOct 18, 2010
  25. Sverre RabbelierOct 18, 2010
  26. Jonathan NiederOct 18, 2010
  27. Ramkumar RamachandraOct 19, 2010
  28. Stephen BashOct 19, 2010
  29. Stephen BashOct 19, 2010
  30. Ramkumar RamachandraOct 19, 2010
  31. Stephen BashOct 19, 2010
  32. David Michael BarrOct 19, 2010
  33. Stephen BashOct 19, 2010
  34. Will PalmerOct 20, 2010
  35. Jakub NarebskiOct 20, 2010
  36. Will PalmerOct 20, 2010
  37. Jakub NarebskiOct 20, 2010
  38. mrevilgnomeOct 21, 2010
  39. Jakub NarebskiOct 21, 2010
  40. Stephen BashOct 21, 2010
  41. Will PalmerOct 21, 2010
  42. Stephen BashOct 21, 2010
  43. Jakub NarebskiOct 21, 2010
  44. Stephen BashOct 21, 2010
  45. Jakub NarebskiOct 21, 2010
  46. Stephen BashOct 21, 2010
  47. Jakub NarebskiOct 22, 2010
  48. Jakub NarebskiOct 21, 2010
  49. Jonathan NiederOct 21, 2010
  50. Ramkumar RamachandraOct 20, 2010
  51. Stephen BashOct 20, 2010
  52. Ramkumar RamachandraOct 20, 2010

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.