tags:

views:

1256

answers:

3

We're using Github. I have committed, and pushed, several patches: A1-->A2-->A3-->A4 (HEAD)

Everyone's pulled these changesets into their local copy.

Now we want to "roll back" to A2, and continue developing from there - essentially throwing away A3 and A4. What's the best way to do this?

+3  A: 

You want git-revert and git-reset depending on how you want to treat A3 and A4. To remove all trace of A3 and A4, use git-reset --hard. To keep A3 and A4 and record the fact you are reverting, use git-revert.

edit: Aristotle Pagaltzis's git-checkout solution is superior, though for small reverts I don't see a problem with git-revert. None the less, I ask future upvotes be given to Aristotle Pagaltzis's answer

I found git magic to be a good resource for git.

freespace
The original poster almost certainly wants revert not reset. Since everyone has pulled A3 and A4 into their own local repositories, I think resetting would mess things up.
Peter Burns
git-revert will only revert one commit at a time and git-reset is the wrong thing to do for published changes. The correct answer is git-checkout.
Aristotle Pagaltzis
Aristotle Pagaltzis: you are correct, I have striken it from my answer.
freespace
+5  A: 

Throwing away those commits will likely have some negative effects on anyone who is pulling from your repository. As another option, you may want to consider creating an alternate development branch starting at A2:

A1-->A2-->A3-->A4 (master/HEAD)
      \
       -->B1-->B2 (new-master/HEAD)

Doing this is as simple as

git branch new-master master~2
Pat Notz
+18  A: 

From the root directory of your working copy just do

git checkout A2 -- .  
git commit -m 'going back to A2'

Using git revert for this purpose would be cumbersome, since you want to get rid of a whole series of commits and revert undoes them one at a time.

You do not want git reset either. That will merely change your master branch pointer: you are left with no record of the mistaken direction. It is also a pain to coordinate: since the commit you changed master to is not a child of the remote repository’s master branch pointer, pushing will fail – unless you add -f (force) or delete the master branch in the remote repository first and recreate it by pushing. But then everyone who tries to pull will still have the old history in their local master branch, so once origin/master diverges, git pull will try to perform a merge. This is not the end of the world: they can get out of this situation by doing git rebase --onto origin/master $old_origin_master_commit master (ie. rebase their local commits made on top of the old origin/master onto the top of the new origin/master). But Git will not know to do this automatically so you have to coordinate with every collaborator. In short, don’t do that.

Aristotle Pagaltzis