12 Aug 2008 federico   » (Master)

Tue 2008/Aug/12

  • Why I want to have the children of git rebase --interactive

    Sometimes you are hacking madly and committing often. Your commit log looks like this:

    * Add some fields for a popup menu
    * Create the popup menu
    * Refactor the base object to accomodate the menu's commands
    * Implement the signal handlers for the menu's commands

    Then you type make and of course your code doesn't compile. So you do one-liner commits, one for each build error:

    * Add missing include gtkmenu.h
    * Fix typo in popup_menu variable name
    * Forgot to declare a menu_item variable
    * Add missing argument for gtk_menu_popup function

    But you don't want you submit all of those patches upstream! You only want to send perfect patches which are either additions or refactorings to the upstream code. You don't want the maintainer to know that you are a fallible human being who forgets include files and variable declarations; instead, you want him to believe that you are a coding god who sends a perfect series of patches every time.

    git rebase --interactive allows you to pretend you are better than you really are. This is a good thing.

    We have 8 commits in total (4 "good" ones that don't compile, and 4 "embarrassing" ones that are little fixes). So, run git rebase --interactive HEAD~8. This means, "let me fix any fuckups since 8 commits ago".

    Git will drop you in an editor where you edit this:

    pick ab365cf Add some fields for a popup menu
    pick 2478bac Create the popup menu
    pick 9180ffe Refactor the base object to accomodate the menu's commands
    pick a6c2467 Implement the signal handlers for the menu's commands
    pick 289cf1a Add missing include gtkmenu.h
    pick 378ac2b Fix typo in popup_menu variable name
    pick 821ac6f Forgot to declare a menu_item variable
    pick 24acf67 Add missing argument for gtk_menu_popup function
    
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit

    Now let's reorder the lines there, and replace some pick commands by squash. I've put in some comments about what each moved line does.

    pick ab365cf Add some fields for a popup menu
    squash 289cf1a Add missing include gtkmenu.h
    # Oops, forgot to "#include <gtk/gtkmenu.h>" to have a field declared "GtkMenu *popup_menu"
    	      
    pick 2478bac Create the popup menu
    squash 821ac6f Forgot to declare a menu_item variable
    # Oops, while creating the menu items I forgot to declare my menu_item variable
    
    squash 24acf67 Add missing argument for gtk_menu_popup function
    # Oops, while creating the menu I also missed an argument to this function (how couldn't anyone?)
    
    pick 9180ffe Refactor the base object to accomodate the menu's commands
    
    pick a6c2467 Implement the signal handlers for the menu's commands
    squash 378ac2b Fix typo in popup_menu variable name
    # ... and I also mistyped popup_menu in a signal handler

    When you are done, save that temporary file and exit your editor. Git will rewrite your commit history so that you have a clean log, with no commits like "fix this little thing". When you send that patch series to the maintainer, he'll have an easier time reading your code, and he'll be amazed at your meticulousness.

    The important thing here is to do one commit per compilation error. Then it's very easy to reorder your commits, where you squash each fix with the corresponding "real" commit.

Syndicated 2008-08-12 14:50:00 from Federico Mena-Quintero - Activity Log

Latest blog entries     Older blog entries

New Advogato Features

FOAF updates: Trust rankings are now exported, making the data available to other users and websites. An external FOAF URI has been added, allowing users to link to an additional FOAF file.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!