Thursday, April 16, 2009

GIT Rebase

I've recently become a die-hard git convert. I used to use subversion but branches in subversion and always having to be connected gave way to an interest in git. Branches in git are ridiculously easy and I like the fact that I don't have to be connected to save changes. Then I started using git and discovered rebase.

My typical workflow is to work and commit locally and then push up my changes when I have major chunks of work done. I also like to try and keep groups of commits small and related.

Typically though I'll do lots of commits and rebase lets me group related commits. You typically don't want to do rewrite the history (what rebase lets you do) to commits you've already pushed to the server but if you are the only one working on it or are sure it won't screw anyone up, you can --force a push to get your newly rewritten history up.

Now, how do I use it? If I have local changes I'm not ready to commit yet, I first use the 'git stash' command. This creates a temporary branch and stores your changes there. You could create another branch if you want and then switch back to rewrite history, but I find the stash command handy.

Now we do the rebase, in this example, we'll go back 5 commits. 'git rebase --interactive HEAD~5' Of course change 5 to whatever number you want to go back. (A quick git log should give you a good idea of how far to go back.)

From here, you'll get a list of commits, each with the work 'pick', the commit's short sha and the commit message. What I primarily use is pick and squash. Just move the line you want to merge into something else under the commit you want to merge into. Change pick to squash. Now save.

It will then open up your editor and ask you for a new commit message. It will show you both and let you change it. Saving this will rewrite your history. Now you can push up your newly rewritten history. Now to get back the changes you stashed away, simply type: 'git stash apply'

Git is really fast at what it does, even when pushing changes to the server. The only time I've noticed it taking a while was transferring an entire bare repository over a slow ssh connection. (Not really gits fault) Once I get very comfortable with it, I'll create a workflow chart that documents how I use it in hopes that it helps others.

No comments: