Git interactive unstage part of a file or by hunks
Solution 1:
If I am not mistaken, what you want is to unstage hunks interactively? I thought git reset -p
does exactly that. Its prompt message is even exactly like Unstage this hunk?
Also from the manual:
This means that git reset -p is the opposite of git add -p, i.e. you can use it to selectively reset hunks. See the “Interactive Mode” section of git-add(1) to learn how to operate the --patch mode.
Solution 2:
I found this answer very helpful when learning staging, so I thought I'd modify it for unstaging, as I haven't found a thorough answer on stackoverflow to this "How to git unstage one line or part of a file?" question.
As @manojlds says, you can use git reset --patch <filename>
(or -p
instead of --patch
for short), and git will begin to break down your file into what it thinks are sensible "hunks" (portions of the file).
Git will then prompt you with a variant of this question:
Unstage this hunk [y,n,q,a,d,g,/,j,J,k,K,s,e,?]?
Here is a description of each option:
- y unstage this hunk from the next commit
- n stage this hunk for the next commit
- q quit; do not unstage this hunk or any of the remaining hunks
- a unstage this hunk and all later hunks in the file
- d do not unstage this hunk or any of the later 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 hunk help
NOTES ABOUT e MANUAL EDITING: Be extra careful when using the edit (e
) mode above as it is not intuitive. I'll include and then revise the in-line git documentation:
# To remove '+' lines, make them ' ' lines (context).
# To remove '-' lines, delete them.
# Lines starting with # will be removed.
Revised for clarity:
- All lines starting with
+
are lines currently staged to be added which will now be unstaged. To keep+
lines from being unstaged (i.e. to leave them as staged changes), replace the initial+
with a space character. - All lines starting with
-
are lines currently staged to be deleted which will now be unstaged. To keep-
lines from being unstaged (i.e. to leave them as staged changes), delete each line entirely. - All lines with #, are comment lines and do not affect the content of the commit.
- Perhaps also keep in mind @Daniel-Alder's comment, to avoid accidentally unstaging the whole hunk.
Afterwards, you can use:
-
git diff --staged
to check that you unstaged/staged the correct changes -
git add -p
to stage mistakenly removed hunks -
git commit -v
to view your commit while you edit the commit message.
Reference for future: Git Tools - Interactive Staging