git add -p How to use patches instead of full commits

Recently I can across an excellent tidbit of advice that I have started to incorporate into my workflow.  All of us as programmers are very familiar with the “git add” command.  It is simple, straightforward and a frequent step in our workflow.

Too often I hear the question “why isn’t the git add and git commit a single step”, why is it separated out into two steps.  Well – the short of the answer is that they literally are two different actions and there are a lot of specific commands that you can do on each action.  Hence they are separated to give you more control.  If you find yourself asking why can’t they be combined – then maybe I should challenge you to try to learn more about each step and how they can be customized to improve your workflow.

Let’s look at the following command:

git add -p

A simple git add command – but what is that -p parameter doing?  Well that stands for a GIT Patch.  This nifty tool allows you to stage only portions of a file compared to the full file itself.

How does “git add -p” work?

git add -p is interactive.  Use git add just like you would normally, however add the -p flag to it.  Note – you may want to try this first with a small edit that only has a few changes.  Doing this to a very large commit can take a but of time.

In this example I have a file with two comments added.  After you run git add -p you should see something such as the following:

[ben@test-box ~]$ git add -p
diff –git a/test.php b/test.php
index b8eb2e2..df32a78 10974
— a/test.php
+++ b/test.php
@@ -40,7 +40,7 @@ self::STATE_REOPENED => ‘Re-opened’
);

+//TEST MOD
+
static $reqTypes = array(

self::REQ_OTHER => ‘Other’,

Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?

This is a standard diff output by GIT.  It provides the Diff then asks you what to do with it.  In essence it runs the add –interactive command and dumps you right into the patch mode within that command.

Here is a list from the git man page of what the various params represent that you can work with for this hunk.

  • y – stage this hunk
  • n – do not stage this hunk
  • q – quit; do not stage this hunk nor any of the remaining ones
  • a – stage this hunk and all later hunks in the file
  • d – do not stage this hunk nor any of the later hunks in the file
  • g – select a hunk to go to / – search for a hunk matching the given regex
  • j – leave this hunk undecided, see next undecided hunk
  • J – leave this hunk undecided, see next hunk
  • k – leave this hunk undecided, see previous undecided hunk
  • K – leave this hunk undecided, see previous hunk
  • s – split the current hunk into smaller hunks
  • e – manually edit the current hunk ? – print help

Once you choose the command you want you will immediately be taken to the next hunk of code for the next patch.  You can then choose to add the hunk or exclude the hunk.  Once completed you can then commit the selected hunks of changes into your new patch.  You did not have to stage the entire file.

So why would this be so useful?  There are two different scenarios where the git add -p method can be useful and save a lot of time.

More Concise Commits

The first is that the git add -p method allows you to make more precise and isolated commits.  Let’s assume that the feature you are working on is rather large and spans several different files.  Because you are a good programmer the changes to each file are in fact separate from each other and can run independently.  instead of committing all the changes in one large commit you decide to break them up into several patches and commit them one by one.  it doesn’t add too much time – but will save you in the long run.

No imagine that your code is going through the release process.  A nasty bug is found within one of the changed files and the Release Manager backs out one of your changes.  Since you took the patch based approach all of your other changes are able to move forward without issue.  You then can work on the isolated bug and fix it.  git add -p prevented a small isolated bug from stopping a very large feature.  it contained it to it’s own individual patch.

Faster / Cleaner Development

In another example let’s consider when you are working in a high stress environment.  A lot of your code is changed and is in no shape to be staged or committed.  A quick emergency comes down on your plate requiring a fast 1 line change in your code.  Using git add -p you can stage and commit just this small change and leave other code within the same file unstaged.  You didn’t have to switch contexts to another branch or work on a different environment.  git app -p saves the day again.

Always use it?  No…

These are just some example usages of git add -p.  Does this mean that you should always use it?  i don’t believe so.  I do believe however that it is an easy way to improve your development effectiveness within GIT and in term allow you to work smarter.  Give git app -p a try and see what it can do for you.

Comments

comments

Posted in and tagged .