Using Gits Patch functionality to commit parts of a file

Wed, 01/14/2015 - 22:38

Have you ever been going through some code while working on a feature and found some minor things that needed to be fixed and you just couldn't help yourself but fixed them right away? I know I have. More than once. The issue is that when I'm done with the original feature I will have some changes in the same file that shouldn't be in that same commit. What to do?

If the changes were in different files it would be easy just to add the files you needed and commit them, but when they are in the same file you either have to commit everything in one go or remove some of you changes. Or use Gits patch functionality.

Git allows you to add only parts of a file to staging. The only requirement for this is that there changes are separated into blocks, meaning there should be unchanged lines between them.

How you actually do it differs a bit between git versions. The guide below is for to be precise. I am working on Ubuntu 10.04. (I know, it's old).

When you are ready to commit your changes you take each file individually (if you have more than one), and do

git add --patch filename.ext

The --patch argument will make git prompt each code block in the file to you with some options. There are several options, but the basic ones you need are y for yes and n for no. It will look something like this:

@@ -231,6 +235,10 @@ function some_function($a, $b) {
     $defaults = _get_defaults();

+    if ($b > 10) {
+      $defaults[$a] = $b;
+    }

     return $defaults;
Stage this hunk [y,n,q,a,d,/,K,g,e,?]

All the hunks of code you write y and hits enter to will be staged. If you hit n it will not be staged. When there are no more hunks of code, the program will exit.

To make sure you know what will be commited you can do a git diff --staged to see a diff of only the things that are staged. You can now commit normally by doing git commit -m "Add $b to defaults".

WARNING: Don't do git commit -am "Add $b to defaults", since the -a will cause all changed files to be added automatically.