Git-fu: Staging Changes Like a Pro with git add --patch

Git-fu: Staging Changes Like a Pro with git add --patch

I've been making an effort to know git in greater depth, so I wanted to share my progress. Through tools like GitKraken, I had learned of the idea of splitting up my files for staging, but I never understood how to do it in the terminal. Here is the rundown:

Why Bother with --patch?

Picture this: you’re knee-deep in a Python file, app.py, and you’ve added some great code while also making some changes that are not quite finished. You are working on two things in tandem in the same file but it wouldn't make sense to commit all of the code at once without making a huge commit message and messing up the organization of your repo. You want your finished portion of code in next commit, but not the unfinished code. Staging the whole file with git add app.py is going to ruin the clarity of your commits and make everything messy. Also, like functions, it's better to keep commits small, succinct, and with one purpose. Enter git add --patch, your secret to git success.

Let’s Get The Party Started

Imagine you are hypothetically writing a tax calculator with some debugging feature that you don't want to have committed. First, take a look at your chaos:

git status        

You’ll see something like:

Changes not staged for commit:
  modified:   app.py        

Now, deploy your ticket to eternal git glory:

git add -p app.py        

This will begin the process of breaking your code up into "hunks" of code and choosing to stage only the changes that you want. Everyone will be jealous of the party you are about to start.

The Party

Here’s what you might see:

diff --git a/app.py b/app.py
index abc123..def456 100644
--- a/app.py
+++ b/app.py
@@ -1,4 +1,7 @@
 def calculate_total(items):
     total = sum(items)
+    return total * 1.1  # Add 10% tax
+
+def debug_info():
+    print("Debugging session started")
Stage this hunk [y,n,q,a,d,s,e,?]?        

This has good code and some debug code to be ignored. Let’s break down what you can do.

The Interactive Toolkit of Git Honor and Fame

You have some options for how you want this party to go [y,n,q,a,d,s,e,?]. Here's what's happening:

  • y - Yes: Stage the whole thing. Type y, and both tax and debug hit the stage.
  • n - No: Don't stage any of it. This code is not invited to the party.
  • q - Quit: Party is over. q is a show-stopper, staging only what you’ve already picked.
  • a - All: Stage all the hunks in this file. a stages this hunk and everything else in the file.
  • d - Discard: Get rid of it. d removes this hunk of code from the file. Use with caution. You won't be able to undo this.
  • s - Split: This is what you want. s splits the hunk if Git can find a break point like an empty line. Perfect for separating the good from the bad code.
  • e - Edit: Editing with e will let you open an editor in your terminal to edit the code using vim.
  • ? - Help: Your lifeline. ? will display a message to give you guidance in case you haven't memorized everything I'm sharing in this article. I trust you won't need this, but just in case.

Splitting it up

Let’s say that hunk’s has some of the code that might ruin your party. Hit s:

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

Git might split it into:

@@ -1,3 +1,4 @@
 def calculate_total(items):
     total = sum(items)
+    return total * 1.1  # Add 10% tax
Stage this hunk [y,n,q,a,d,s,e,?]?        

And then:

@@ -4,0 +5,2 @@
+
+def debug_info():
+    print("Debugging session started")
Stage this hunk [y,n,q,a,d,s,e,?]?        

Now you can stage the calculator (y) and ditch the debug code (n). If it won’t split, the changes are too close together. Use e instead.

Check Yourself Before You Wreck Yourself

See what’s staged:

git diff --staged        

Output:

diff --git a/app.py b/app.py
index abc123..xyz789 100644
--- a/app.py
+++ b/app.py
@@ -1,3 +1,4 @@
 def calculate_total(items):
     total = sum(items)
+    return total * 1.1  # Add 10% tax        

Unstaged changes remain unstaged, preserving your magnificence:

git diff        

Output:

diff --git a/app.py b/app.py
index xyz789..def456 100644
--- a/app.py
+++ b/app.py
@@ -3,2 +3,5 @@
     return total * 1.1  # Add 10% tax
+
+def debug_info():
+    print("Debugging session started")        

Commit your masterpiece:

git commit -m "Add my good code like a pro"        

Pro Tips

  • Your Editor: Hate Vim? You're wrong... just kidding, but git config --global core.editor "nano" to use nano instead.
  • Patching all of the files at once: Skip the file name with git add -p to patch all your code at once.

TLDR

git add --patch is your ticket to eternal git prestige glory. It allows you to stage your code in hunks, edit, or split it up into smaller hunks. Split with s, edit with e, add a chunk y or n to skip it. You'll have clean commits and everyone on the internet will admire the clarity of everything you've ever made.

If you've made it this far, go write some code!

To view or add a comment, sign in

More articles by Jonathan Math

Others also viewed

Explore content categories