Git commit partitioning

From RidgeRun Developer Wiki

There is a lot of great Git branching information. I found most ignore how to partition the commits that are part of a successful software development process.

Problem statement

You need to add functionality to an existing code base or fix a defect. How do you decide which changes go into which git commit?

Guidelines

Guildeline Reason
The code should build and run after each commit. This allows the git bisect command to work as expected.
There should only be one functional change per commit. This makes the code easier to review. If the commit introduces an error, it is much more obvious what is the source of the error and how to fix it.
The first commit often cleans up the code match the coding standard. If you touching the code, make it better. There should be no functional change.
The second commit often refactors the code without changing the functionality. This makes it more straight forward to understand the commits that fix the defect or adds new functionality.

Commits on a branch

You have been working hard, you have been pushing your work to the big repository in the sky, you have all your changes implemented, tested, and working on a branch. Now what?

Others have said it better than I:

But I like to hear myself talk, so I am going to add my perspective.

If you are a guru Linux kernel developer, the commits will be exactly right, the log messages accurate and concise; basically you will have a work of art.

If you are a mere mortal, you may have a branch that is a mess; more like finger painting rather than a Rembrandt. Don't despair, you too can create patch set you are proud of.

  1. Look though all the commits on your branch that haven't been pushed. Write down the list of code clean up, refactoring, and new features. This will be the starting point for how you repartition your code changes.
  2. Get the hash for the commit prior to your first change and the hash for your last commit. Use a visual difference tool to review all your changes.
    git difftool --no-prompt --tool=meld  $STARTING_POINT_HASH HEAD
  3. Update your repartition list based on the inspection of the differences.
  4. Create a new branch using the same starting point as your branch that is in need of commit repartitioning.
  5. Using the current version of the source code on the new branch and the HEAD of the branch being refactored, use a meld or similar to drag the changes to the current code, based on your list of properly partitioned commits.
  6. Verify the code builds, runs, and passes the test suite after each commit.
  7. When finished, verify there are no unexpected changes between the HEAD of your old branch and the head of your new branch.
  8. Review each commit, feeling nearly as proud as Rembrandt when others admired his artwork.