Search code examples
gitgit-revert

How to revert changes from old commit in a single file


How do I revert/remove the changes done in an older multi-file commit, but only do it in a single file? I.e. something like

git revert <commit-specifier> <file>

except git revert does not accept <file> argument. None of the following answers addresses this problem:

Git: Revert old commit on single file is rather about how to debug conflicts.

Undo a particular commit in Git that's been pushed to remote repos does not address my single file issue.

Git: revert on older commit also does not address single file issue.


Solution

  • Git is a tool-set, not a solution, so there are multiple solutions. However, one relatively straightforward way is to start with git revert -n, which starts the revert but does not finish it:

    git revert -n <commit-specifier>
    

    This tries to back out all changes to all files, of course. You only want to back out changes to one file. But now that git revert has made this attempt without committing you merely need to restore each file that you didn't want changed. Get a list of such files, and then use git checkout or git restore—using the commands exactly as git status advises—to make those files match the current commit. Now git status will show only the one file as changes to be committed, and you can now git commit that one file.

    Another relatively straightforward way is to use:

    git show <commit-specifier> -- <pathspec> | git apply -R
    

    You can add -3 to the git apply command if you'd like Git to use a three-way merge on the base version of the file; in this case it may help to add --full-index to the git show command options. (As with the cherry-pick -n method you will have to commit the result yourself.)