Undo part of unstaged changes in git

Git

Git Problem Overview


How do I undo parts of my unstaged changes in git but keep the rest as unstaged? The way I figured out is:

git commit --interactive
# Choose the parts I want to delete
# Commit the changes
git stash
git rebase -i master # (I am an ancestor of master)
# Delete the line of the most recent commit
git stash apply

This works, but it would be nice if there were something like git commit --interactive only for reverting changes. Any better methods?

Git Solutions


Solution 1 - Git

You can use git checkout -p, which lets you choose individual hunks from the diff between your working copy and index to revert. Likewise, git add -p allows you to choose hunks to add to the index, and git reset -p allows you to choose individual hunks from the diff between the index and HEAD to back out of the index.

$ git checkout -p file/to/partially/revert
# or ...
$ git checkout -p .

If you wish to snapshot your git repository beforehand to preserve these changes before reverting them, I like to do:

$ git stash; git stash apply

If you use that often, you might want to alias it:

[alias]
    checkpoint = !git stash; git stash apply

Reverting individual hunks or lines can be even easier if you use a good editor mode or plugin, which may provide support for selecting lines directly to revert, as -p can be a bit clumsy to use sometimes. I use Magit, an Emacs mode that is very helpful for working with Git. In Magit, you can run magit-status, find the diffs for the changes that you want to revert, select the lines you wish to revert (or simply put the cursor on hunks you wish to revert if you want to revert a hunk at a time instead of a line at a time), and press k to revert those specific lines. I highly recommend Magit if you use Emacs.

Solution 2 - Git

git diff > patchfile

Then edit the patchfile and remove the parts you don't want to undo, then:

patch -R < patchfile

Solution 3 - Git

You could do

git checkout master -- path/to/file

For each file you want to reset.

Solution 4 - Git

How about

  1. Back out the affected files with changes from the index
  2. use git add -p to only add back the changes that you want to the index.

Solution 5 - Git

When I run 'git status', it says:

$ git status
# On branch fr/fr.002
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   makefile
#
no changes added to commit (use "git add" and/or "git commit -a")
$

So, to cancel the unstaged edits, it tells me to run:

git checkout -- makefile

Solution 6 - Git

Brian Campbell's answer crashes my git, version 1.9.2.msysgit.0, for reasons unknown, so my approach is to stage hunks I want to keep, discard changes in the working copy, then unstage.

$ git add -p
   ... select the hunks to keep
$ git checkout -- .
$ git reset HEAD .

Solution 7 - Git

you can do git checkout and give it name names of the parts you want to undo.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionasmeurerView Question on Stackoverflow
Solution 1 - GitBrian CampbellView Answer on Stackoverflow
Solution 2 - Gitoctoberblu3View Answer on Stackoverflow
Solution 3 - GitDrew HoskinsView Answer on Stackoverflow
Solution 4 - GitAbizernView Answer on Stackoverflow
Solution 5 - GitJonathan LefflerView Answer on Stackoverflow
Solution 6 - GitG-WizView Answer on Stackoverflow
Solution 7 - GitAndrewView Answer on Stackoverflow