114

Usually the command git revert automatically creates some commits with commit log messages stating which commits were reverted.

To avoid automatic commit there's the option -n (or --no-commit).

But after this command, the reverted files are in the staged area. I can unstage them by using the command git reset HEAD.

Is there a direct way to revert a commit without committing and staging?

In other words: is there a direct command to revert a commit applying the changes only to the working directory, without touching the index?

lornova
  • 6,667
  • 9
  • 47
  • 74
  • What would this look like? What does "reverting" mean if you don't have a change that reverts it? – Edward Thomson Nov 12 '15 at 15:01
  • 2
    I just want the local files with the reverted changes applied to them, with no commits and no handling of the staging area. That's what happens if you do `git revert -n && git reset HEAD` but I'd like to do it at once. – lornova Nov 12 '15 at 15:07
  • 4
    Aha, I understand - so you want the reverted changes applied to the workdir but not staged. Upon re-reading your question this does seem clear but my first read didn't parse that meaning correctly. – Edward Thomson Nov 12 '15 at 15:12
  • Probably it's my fault, I tried to clarify my intent in the question. – lornova Nov 12 '15 at 15:15
  • What in `git revert -n && git reset HEAD` is not "at once"? I mean, does it really matter whether you type `&&` and another `git` command versus an imaginary long argument name to `git revert` like `git revert --neither-commit-nor-stage `? – sschuberth Nov 12 '15 at 15:38
  • 1
    @sschuberth: those are two steps. Sure it doesn't hurts, but I just want to know if there's a direct way to accomplish that. – lornova Nov 12 '15 at 16:16
  • Not everything can be done in one command. Write a bash function to do this all at once if you really want to. – jaredready Nov 12 '15 at 16:27

1 Answers1

103

There is no single command for it. As you already noted, you can combine git revert -n with git reset to get the reversion undone in the index.

Besides that method, you can use git apply -R to "reverse apply" a patch, and you can turn a commit into a patch with git show, so:

$ git show <rev> | git apply -R

has the same effect, with one important (but subtle) difference. Let me quote from the git revert documentation and add my own emphasis:

-n, --no-commit
Usually the command automatically creates some commits with commit log messages stating which commits were reverted. This flag applies the changes necessary to revert the named commits to your working tree and the index, but does not make the commits. In addition, when this option is used, your index does not have to match the HEAD commit. The revert is done against the beginning state of your index.

In other words, git revert -n operates in, and on, the index, with a side effect of updating your work tree. The git apply command operates (by default anyway) on the work-tree only, and in fact can be used outside a git repository.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I got _error: unrecognized input_ . Any idea what could have gone wrong? – Robert Pankowecki Feb 16 '18 at 16:47
  • 1
    @RobertPankowecki: https://www.google.com/search?&q=git+apply+unrecognized+input has its first hit on a StackOverflow post about colorized diffs. That seems like the most likely problem. – torek Feb 16 '18 at 17:41
  • So how do I continue after making `git revert --no-commit` ? Nothing happens when I do `git revert --continue`. – Dr_Zaszuś Apr 18 '20 at 20:13
  • @Dr_Zaszuś: After `git revert --no-commit`, you just keep working as usual: edit files if you like, `git add` if/when you like, `git rm` if/when you like, and finally, `git commit`. – torek Apr 18 '20 at 21:11