Skip to content
HN On Hacker News ↗

Staging patches with git add

▲ 34 points 52 comments by ankitg12 4w ago HN discussion ↗

Pangram verdict · v3.3

We believe this text is mainly human-written, with some AI content.

5 %

AI likelihood · overall

Human
95% human-written 5% AI-generated
SEGMENTS · HUMAN 2 of 3
SEGMENTS · AI 0 of 3
WORD COUNT 881
PEAK AI % 58% · §2
Analyzed
Jul 29
backend: pangram/v3.3
Segments scanned
3 windows
avg 294 words each
Distribution
95 / 5%
human / AI fraction
Verdict
Human
Pangram v3.3

Article text · 881 words · 3 segments analyzed

Human AI-generated
§1 Human · 0%

IntroductionIf you’re not already using git add -p to stage your commits then you’re missing out. It allows you to interactively stage a file or just part of it giving you greater control over your git commit process.Why should you want to do this?Here are some of the reasons why I prefer using git add -p in my workflow. Primarily, because it allows me to review my changes as I stage them and I often find mistakes this way.

§2 Mixed · 58%

By reviewing changes during staging, I catch bugs, typos, and other issues that might have slipped through during initial coding or content creation.There is an additional benefit though; it allows me to stage only part of file.

§3 Human · 3%

Git, rather oddly, refers to these parts as hunks so I will use that term going forward.This feature is really useful when you have a number changes, but you want to group them up into different commits. Imagine you’ve made several related changes across different parts of a file. With git add -p, you can selectively stage these changes together, ensuring cleaner and more organized commits.Staging part of a fileHere is an example of the interface showing you the diff and then prompting you to “Stage this hunk?”.diff --git a/main.mts b/main.mts index e1132f2..8f7c279 100644 --- a/main.mts +++ b/main.mts @@ -1,2 +1,4 @@ export const add = (a, b) => a + b +export const div = (a, b) => a / b export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) +export const avg = (xs) => div(sum(xs), xs.length) (1/1) Stage this hunk [y,n,q,a,d,s,e,?]? In its simplest form we can enter y to stage that diff ready for commit or n not to. For this example I am not ready to commit the avg function, but I want to get div pushed up so I choose to enter s to split the hunk into smaller hunks. Git then asks me this.Split into 2 hunks. @@ -1,2 +1,3 @@ export const add = (a, b) => a + b +export const div = (a, b) => a / b export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? So I enter y to stage that hunk for commit and git responds with the next hunk.@@ -2 +3,2 @@ export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) +export const avg = (xs) => div(sum(xs), xs.length) (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? Remembering that I only want to commit the div function I then enter q to quit the interactive hunk staging.After interacting with the hunk staging, I return to the command prompt. From there, I can proceed with git commit or any other necessary commands.Checking it workedIf I were to run a git status to check the staged files I would see that the fil (main.mts) appears in both sections; to be committed and not staged for commit. This is because we only staged part of the file and it is what we wanted!On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits)

Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: main.mts

Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: main.mts By selectively staging only part of the file, we’ve successfully prepared a single hunk—a patch—for our upcoming commit.Other optionsThe list ([y,n,q,a,d,s,e,?]) of potential responses is shortened, but you can get extended information by entering ? to get the help documentation.Here are some response options you can use during interactive hunk staging taken from the git documentation. You’ll notice that there are a lot more options than in the list we saw earlier.y: stage this hunkn: do not stage this hunka: stage this and all the remaining hunks in the filed: do not stage this hunk nor any of the remaining hunks in the fileg: select a hunk to go to/: search for a hunk matching the given regexj: leave this hunk undecided, see next undecided hunkJ: leave this hunk undecided, see next hunkk: leave this hunk undecided, see previous undecided hunkK: leave this hunk undecided, see previous hunks: split the current hunk into smaller hunkse: manually edit the current hunk?: print helpWhen not to use itI use git add -p nearly every time I commit every working day. There are two occasions where I don’t:There is a newly created file to commit for the first time - when a file is newly created there is no previous version to diff against of course so git add -p cannot present a diff for you to approve for staging.In rare cases, when I want to commit an entire directory and am confident about its content, I usually opt for the standard approach. However, even in such edge cases, I often find myself using git add -p for finer control.ConclusionBy incorporating git add -p into your workflow, you’ll streamline your git and commit process.. I use this technique, without exaggeration, nearly every single time I need to commit a changeset to git. It allows me to easily review my code as I stage it for commit and control exactly what goes into each of my commits.