Reverting specific commits from git

Sankar picture Sankar · Dec 2, 2013 · Viewed 57.4k times · Source

I have a git tree with a lot of commits and a lot of files. Now, I want to revert specific commits that touch a file only. To explain:

> git init
Initialized empty Git repository in /home/psankar/specific/.git/
> echo "File a" > a
> git add a ; git commit -m "File a"
[master (root-commit) 5267c21] File a
 1 file changed, 1 insertion(+)
 create mode 100644 a
> echo "File b" > b
> git add b; git commit -m "File b"
[master 7b560ae] File b
 1 file changed, 1 insertion(+)
 create mode 100644 b
> echo "File c" > c
> git add c; git commit -m "File c"
[master fd6c132] File c
 1 file changed, 1 insertion(+)
 create mode 100644 c
> echo "b and c modified" > b ; cp b c
> git commit -a -m "b and c modified"
[master 1d8b062] b and c modified
 2 files changed, 2 insertions(+), 2 deletions(-)
> echo "a modified" > a
> git commit -a -m "a modified"
[master 5b7e0cd] a modified
 1 file changed, 1 insertion(+), 1 deletion(-)
> echo "c modified" > c
> git commit -a -m "c modified"
[master b49eb8e] c modified
 1 file changed, 1 insertion(+), 1 deletion(-)
> git log --pretty=oneline c
> git log --pretty=oneline c | cat
b49eb8e03af331bddf90342af7d076f831282bc9 c modified
1d8b062748f23d5b75a77f120930af6610b8ff98 b and c modified
fd6c13282ae887598d39bcd894c050878c53ccf1 File c

Now I want to revert just the two commits b49eb8 and 1d8b06 without reverting the changes to a. IOW revert only the commits in a file (without reverting other intermediate commits (which may be thousands in number) in different files) How is this possible ?

Answer

mamapitufo picture mamapitufo · Dec 2, 2013

You can use git revert with the --no-commit option. In your example:

$ git revert --no-commit b49eb8e 1d8b062
# Files that were modified in those 2 commits will be changed in your working directory
# If any of those 2 commits had changed the file 'a' then you could discard the revert for it:
$ git checkout a
$ git commit -a -m "Revert commits b49eb8e and 1d8b062"

If you don't provide a commit message then a prepared message will be available when the commit message editor is started.

If you omit the --no-commit option then the changes in the commits you specify will be reverted. This is achieved by applying the reverse of the changes in the specified commits and committing that. This results in a new commit, both the original and the reverted commit will be in the history of your repository.