The problem: A branch has good commits interleaved with undesired ones.
Attempted solution:
git revert hash5 hash8 hash9 hash23
What I thought this would do is that it'd apply all specified commits, and then let me sort out any conflicts.
What I now think that happens:
Question: How do I get git to apply all the reverts in a row before presenting any possible conflicts to me?
The easiest way to undo the last Git commit is to execute the “git reset” command with the “–soft” option that will preserve changes done to your files. You have to specify the commit to undo which is “HEAD~1” in this case. The last commit will be removed from your Git history.
Revert uncommitted changes In the Commit tool window Alt+0 , select one or more files that you want to revert, and select Rollback from the context menu, or press Ctrl+Alt+Z .
First, note that git revert
reverts your patches in the order you list their hashes; you need to list the hashes from newest to oldest, since you want to proceed backwards in time. So, I'm going to call your hashes
<hash1> ... <hashN>
where <hash1>
is older than <hash2>
... is older than <hashN>
. So, make sure you were doing
git revert <hashN> ... <hash1>
in the first place!
Second, assuming you had been reverting them in the right order, try the --no-commit
option:
git revert --no-commit <hashN> ... <hash1>
Third, If the easy solution doesn't work well, but the commits you want to revert really do make sense as a single commit (if not I don't see much hope), then try this: build one big commit out of the four you want to revert, and then revert the big commit.
Build the big commit:
Create a branch at the parent of the oldest commit:
git checkout -b big-commit <hash1>~
Copy the commits on your new branch and collapse them:
git cherry-pick --no-commit <hash1> ... <hashN>
git commit -m "Big commit"
You should now have one big commit on your branch big-commit
.
Apply the big commit in reverse to the branch you're trying to revert:
git checkout <branch you wanted to revert on>
git revert big-commit
Use selective rebasing to rebuild the branch in question as if it never contained the unwanted commits:
Create a new rebuild
branch to work in:
git checkout -b rebuild <branch you want to revert>
Interactively rebase, dropping the commits you don't want:
git rebase -i <hash1>~
In the interactive rebase editor, delete the lines for <hash1>
... <hashN>
.
Now your rebuild
branch will contain <branch you want to revert>
, as though <hash1>
... <hashN>
never existed. If you run into conflicts here it would seem they're unavoidable.
If you need your work to be on <branch you want to revert>
, and you can't just git reset
it to point to your new rebuild
branch:
git checkout <branch you want to revert>
git reset --hard rebuild
(e.g. because you've already pushed it publicly), then you can instead apply the differences to <branch you want to revert>
as a patch:
git co <branch you want to revert>
git diff <branch you want to revert> rebuild | patch
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With