Reputation: 55934
How can I revert a range of commits in git? From looking at the gitrevisions documentation, I cannot see how to specify the range I need. For example:
A -> B -> C -> D -> E -> HEAD
I want to do the equivalent of:
git revert B-D
where the result would be:
A -> B -> C -> D -> E -> F -> HEAD
where F contains the reverse of B-D inclusive.
Upvotes: 214
Views: 106526
Reputation: 7729
How to revert a range of commits with one single revert commit
If you want to revert commit range B to D (at least in git version 2) in a single commit, you can do:
git revert -n B^..D
git commit -m "revert the commit range B to D, inclusive"
The -n
(or --no-commit
) argument tells git to revert the changes done by the commits starting from B's parent commit (excluded) to the D commit (included), but not to create any commit with the reverted changes. The revert only modifies the working tree (your active file system) and the index (your staged file section).
Don't forget to commit the changes after running git revert -n
:
git commit -m "revert the commit range B to D, inclusive"
You can also revert multiple unrelated commits in a single commit, using the same method. For example: to revert B and D but not C:
git revert -n B D
git commit -m "Revert commits B and D"
References:
https://www.kernel.org/pub/software/scm/git/docs/git-revert.html
Thanks Honza Haering for the correction.
From man git revert
:
-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.This is useful when reverting more than one commits' effect to your index in a row.
Upvotes: 42
Reputation: 9712
Doing git revert OLDER_COMMIT^..NEWER_COMMIT
didn't work for me.
I used git revert -n OLDER_COMMIT^..NEWER_COMMIT
and everything is good. I'm using git version 1.7.9.6
.
Upvotes: 14
Reputation: 1329202
What version of Git are you using?
Reverting multiple commits in only supported in Git1.7.2+: see "Rollback to an old commit using revert multiple times." for more details.
The current git revert
man page is only for the current Git version (1.7.4+).
As the OP Alex Spurling reports in the comments:
Upgrading to 1.7.4 works fine.
To answer my own question, this is the syntax I was looking for:
git revert B^..D
B^
means "the first parent commit of B": that allows to include B
in the revert.
See "git rev-parse
SPECIFYING REVISIONS section" which include the <rev>^
, e.g. HEAD^
syntax: see more at "What does the caret (^
) character mean?")
Note that each reverted commit is committed separately.
Henrik N clarifies in the comments:
git revert OLDER_COMMIT^..NEWER_COMMIT
As shown below, you can revert without committing right away:
git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"
Upvotes: 263
Reputation: 60711
Use git rebase -i
to squash the relevant commits into one. Then you just have one commit to revert.
Upvotes: -2