3

After I did the git svn clone --stdlayout ..., everything looks good and I have converted remote branches. But when git log --graph, I don't see any branch merging graph. Is it normal?

Drake Guan
  • 14,514
  • 15
  • 67
  • 94

3 Answers3

6

Since version 1.5.0 released in summer of 2008 Subversion does support merge-tracking. Subversion keeps information on performed merges as svn:mergeinfo property set on merge target, be it a branch directory, like ^/trunk/, or any other directory.

There are major differences between merge-tracking mechanisms in Git and Subversion:

  1. The whole branch merge.

    When you're on master branch, the command

    $ git merge some-branch
    

    results in a merge commit with its first parent set to the commit referenced by master and the second parent set to the commit referenced by some-branch (I don't take into account fast-forward and conflicted merges here).

    For git it means that created merge commit includes the whole history of both master and some-branch.

    When you've checked out ^/trunk/ branch into svn working copy and then run

    $ svn merge ^/branches/some-branch trunk-working-copy
    

    Subversion will set svn:mergeinfo property on trunk-working-copy directory as follows:

    /branches/some-branch:10-20,30-40,50-60
    

    The range 10-20,30-40,50-60 includes those revisions which are not yet merged into ^/trunk/ branch from ^/branches/some-branch/ (Subversion detects them automatically).

    Mergeinfo property just specifies those revisions which were once merged into the branch. And it's up to user to check whether all these merged revisions include the whole history of the branch.

  2. Cherry-pick merge.

    When you need to merge changes from a single commit into your master branch, you run

    $ git cherry-pick bc347a8
    

    After that git creates a commit with corresponding changes and a single parent set to the commit previously referenced by master branch.

    That is, git doesn't create any kind of merge commit for cherry-pick. So, git has no means to track cherry-picked commits via its graph structure.

    Opposite to that Subversion does track cherry-pick merges by adjusting svn:mergeinfo property with respect to cherry-picked revision:

    $ svn merge -c100 ^/branches/some-branch trunk-working-copy
    

    This command is quite straight-forward, it adjusts svn:mergeinfo as follows:

    /branches/some-branch:100
    

    That means Subversion tracks cherry-pick merges.

So, you don't get merge commits after the translation. To my best knowledge git-svn has certain problems when it comes to merge history.

But as subgit developer I have to say that subgit should correctly handle the merge-tracking info. Most probably svn:mergeinfo property set on your branches doesn't include the whole history of the branches merged to them. Here's how that could happen:

  • You have used old svn client (< 1.5), so your branches don't have enough merge-tracking information.
  • You have performed cherry-picks and skipped some revision ranges from adding into svn:mergeinfo.
  • You have svn:mergeinfo set on directories which are not branch directories, i.e. they are not ^/trunk/, ^/branches/some-branch, etc (for standard layout).

To fix that you have to find the skipped part of merge-tracking information and add it into your branches:

  1. Try to find which revision are not yet merged:

    $ svn mergeinfo --show-revs eligible ^/branches/some-branch/@HEAD ^/trunk/@HEAD
    

    The output must include all the revision you haven't yet merged from ^/branches/some-branch/ to ^/trunk/.

  2. Try to merge not yet merged revisions by svn.

    • If you think all changes are already merged, use --record-only option of svn merge command;
    • If you're not so sure, it's better to perform normal svn merge which will apply all the missing changes.
  3. Using subgit you can also merge by git means and then push created merge commits to subgit powered repository, so it will translate these merge commits to svn revisions with correct svn:mergeinfo.

As a nice bonus you may refer to SubGit specification related to the merge-tracking stuff, it has some pretty diagrams for all I've said above.

vadishev
  • 2,979
  • 20
  • 28
1

Subversion tracks merges with the help of svn:mergeinfo property. While history may not be displayed as a graph by your tool it is not linear by nature. Actually svn:mergeinfo is more powerful than Git merge commits (though this power might be of no practical use)

Tools like SubGit does translate svn:mergeinfo into merge commits when it is possible.

I'm working on the tool I've recommended (SubGit), but really git-svn is very weak in translating merges in both directions.

  • Does that mean I can try to use SubGit for this issue? How to do that? – Drake Guan Nov 25 '11 at 02:22
  • @DrakeGuan You may try [SubGit](http://subgit.com) in case you may install SubGit into your Subversion repository - SubGit works on the server side. To install SubGit run `subgit install repos` on the server side. As soon as SubGit is installed you just use git running, for instance, `git clone ssh://user@host/svn/repos`, for more detailed configuration examples please refer to the documentation on SubGit site. – Alexander Kitaev Nov 28 '11 at 15:37
  • I did give it a try and still got the straight commit logs instead of tree-like ones... – Drake Guan Nov 28 '11 at 15:53
0

Using git-svn won't change the fact that SVN itself has linear history, so technically all merges are fast-forwards, in git terms. No merge commits, thus no merges in the graph, either.

Dominik Honnef
  • 17,937
  • 7
  • 41
  • 43
  • 1
    Subversion tracks merges with the help of svn:mergeinfo property. While history may not be _displayed_ as a graph it is not linear by nature. – Alexander Kitaev Nov 24 '11 at 20:14