I'm manually reviewing a huge number of changes (in the 1000s) made by a search and replace script over some message catalogs. At the moment I'm doing git add -p
, but I keep taking breaks to check other files or adjust the script, so I'm alternating that with git checkout -p
to discard the changes I don't want. Is there a way to combine the two? I.e. for each hunk I want the option to stage it, or discard it.

- 8,812
- 5
- 31
- 51
-
I'm having the same problem. Using `git add -p` to select some hunks I would like in my first commit. Switching to `git checkout -p` to discard some. Adding more. Commit and then add all that's left for a second commit. Would be great to combine add and checkout! – Tieme Jan 13 '16 at 15:58
5 Answers
If you are using Windows or Mac OS you can use free SourceTree GUI app that allows you to stage or discard each hunk (or even select lines from each hunk) in the diff view.

- 13,042
- 3
- 41
- 59
-
Yeah that would be workaround. I was looking for a cli solution. Bu thanks anyway :) – Tieme Jan 20 '16 at 09:41
how about typing j - leave this hunk undecided, see next undecided hunk
for hunks which you don't want to stage,
and after all of these, run git checkout --
, then those hunks selected will be staged, and other discarded.
when you are using git add -p
, typing ?
will show the help
Stage this hunk [y,n,q,a,d,/,e,?]?
y - stage this hunk
n - do not stage this hunk
q - quit, do not stage this hunk nor any of the remaining ones
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining 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
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

- 79
- 7
-
Always using `j` for all hunks you don't want to stage will get you in a loop... You could use `n` for alle you don't want to stage and then then `git checkout --` afterwards indeed.. but that won't work for the case I tried to describe in my comment beneath the question. – Tieme Jan 21 '16 at 08:36
Have you had a look at git gui. It is a utility that comes bundled with git these days and is tries to make it easy to do complex operations which are mix of staging and checkout. You can read about it here
You can choose to stage a hunk and discard the rest of changes. By doing ctrl + j
or cmd + j
you can checkout the selected file.
I know its much faster to use git from shell, but in complex cases like these, switching between different commands becomes a overhead.

- 2,098
- 1
- 10
- 13
That is closer with Git 2.28 (Q3 2020)!
Before, "git checkout -p
" did not handle a newly added path at all.
See commit 2c8bd84 (27 May 2020) by Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
-- in commit 2bdf00e, 09 Jun 2020)
checkout -p
: handle new files correctlyReported-by: Merlin Büge
Helped-by: Jeff King
Signed-off-by: Johannes SchindelinThe original patch selection code was written for
git add -p
, and the fundamental unit on which it works is a hunk.We hacked around that to handle deletions back in 24ab81ae4d ("
add-interactive
: handle deletion of empty files", 2009-10-27, Git v1.6.6-rc0 -- merge).
Butgit add -p
would never see a new file, since we only consider the set of tracked files in the index.However, since the same machinery was used for
git checkout -p
& friends, we can see new files.Handle this case specifically, adding a new prompt for it that is modeled after the
deleted file
case.This also fixes the problem where added
_empty
_ files could not be staged viagit checkout -p
.
So the prompt for git checkout -p
now includes:
Discard mode change from worktree [y,n,q,a,d%s,?]?
Discard deletion from worktree [y,n,q,a,d%s,?]?
Discard addition from worktree [y,n,q,a,d%s,?]? <===
Discard this hunk from worktree [y,n,q,a,d%s,?]?
If you discard what you don't want, and commit what you need, then a git add $(git ls-files -o --exclude-standard)
will add the new remaining files.

- 1,262,500
- 529
- 4,410
- 5,250
stage all you need, commit and then reset or stash to clean the working dir to get rid of what you don't need.

- 124,556
- 26
- 146
- 141