21

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.

ZoFreX
  • 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 Answers5

4

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.

Stage/Discard hunk

Paul
  • 13,042
  • 3
  • 41
  • 59
0

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
Yi Tang
  • 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
0

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.

sandeep
  • 2,098
  • 1
  • 10
  • 13
0

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 correctly

Reported-by: Merlin Büge
Helped-by: Jeff King
Signed-off-by: Johannes Schindelin

The 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).
But git 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 via git 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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-1

stage all you need, commit and then reset or stash to clean the working dir to get rid of what you don't need.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141