Git is a phenomenal tool, but I have yet to wrap my mind around the best way to undo pushed changes. Here's the situation.
I'm on a branch, and have pushed several commits to GitHub. It has since been decided that I've gone too far down the rabbit hole, and we need to scrap several of the commits I've done, and start over. Essentially, I need to reverse all of the pushed commits, back to a previous one. Here are the two commands that I think are appropriate
git revert # - creates a new commit that "undoes" the changes of one specific commit
git checkout 'commit SHA' # - sets the head to that specific commit, wherein I will re-push to the repo, undoing my changes... I think
So, am I right? Do I need to do a git checkout on the specific commit I want to return to? Or is there something in this convoluted process that I am not understanding?
Thanks.
There are two scenarios depending on the state of what you pushed:
Nobody has used the pushed branch for anything yet. In that case you can use git reset
to force the local branch to a specific commit - and then you can git push
the branch with a --force
parameter.
If, however, there are someone who has based his work off on the branch you accidentally pushed, then you can't really reset it, as he will then be basing his changes off of a branch in limbo. This is where git revert
comes into play. It will record an inverse patch effectively undoing earlier changes. The advantage here is that other can base their work on the branch with ease.
The choice of method depends on how your repository is and for how long the accidental patches have been up there. If there are few developers, communication and a reset
is probably the answer. But have the thing lived for a long time, it is probably better to revert - unless you want to rewrite the whole history!
Another way to look at it is this: git revert
is persistent whereas git reset / git push --force
is destructive rewriting of the history. There is an appropriate time for both.
Finally, when I delve to follow Alice down the Rabbit hole and investigate what lies beyond, I usually do it on locally created branches. Then if I like the changes, I usually merge them into a test branch and let them stir a bit on the test branch, before I merge them to master
. That way you avoid the problem a lot of the time. In Short, I often have 20-30 local branches, one for each feature I am working on. They tend to be tested individually first. Occasionally, I create a new branch test
and merge everything into that branch and do all the tests together. To track conflicts across branches I use git rerere
. The advantage is that I can decide when a feature is stable enough to push to others.
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