GIT merge-svn

apr. 23rd, 2013 | Filed under Programming, Rest of the World

How to use GIT to merge two SVN branches

TL;DR: Download the git-merge-svn script here

I’ve been using git for years now but had to start using SVN for some projects. I found that GIT is good enough Subversion client too, especially as I retain the ability to commit often and rebase my work on top of commits from other devs (on the SVN side).

The only question arose – can I merge two SVN branches so that GIT log will show the merge?

The git-svn manual states that one should avoid all git clone|merge|pull|push activity when using git-svn.

But git log does show merge history that was created in Subversion – how does it do that?

svn:mergeinfo

Subversion does not support actual merge of branches (more like cherry-picking), but since version 1.5 Subversion supports the svn:mergeinfo property that is used to track what has been merged into this folder previously.

Digging some more into the matter, I found out that GIT supports setting svn:mergeinfo property on the SVN branch when dcommit’ing:

NB! the svn:mergeinfo is overwritten with whatever is given on the command-line, so be careful to list previous merges too.

While more recent git version added the config parameter to automatically set this property:

I had some troubles with the automatic mergeinfo – for one reason or the other GIT calculated it wrong and I couldn’t get it to work.

SOLUTION: git-merge-svn

To automate the process, I wrote a shell script git merge-svn which can be used to merge two SVN branches with correct svn:mergeinfo set on the dcommit.

The script handles both situations:

  • the branch is not merged in git – will do git merge beforehand
  • the branches have been already merged in git (but not in SVN) – will traverse until previous ancestor for the merged commit revisions.

UPDATE: Thanks theantway and haraldreingruber for patches – the script now:

  • always does full merge (no fast-forward) so that SVN can fully understand and
  • does not die on first merge (no previous mergeinfo)

Download the git-merge-svn script here

Example usage

With this script I was able to produce these merges solely on git-side and retain the merge info so that GIT graph shows the log nicely:

git-merge-svn result

  1. Make some commits on devel6
  2. dcommit devel6 to SVN (required to get SVN revision numbers for the commits)
  3. check out testtunk6 – yes, I know I made a typo in the name 😉
  4. git merge-svn devel6

The last commant outputs:

Be Sociable, Share!
  1. eagleinfly
    apr. 25th, 2014 at 07:26
    Reply | Quote | #1

    Nice work, and I have used it for 2 months without a problem until today.
    Unfortunately, I got a problem that after merge, the remote url changed to the FROM branch because git merge using the fast forward, so maybe you could add –no-ff to git merge command.
    Gist doesn’t have a pull request feature, so I can only leave the message here. and my fork is : https://gist.github.com/theantway/11278250.

    Anyway, it’s a great work, and saved lots of my time. Thanks.

  2. Laas
    apr. 25th, 2014 at 10:42
    Reply | Quote | #2

    Thanks! I merged your change (Gist is actually full-blown git repo, so even w/o pull-requests, merging is possible).