since 1999

 

3 minutes estimated reading time.

Manually Editing Git Hunks: The Easy Way

Christopher Choi

If you’ve been following our Git related posts, you probably notice we use git add --p with many of the examples used. This a great way for developers to split up code changes on one file to their own commit message. Not only will this make your pull requests cleaner, but will allow the code reviewer to get valuable context when diving into code changes on said file.

Git add patch gives us many options: Stage this hunk [y,n,q,a,d,e,?]?, the split option allows us to split lines that are close in proximity to each other. There are times where split won’t conveniently break up lines into hunks, lets explore how we can manually edit those tricky splits.

git add --patch

Lets begin with how we could use git add --patch to keep relevant code changes grouped:

Suppose we are recommended to extract some functionality into their own methods. We could go about this by adding and committing these changes as a fix in response to the code review.

$ git add app/models/user.rb -p
diff --git a/app/models/user.rb b/app/models/user.rb
index b5f941a..baa0bdb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -17,4 +17,12 @@ class User < ApplicationRecord
+  def method_a
+    puts 'bar'
+  end
+
+  def method_b
+    puts 'sla'
+  end
 end
Stage this hunk [y,n,q,a,d,e,?]?

Adding them all grouped together with commit messages like Fix up feature A and B for code review can make the PR look untidy before squashing and merging it. What we could do instead is split these patches with the split option to keep it tidy:

Stage this hunk [y,n,q,a,d,e,?]? s
Sorry, cannot split this hunk

Doh! We can’t split this hunk when code changes are too close together, the split option can’t conveniently split up those changes into hunks. We need to get into the weeds and use e(manual) in order to split this manually into separate hunks.

1 # Manual hunk edit mode -- see bottom for a quick guide.
  2 class User < ApplicationRecord
  3 +
  4 +  def method_a
  5 +    puts "bar"
  6 +  end
  7 +
  8 +  def method_b
  9 +    puts "sla"
 10 +  end
 11  end
 12 # ---
 13 # To remove '-' lines, make them ' ' lines (context).
 14 # To remove '+' lines, delete them.
 15 # Lines starting with # will be removed.

Like the instructions say, if we want to first add in the method_a changes, we would need to remove lines 7 to 10 in order to only add lines 3 to 6 to our staging area.

1 # Manual hunk edit mode -- see bottom for a quick guide.
  2 class User < ApplicationRecord
  3 +
  4 +  def method_a
  5 +    puts "bar"
  6 +  end
 11  end
 12 # ---
 13 # To remove '-' lines, make them ' ' lines (context).
 14 # To remove '+' lines, delete them.
 15 # Lines starting with # will be removed.

Once the unwanted hunks are removed, we can exit and save out of the editor session. The changes that we manually hunked are now ready to be committed to our local repository. By utilizing manual hunk, manually editing splits not only keeps relevant changes with their commits, it also helps the code reviewer to navigate through our commits with ease!