0

Ok, I'm fairly familiar with git, including git revert and git reset. I think that what I want to do can't be done, but just wanted to double-check.

Let's assume I have a repo into which a colleague has made dozens of bad merge commits. I want to reset the repo back to the last known good commit. I don't want to use a reset and have to do a force push, because that will mess up the local copy of all my other colleagues. I also don't think revert can very easily be used to undo dozens of merge commits.

My best idea is to clone a second copy of the repo, checkout the right commit, and then go to my original local copy, make a branch, delete every file, and copy everything from the second repo. Then commit, push, merge normally. Can I improve on this?

timcrall
  • 75
  • 1
  • 9
  • Possible duplicate of [How can I revert multiple Git commits (already pushed) to a published repository?](https://stackoverflow.com/questions/10780228/how-can-i-revert-multiple-git-commits-already-pushed-to-a-published-repository) – Mureinik Jan 04 '18 at 20:12
  • @Mureinik Does that play nicely with merge commits? That particular issue wasn’t addressed there. – Daniel H Jan 04 '18 at 20:14
  • @DanielH it **should**, but I admit I haven't tried. Why don't you give it a try and tell us how it went? – Mureinik Jan 04 '18 at 20:15

3 Answers3

2

Yes, you could combine all this into operations on one git repo.

git checkout <branch in question>
rm -Rf * # This will leave the .git directory and any other hidden files in the root that you may need to manually further deal with
git checkout <good sha> -- .
git add .
# commit, test, etc. as required
Mort
  • 3,379
  • 1
  • 25
  • 40
0

Try this, for your commit hash <commit>:

git revert --no-commit <commit>..HEAD
git commit -m "Reverted a bunch of bad merges"
Harald Nordgren
  • 11,693
  • 6
  • 41
  • 65
  • Thanks - this will follow merged branches okay? Usually you have to use the -m for reverting branches so it know which path to take – timcrall Jan 04 '18 at 21:21
0

There is a one-liner option, if you don't mind running a plumbing command. With master (or whatever branch is going to receive the new "revert" commit) checked out:

 git reset --hard `git commit-tree -p HEAD -m "revert to last good state" <good-commit>^{tree}`

where <good-commit> is the ID (or some other valid name - maybe a tag, or an expression like HEAD~15) for the commit whose state you want.

This does use reset, but it does it in a way that honors the "normal" direction of branch movement, so no force-push and no clean-up of other repos will be needed.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • Thanks - not totally clear what that's doing but I'll try it out and read about commit-tree... – timcrall Jan 04 '18 at 21:20
  • You can also use `git read-tree --reset -u ; git commit`. See https://stackoverflow.com/a/48090390/1256452 – torek Jan 04 '18 at 21:34