how to finish reverting a commit, and how to revert a lot of commits
Asked Answered
S

3

27

This has to be simple, but I can't find it in git-scm.

I've been making a lot of small commits to a public project, and all of my work is bad. I want to remove everything that I've done. Some I've just committed locally, some I've pushed to 'origin master'.

The first commit (a week ago) is bdbad86... with the most recent being e82401b...

I want to just make all these go away. I've tried to revert one.

git status  
# On branch master  
# You are currently reverting commit e82401b.  
#   (all conflicts fixed: run "git revert --continue")  
#   (use "git revert --abort" to cancel the revert operation)  
  1. I can't figure out how to finish this reverting.
  2. I don't want to have to do each commit separately, I want to blow them all away.
Stancil answered 16/12, 2013 at 5:37 Comment(1)
git revert --abort worked for me.Gordan
P
9

I'm assuming here that no one else interjected commits in between your work, and that you bad commits form a continuous range in the repo's history. Otherwise you're going to have to get more complicated. Let's assume your history looks like this:

e82401b - (master, HEAD) My most recent private commit
...
bc2da37 - My first private commit
cf3a183 - (origin/master) My most recent bad public commit
...
292acf1 - My first bad public commit
82edb2a - The last good public commit

The first thing we want to do is blow away the commits that you haven't made public yet. You can do this with the following command (note that your changes will be gone and should be considered unrecoverable):

git reset --hard cf3a183 

Equivalently (and more readable):

git reset--hard origin/master

Now your view of the repository agrees with the view in origin/master. You now want to revert your bad public changes and publish them as a revert commit. These instructions are for creating a single revert commit.

You can use git revert --no-commit a..b to revert all the commits starting at the commit after a (note that!) and ending at, and including, commit b. The reversion will be staged for you to commit. So, here, we would do:

git revert --no-commit 82edb2a..HEAD

Or, equivalently:

git revert --no-commit 292acf1^..HEAD

Remembering that HEAD now points to the same place as origin/master.

After running the revert command you now have your changes staged and ready to commit, so just run a simple git commit -m "Reverting those bad changes I accidentally pushed and made public".

Pops answered 16/12, 2013 at 6:2 Comment(2)
Thanks, this is the kind of information I needed. One additional question: how do I get the (master, HEAD) or (origin/master) information so I can tell when to do the two sets of commands?Stancil
@Pat The easiest way is to set up an alternative form of git log to get this information at a glance. You can read here about the format to use. A good starting base is something like this: git log --pretty="%h %Cgreen%d%Creset %s %an %Cblue(%cr)"Pops
S
9

Instead of running

git revert --continue

Just run

git commit -m "commit message here"

If that doesn't work, make sure you've staged all the files involved in the revert. Even the files that you reverted and then discarded changes to.

Spadefish answered 21/5, 2020 at 13:59 Comment(1)
I found I was still stuck in the reverting state, even though I had committed everything. I had to run git commit -m "empty commit to escape revert" --allow-empty, but that seems to have fixed it.Amnion
R
2

This question is already answered correctly, but I just want to address the first point of op's question -- I can't figure out how to finish this reverting. if you too were stuck in revert state like me and got here searching for an answer.

it can be straightforward as git revert --continue. but only if you're reverting some changes inside a file. if you get stuck in revert state, that's most likely because you're trying to revert a commit that created a file and that file is modified in any of the subsequent commit.

take an example:

1c40cd3 added fileB
4e06828 added fileA
faf29dd (origin/main, origin/HEAD, main) Merged in feature5 (pull request #13)
6e735e3 (origin/feature5, feature5) updated file.txt
fb51fca added file.txt
744ba74 Initial commit

now, if you're trying to revert fb51fca (added file.txt), it will show you something like:

$ git revert fb51fca
CONFLICT (modify/delete): file.txt deleted in parent of fb51fca (added file.txt) and modified in HEAD.  Version HEAD of file.txt left in tree.
error: could not revert fb51fca... added file.txt
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".

$ git status
On branch feature6
You are currently reverting commit fb51fca.
  (fix conflicts and run "git revert --continue")
  (use "git revert --skip" to skip this patch)
  (use "git revert --abort" to cancel the revert operation)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add/rm <file>..." as appropriate to mark resolution)
        deleted by them: file.txt

you can clearly see file.txt deleted in fb51fca (added file.txt) and modified in HEAD. Version HEAD of file.txt left in tree.. now, you can do git add -A and git commit ... BUT

what revert does is goes back in history (in the specified commit), removes the changes that were done in that commit. and makes a new commit. but the issue is, you created a file, now revert is deleting it. in the end, there is no file left to stage and as you know, git doesn't allow empty directories or empty commits.

but there's a workaround for empty commits. as ryan suggested, you can do git commit -m "empty commit to escape revert" --allow-empty. git revert probably doesn't use this --allow-empty flag and that's probably the reason it can't do a commit gets stuck in revert state.

either way, if you get stuck in the revert state, you're probably doing something wrong. trying to revert something that doesn't make sense.

Ricercare answered 10/2, 2022 at 15:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.