Is it possible to revert only a single file or certain changes in a file in multi file commit?
Full story I committed a bunch of files. A number of
You can revert the commit without creating a new one by adding the '--no-commit' option. This leaves all the reverted files in the staging area. From there, I'd perform a soft reset and add in the changes I really wanted. For an example workflow:
git revert <sha-of-bad-commit> --no-commit
git reset // This gets them out of the staging area
<edit bad file to look like it should, if necessary>
git add <bad-file>
git checkout . // This wipes all the undesired reverts still hanging around in the working copy
git commit
You can just manually check out the old, good contents of the files you want to revert using git checkout
. For instance, if you want to revert my-important-file
to the version it was in the version abc123
, you can do
git checkout abc123 -- my-important-file
Now you have the old contents of my-important-file
back, and can even edit them if you feel like, and commit as usual to make a commit which will revert the changes that he made. If there are only some parts of his commit that you want to revert, use git add -p
to select only a few hunks from the patch that you are committing.
I found a way to do this on the Git mailing list:
git show <commit> -- <path> | git apply --reverse
Source: http://git.661346.n2.nabble.com/Revert-a-single-commit-in-a-single-file-td6064050.html#a6064406
That command fails (causing no changes) if the patch does not apply cleanly, but with --3way
you instead get conflicts which you can then resolve manually (in this case Casey's answer might be more practical):
git show <commit> -- <path> | git apply --reverse --3way
You can also use this to partially revert multiple commits, e.g.:
git log -S<string> --patch | git apply --reverse
to revert files with changes matching <string>
in any commit. This is exactly what I needed in my use case (a few separate commits introduced similar changes to different files, along with changes other files in unrelated ways that I did not want to revert).
If you have diff.noprefix=true
set in your ~/.gitconfig
then you need to add -p0
to the git apply
command, e.g.
git show <commit> -- <path> | git apply -p0 --reverse
You can interactively apply old version of a file using the checkout
command.
For example, if you know the COMMIT
where the code to add back was removed, you can run the following command:
git checkout -p COMMIT^ -- FILE_TO_REVERT
Git will prompt you to add back the hunks that are missing from the current version of the file. You can use e
to create a patch of the change before applying it back.