I thought that nobody used SVN anymore and our world was a better place to live and work in. I was wrong. I recently agreed to fix some issues on a project and only when I got it did I understand that some people still use svn in their projects. For me it was total frustration, but it was too late to reject the project (yes, now you can laugh :) ). I didn't want to work with svn, so, I needed a way to work with it through git, and I found it. In this article I want to describe how to work with svn through your best dcvs - git. If you're out of luck for some reason and the project you've got uses svn, then you definitely need to read this article. Working with svn through git is as easy and almost as pleasant as working with git itself, I promise
Installation of git-svn bridge
First of all we need to install git-svn bridge. I use Fedora 20, so I can do it like:
$ sudo yum install git-svn
After you do this, you will see that new bunch of commands is available via `git svn`. It means that you've successfully installed git-svn bridge and we can move forward.
Clonning an svn repository through git
When we have git-svn installed on our machine, then it's easy to setup svn project:
git svn clone http://example.com/repo -s
Here we use our first svn command `clone` through git: `git svn clone` to clone a remote svn repository. `-s` option in our case means that the svn repository uses a standard layout for branches and tags (`-s` will be fine in most cases).
Working with svn through git
After we've cloned an svn repository, we can work with it almost as with a usual git repository and it's awesome. For example you still can use next familiar to you commands:
git status git add . git commit -m 'Even if it is an old awful svn I work with it as with Git'
You may do as many local commits as you want, just treat the repository as it was a git repository.
What should I do to push my changes to a remote svn repository?
Of course there still exists some difference between a real git repository and a git-svn repository because svn doesn't support some cool features. When you're ready to push your changes to an svn server, you need to do two simple steps:
1. Pull all changes from an svn repository
git svn rebase
This command will fetch all new commits from an svn repository and then apply all your local commits to the project one by one. This is cool, because you still can check the real state of a project before pushing changes back to an svn server. Keep in mind that your working directory should be clean before you run `git svn rebase`.
2. Push changes to an svn repository
Now you have all changes from an svn repositoy plus your own commits, so you're ready to push them back to an svn server. You can do it via:
git svn dcommit
it will push all your local commits to an svn server. That's it, we're done.
Conclusion
I worked with svn more than 3 years ago and I don't want to remember that time. I think that work with projects should be comfortable and you don't need to learn old ugly things like svn. Git to the rescue, again. Even if project is under svn we still use our lovely tool - git and it's awesome. We can use branches, stashing, check state of our project on a local machine before pushing updates and so on.
This solution isn't perfect, because it has cons and caveats:
- You need to keep a linear Git history. It means that you need to use `rebase` approach instead of `merge` one. Rebase any work before you pull/push changes from/to an svn repository.
- After you do a `dcommit` all your commits are rewritten with `git-svn-id`. If you plan not only to work with svn through git but also to use git servers to quickly work with tons of commits, you need to be careful. You should push commits to git server/repository only when they have `git-svn-id` or you may have troubles with svn server then.
Suggestions
When you get an svn project, use Git. You'll save your brain from troubles. Also try to talk to owner/team to do a total migration from svn to git, because git definitely has a lot of advantages to make work with a project smooth and pelasant.