I have a git repository that looks like this:
A <- B <- C <- D <- HEAD
I want the head of the branch to point to A, i.e. I want B
Similar to Jakub's answer, this allows you to easily select consecutive commits to revert.
# revert all commits from B to HEAD, inclusively
$ git revert --no-commit B..HEAD
$ git commit -m 'message'
git reset --hard a
git reset --mixed d
git commit
That will act as a revert for all of them at once. Give a good commit message.
For doing so you just have to use the revert command, specifying the range of commits you want to get reverted.
Taking into account your example, you'd have to do this (assuming you're on branch 'master'):
git revert master~3..master
or git revert B...D
or git revert D C B
This will create a new commit in your local with the inverse commit of B, C and D (meaning that it will undo changes introduced by these commits):
A <- B <- C <- D <- BCD' <- HEAD
First be sure that your working copy is not modified. Then:
git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply
and then just commit. Don't forget to document what's the reason for revert.
If you want to temporarily revert the commits of a feature, then you can use the series of following commands.
Here is how it works
git log --pretty=oneline | grep 'feature_name' | cut -d ' ' -f1 | xargs -n1 git revert --no-edit
I really wanted to avoid hard resets, this is what I came up with.
A -> B -> C -> D -> HEAD
To go back to A (which is 4 steps back):
git pull # Get latest changes
git reset --soft HEAD~4 # Set back 4 steps
git stash # Stash the reset
git pull # Go back to head
git stash pop # Pop the reset
git commit -m "Revert" # Commit the changes