Git: use revert or checkout to undo pushed changes?
G开发者_运维问答it 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 cangit 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.
As Horia pointed out correctly you'll need git reset.
Git checkout means you switch to another branch or by using checkout -b you can create a new branch and switch to it right away.
Try git reset
: http://git-scm.com/docs/git-reset
精彩评论