Rollback to an old commit using revert multiple times
I want to rollback to a commit using git revert so I can preserve the history. Is there an easier way to do this then to run git revert for every commit hash I want to revert? Is there a quicker way to revert from a specific commit all the w开发者_StackOverflow社区ay up to another commit hash?
On the man page they state that you can do something like this git revert -n master~5..master~2
but when I try to do that I get this error: fatal: Cannot find 'master~5..master~2'
git revert
should take a single commit, so that error is complaining that you're giving it a list of revisions where it's expecting one. (Update: thanks to Jefromi for pointing out that since 1.7.2, git revert
actually can take multiple commits.) I'll suggest three possible courses of action below:
Creating multiple revert commits
I'm not sure if you can do this in one command, but if you know that db0bc
is the last good commit (i.e. you want to revert every commit after that) and the history is linear, you could do:
for s in $(git rev-list --reverse db0bc..)
do
git revert --no-edit $s
done
Going straight back to the old state, but still on one branch
On the other hand, if you just care about the history being there, you could always make the next commit be the state of the source tree back at the last good commit db0bc
without introducing revert commits - you'll still have the history that was introduced between then and your new commit, but without lots of revert commits in between. Also this won't have trouble if the history is non-linear:
# Check that "git status" is clean:
git status
# Set the index (staging area) to be as it was at commit db0bc:
git read-tree db0bc
# Create a commit based on that index:
git commit -m "Going back to the state at commit db0bc"
# Your working tree will still be as it was when you started, so
# you'll want to reset that to the new commit:
git reset --hard
Create a new branch for the old commits
If you're the only person working on the project, or you haven't pushed master yet, or you know that resetting your master branch won't cause problems, you could take an alternative tack, and create a new branch at your current position and then reset master back, as described nicely on github's "undoing" page. In short you could do:
# Make sure you're on master:
git checkout master
# Check that "git status" is clean, since later you'll be using "git reset --hard":
git status
# Create a new branch based on your current HEAD:
git branch unwanted-work
# Reset master back to the last good commit:
git reset --hard db0bc
The diagrams on that github page make this nice and clear, I think.
IMHO the most natural approach is to do (assuming you have a clean working copy):
git reset --hard $lastnicecommit;
git merge -s ours @{1}
and then git commit --amend
to add some description. (On newer versions of git git-merge
already lets you specify a description.)
(@{1}
is just referring to the commit your branch pointed to before the reset.)
This makes a fast-forward change and so documents the history completely. Still the changes introduced in the commits since $lastnicecommit
don't introduce any changes.
精彩评论