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
    # 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!


  1. Usually I git rebase -i master or even git-rebase -i origin/master. That way I know exactly which commits I will end up pushing. Plus I don't have to keep track of how much commits I've done.

  2. That depends heavily on the project you are working on and the size of the changes.

    Nice post, anyway and good tip from Benjamin. You should actually follow the distributed philosophy, where the versioning system will take care of what if already merged.

    git rebase will destroy your branch history, so you or someone looking for a bug introduced by your branch will have less help in finding the exact point where the bug was introduced.

    You can rebase all your changes if you keep the branches small, so it will be easy to look at the resulting commit and find the errors, and also git bisect will still be useful.
    Prevent git bisect from working is very bad. It's another very powerful toy provided by git that allows you to easily find the changeset a bug was introduced.

  3. @Tiago git rebase will destroy your branch history yes, so actually it's up to you to decide which to squash or not. I usually squash tiny commits into a single, general commit focusing on a particular change. I don't really merge multiple changes(multiple bug fixes?) together but thanks for the advice. You too Benjamin. :p

  4. I suggest you to take a look at topgit. It's a really usefull porcelain if you need a 'single-patch' workflow.

  5. thanks for the suggestion.

    apparently this post is kinda beginnerish which is exactly what i've learned about posting patches in the past 3 months: the workflow which worked for me.