Thursday, April 7, 2011

Quick and Easy Development with Git

This article just summaries the workflow I have on git.

Suppose that you have bug 444444 to fix.
  1. Check out into a new branch.
    git branch -b 444444 origin/HEAD
    
    The additional origin/HEAD makes it track the remote origin everytime git pull --rebase is done, to prevent it from yielding any errors even when you are not in master
  2. Code. Modify. Debug. Etc. Don't be afraid to commit the changes which you think would be important milestones in your patch/development. Do git commit -a whenever you think, or even whenever you like. You will see why later
  3. So you've done all the hard work and you are ready to push the patch. You need to merge all the changes into 1 commit before pushing it, right?
    git rebase -i HEAD~N
    
    With N being the number of commits that you intend to merge. This command is very powerful. You will be presented with an preformatted plaintext in your favorite editor.
    pick 7e95944 Require and build against Mutter 3.0
    pick a73f02a Add NEWS file with 3.0 contributors
    pick d6c3868 Bump version to 3.0.0
    pick b9828bf StScrollbar: clean up properly when unmapped during scroll
    pick 89de3a8 Bump version to 3.0.0.1
    
    # Rebase d25418b..89de3a8 onto d25418b
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #  f, fixup = like "squash", but discard this commit's log message
    #  x, exec = run command (the rest of the line) using shell
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    
    In the above example, I chose git rebase -i HEAD~5. The commands are pretty self-explanatory: just choose whichever commit you wanna merge into(the previous commit), changing the word which starts the corresponding commit 'pick' with 'squash'. When you close the editor, you will have a chance to edit the final commit message before the final change in the affected commits is being applied.

    Note that git rebase destroys/changes history, so it may be a problem if you want to track a particular change which you did which introduced a new bug. What I usually do is that I only merge tiny changes into one big commit which fixes a feature of the bug. Just make sure that your 'squashed' commits will focus on one atomic change so you can track what you did. Thanks Caio Tiego for mentioning this.
So what do I do now? Just create the patch with git format-patch and you are good to attach that patch!

I noticed git rebase is a damn useful set of commands git has. Feel free to take a look at its man page to see other tips and tricks!