Friday, January 22, 2010

How Git shines above Subversion at Merging

I've recently started getting my head around Git having been a Subversion (sadly even CVS) user all along. While I liked the fact that it was distributed and way faster than Subversion at most operations, I couldn't understand why many claimed it was better at merging than Subversion (1.5 and above). Even the "Branch Handling" section in Git's wiki talks only about better history tracking but not about how Git is better at merging the content themselves.

While correct history tracking is important, merging without breaking the code is an absolute must. So I wanted to see if there was a place where Subversion would silently break the code during a merge but Git would not. This might not be new to long time Git users but I hope this would help many Subversion users take another look at Git. Without further ado, lets see how Git manages merges better.

The Workflow

You initially start off with a file named Test.java in both SVN and Git repositories with initial content as below.


You then create a branch named "refactor" and within this branch rename the class to NicerName (and consequently rename the file too) and commit to the branch.


You switch back to the main branch (trunk/master) and fix a bug. In this case we change the message being printed to "Correct Message" and commit to the main branch.


Finally, we merge the changes from the refactor branch into the main branch.

The commands

SVN would do it with the following commands.


Git would do the same with these commands.


The Result

Neither SVN nor Git complain about conflicts which is fine. However, after the merge, SVN leaves two files in the main branch. NicerName.java has the new name but doesn't have the fix while Test.java has the fix but not the new name. Here is how it looks in SVN.



Essentially your code is broken silently by SVN during the merge. On the other hand Git handles this very cleanly. It leaves only NicerName.java back including the fix to the message and removes Test.java, exactly as you'd expect.


Over all the branching and merging commands looked cleaner with Git too. This kind of excellent support for branching, refactoring and merging back alone should make everyone give Git a serious consideration. Even if Git is used in a centralized workflow just like Subversion, it can still provide huge benefits over Subversion. If you utilize its distribution features too, it just gets better!

1 comment:

Sayan "Riju" Chakrabarti said...

http://jam-bazaar.blogspot.com/2009/10/refactoring-work-for-review-and-keep.html