Selectively revert or checkout changes to a file in Git?

Git

Git Problem Overview


Is there a command that allows you to partially undo the changes to a file (or files) in the working directory?

Suppose you have edited a file a lot but you realize that you want to undo some of the changes back to the committed state, but not the other changes.

I'm envisioning an option for git checkout that works a lot like git add -p, i.e. it goes through the file hunk by hunk and asks if you want to keep it or not.

Git Solutions


Solution 1 - Git

With git version >= 1.7.1 I can

git checkout -p

I am not sure when this feature was introduced.

Solution 2 - Git

You could use

git add -p <path>

to stage the chunks that you want to keep in a particular file, then

git checkout -- <path>

to discard the working tree changes that you didn't want to keep, by checking out the staged version of the file.

Finally, you can use

git reset -- <path>

to revert the staged version of the file to the most recent committed version of the file to leave you with your changes unstaged.

Solution 3 - Git

git checkout $file reverts the state of the file $file to the last committed state. I think you can use git checkout SHA-1 -- $file to revert the file to the commit identified by SHA-1.

Solution 4 - Git

How many commits do you need to go back and select from? If it's just one, maybe take a branch just before it, checkout the file you committed and then use git add -p to add it how you wanted it. Then you can go back to where you were and checkout the file from your temp branch.

that is:

git checkout -b temp troublesome-commit^
git checkout troublesome-commit -- path/to/file
git add -p path/to/file
git commit -c troublesome-commit
git checkout @{-1}
git checkout temp -- path/to/file
git commit path/to/file
git branch -D temp

Other alternatives include going back and editing the commit with git rebase -i (marking the commit as edit, then doing a git reset HEAD^ and redoing the commit when dropped back into the shell).

If the changes you need to select from are spread over a series of commits, it may be better to extract them as patches (or a patch covering all of them) and hand-edit the patch, taking out the changes you want to keep, and feeding the residual into git apply --reverse.

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
Question1800 INFORMATIONView Question on Stackoverflow
Solution 1 - GitthisgeekView Answer on Stackoverflow
Solution 2 - GitCB BaileyView Answer on Stackoverflow
Solution 3 - GitKoraktorView Answer on Stackoverflow
Solution 4 - GitaraqnidView Answer on Stackoverflow