You’ve been working on a big set of changes, and haven’t committed to Git yet. Now, you want to commit some, but not all, changes to a file. Let’s look at adding patches.

Here’s the command.

$ git add --patch

--patch lets you interactively choose which changes to apply to a commit.

Applying Patches

Run this command and you’ll see the following:

$ git add --patch
diff --git a/README.md b/README.md
index 18d277a..b012031 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # [jakeworth][production-url]

+A blog of awesome Git tricks.
+
(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?

This is a piece of our diff, or a ‘hunk’, with information telling us which one we are currently reviewing (one of two), and a menu of options.

Type ?, to learn about each option.

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or 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
e - manually edit the current hunk
? - print help

What you do next is up to you. I approach this with the following thought process:

  1. Am I seeing too many changes at once? Or, would I like to keep some but not all of them? Split the hunks with s to consider each separately.
  2. For each hunk, do I want to commit it now? y or n.
  3. Or, do I know I want to add all the changes to the file? a.
  4. Or, discard the changes to the file? d.
  5. Do I want to edit this change? e, although this can be tricky if you aren’t comfortable editing diffs.

Consider each hunk, then commit the hunks you said y, or a, e to with:

$ git commit

Going Further

This is the only way that I commit, even for small changes. Why? I find it’s a nice default. And even for those small changes, I often am surprised to realize that I can break them down even more when reviewing them one-by-one.

To help, I’ve aliased this to gap, a trick I picked up at Hashrocket.

alias gap='git add --patch'

This flag also applies to git checkout, which is handy. Use it to checkout changes to a file, in pieces:

$ git checkout --patch