I got this question recently:
Why do you use git when we have svn already?
The easy and smart-xxxx answer is “Because I can..” – but that’s not acurate. So if you’ll allow me – I’ll just get on top of my soap-box …
Git with svn (aka git-svn) brings a lot of goodness to the table.
Git checks the entire repository for changes
Ever forgot to check in part of your work, breaking the build because of a missing file or two? When you commit to svn (using git-svn) the entire repository (all code checked out) must be in a non-dirty state. This means that your code is either committed locally or ignored. That makes it easier to spot files that should have been part of the commit.
Git works on local files
Which means it’s possible to commit locally. This can be used to safe-guard work that, although it’s not ready to be seen by the entire project-group, it important enough that you’d want a copy of it – just in case.
Typically an SVN repository would look something like this:
Where ReleaseXX represents whatever is important for the project to track, so your SVN may look different. The main point is this: SVN repository track what is important for the entire project. The creation and naming of branches is strictly controlled – as it should be.
Working in the same commit track as the rest of the project means that you have to be careful what you commit. The commit must never break the build. But what if you have some code that you’d like to keep, some snapshot that represents and important place for your work – but committing it would break the main build? What you’d normally have to do a file-system copy of the work. When I do things this way I end up the several copies of the source-tree – and I can never keep track of which copy is which…
With git you create a local branch where you do your work. Your commits are local so you can commit whenever you want and add a commit message that makes sense to you. Then when you’re ready, you pull from SVN. And merge your local branch into the SVN branch. Then the SVN branch commit to then SVN repository adding a commit message that makes sense to the project.
Working in a local branch allows for greater control when merging
If you’re lucky you work one something that rarely introduces merge conflicts. But in some frameworks this is unavoidable.
When working with svn an “svn update” is mandatory before committing.
Sometimes doing the update introduces conflicts. Sometimes errors. What introduces this error? Your code? The repository code? Or the combination of your code and repository? Wouldn’t it be nice if you could check that?
When using git with svn (aka git-svn) your local git repository by default includes a “master” branch. This is the branch that tracks the subversion repository. Whatever other branches you might have will not affect the master branch, unless you perform changes on it.
A standard workflow could look something like this:
- Create your local repository (and the svn master branch)
- Create a local branch
- As many times as needed …:
- … do some work on the code …
- Commit to you local branch
- Switch to the svn master branch
- Update from the SVN repository
- Merge your local branch to the svn master
- Test and commit the changes
Now if something goes wrong during your update/merge with SVN, you’ll have access to the following code-trees:
- Your local work – without any svn updates
- The master branch before you updated from svn
- The master branch after you updated from svn
- The master branch including your changes
Having this information makes it a lot easier to track down the problem and solve it.