Please provide tips for effectively using git with svn. What are your "best practices"?
Here's some that I recently learned:
- always do
git svn rebase
before doinggit svn dcommit
- when you are doing
dcommit
, do it from a temporary staging branch - if you (or git) mess up, it's much easier to recover by just deleting the branch and starting over
When svn dcommit
dies halfway through a large commit and you seem to have lost all of your history, do this:
How To Recover:
First, open .git/logs/HEAD
Find the hash of the commit that's the head of your git repo. Hopefully you remember the commit message and can figure it out, but it should be pretty obvious
Back in your now f-ed up working-dir:
git reset --hard <hash from log>
This gets your working dir back to where it was before you did a git- svn dcommit. Then:
git-svn rebase git-svn dcommit
When you create the clone, use --prefix=svn/
. It creates nicer branch names.
Also, don't neglect the --trunk
, --tags
, and --branches
arguments when doing clone
or init
.
Fetching is one of the more time-consuming steps, so set up a cron job to do git svn fetch
in the background. This is safe because fetching doesn't affect any of your working branches.
( Background info on git svn fetch
: This command is executed first whenever you do git svn rebase
, so by doing this step ahead of time, your git svn rebase
call will usually be faster. The fetch
command downloads SVN commits and sticks them into special branches managed by git-svn. These branches are viewable by doing git branch -r
, and if you did the above step, they start with "svn/". )
Make sure you know how to use git reflog
. I've had a few occasions where git svn dcommit
died (usually because I tried to check in something huge) and my commit seemed to be lost. In every case, the commit was easily found in the reflog.
If you have a post-commit hook in your SVN repository that can reject commits, then git svn dcommit
will stop processing commits the first time a commit is rejected, and you'll have to recover your remaining commits from the git reflog.
Actually, I think the above problem was caused by my cow-orker not running git rebase -i
correctly while trying to fix the rejected commits. But, thanks to the reflog we were able to recover everything!
I've been blogging a bit about how to live with Subversion and Git in parallel, and I've also put up a couple of rudimentary screencasts. Gathered everything here: http://www.tfnico.com/presentations/git-and-subversion
I'll try a summary:
- Just go for it! Doesn't hurt to try it out :)
- Start off with a small Git project to learn first.
- Stick to the command-line until you master it. GUI-tools might just confuse you.
- If possible, do one-off migrations, leave SVN behind, one project at a time, starting with the small ones.
- If you do have to live with a Git and SVN together, be aware that you have to give up many advantages you get from Git, like branches, but you get the "local" benefits (stash, index, speed).
- If you are one Git user, just do git-svn rebasing and dcommitting by yourself.
- If you are several Git collaborators, set up a central Git/SVN that only pulls from SVN, while each Git-user dcommits directly back to SVN. More info here.