Contaminated Remote master branch or Anti-Cherry-Pick
Asked Answered
O

2

2

I have a situation where the remote repository has some "bad" commits. e.g.

... o ---- C ---- A ---- B  origin/master 

Where A is bad (but B is good) I want the remote to become...

... o ---- C ---- B  origin/master 
                   \
                    A  origin/dev 

It is not obvious to me how to do this.

In the case where a rebase is inappropriate a different result is needed.

... o ---- C ---- A ---- B ---- ~A origin/master 
                          \
                           -  origin/dev 

This results in a dev branch containing the A commit and the master not containing the A commit. The revised question is: How to do an anti-cherry-pick? So rather than generating a patch which changes the repository from state C to A apply a patch which changes B to A.

Outride answered 22/1, 2011 at 19:40 Comment(3)
Obviously a rebase on a shared repository is bad form. In this case it is acceptable. In general though a more general solution is required.Outride
An anti-cherry-pick is called a revert?Outride
Here is my own answer, without using git reset or rebase stackoverflow.com/a/60890028/2338477Sweater
S
3

Pull so that you have the same repository locally.

Use git rebase --interactive (see this rundown if you are unfamiliar with interactive rebase) to reorder the A and B commits, so that you now have

... o ---- o ---- B ---- A  master 

Checkout a new branch dev from that spot, so you get

... o ---- o ---- B ---- A  master, dev

Switch to the master branch, do a git reset --hard HEAD^ to rewind that branch one commit. You now have

... o ---- o ---- B  master 
                   \
                    A  dev 

Now git push --force --all and you should be golden. (You need --force because you are rewriting history in the remote repository, which is dangerous and not recommended if other developers have already pulled from it.)

Schmaltz answered 22/1, 2011 at 19:46 Comment(0)
S
1
git revert -n <git commit hash>

Reverts particular change, but keeps commit changes locally - useful if you don't want to revert everything, but just something (This is also behavior of Tortoise Git).

git revert --no-edit <git commit hash>

Reverts particular change, and commits change to git (but does not push it to server) - in case if you want to return to old version to understand what was done wrong.

git revert --no-edit <git commit hash>
git cherry-pick -n  <git commit hash>

Revert change back to old version and pick up commit changes to local files, so you can continue from same point as previously. Useful to start problem solving over again, with previous commit change as "working draft".

If you decide to commit your change later on, you will end up with two commits instead of one. (one revert commit, one forward commit) - or you can also revert all your local changes and last revert commit using:

git reset --hard HEAD~1

Deletes local changes and last commit completely (from git history and from file system, WARNING: change cannot be recovered) Useful if you managed to understand what went wrong and how to fix current version, and want to return one commit back.

Sweater answered 27/3, 2020 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.