1

I have been facing some issues regarding my master branch. I accidentally pushed some commits to my master branch which were really old.

Now I want my master and source to go back to a previous commit (highlighted with blue color in the picture) and discard all the other commits after that from the source and history so that I can push my new commits after that. I am using bitbucket and SourceTree.

How would you do this?

enter image description here

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
Tajmin
  • 353
  • 1
  • 7
  • 23

1 Answers1

1

It is best to create a new commit which will be the exact image of the old 'Booking' one:

First:

 git checkout master
 git branch tmp                    # let's mark the current master (with wrong commit)

Then:

 git reset --hard <SHA1 'Booking'> # reset worktree and index of master
                                   # to Booking content
 git reset tmp                     # reset master HEAD and index to its original position 
                                   # (but keep working tree of Booking)

Now that the working tree represents the right content:

 git add .
 git commit -m "restore Booking"
 git push

That way, no filter-branch (which would rewrite the history), no revert (which might be complex when a merge is involved).


To know more about the "reset magic", read "Reset Demystified"

The first reset --hard restore the right content (but also moves HEAD and reset index)

https://git-scm.com/images/reset/reset-hard.png

The second reset (--mixed) will restore HEAD to its original place, and will restore the index as well. But it will leave the working tree untouched.

enter image description here

That way, there is a difference between master index and the working tree, which represents the content of the old commit.
Adding and committing are enough to create a new commit on top of the current master, with the old commit content.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I didn't get the answer. The `reset --hard` will take us to the booking commit right? And the you did `soft reset` which should remove the commit but keep the changes? Or I got it wrong here? And then you made the same changes in a new commit and pushed it? – Deepesh Dec 31 '16 at 08:20
  • @Deep Actually, a reset --mixed is needed here: you want to reset HEAD and index to the original master, but keep the working tree of Booking. Once you have that, you can add and commit, in order to restore Booking content into a new commit. – VonC Dec 31 '16 at 08:24
  • Sorry @VonC still I am bit confused. So if you will `reset --hard` the changes would be lost of those commit? I tried it on one of my branches and had the same thing. Suppose I go one commit back and using `--hard reset`. now the `reset tmp` will just set the HEAD to that commit. Now why `add` and `commit`? As I don't have any changes in the folder? – Deepesh Dec 31 '16 at 08:35
  • @Deep A mixed reset will reset HEAD and index, not working tree. That means you go back to your current master, but with files representing the content that you want (Booking). Compared to your current master index, those files introduces changes: you add and commit that content. – VonC Dec 31 '16 at 08:36
  • I tried this on my local, when I run this `git reset tmp ` it again brings back my same merge commit back to the branch. I went to the `master` created a duplicate branch `tmp`. Did a `reset --hard` one last `merge` commit and then did `git reset tmp`. When I see `git log` the same commits are shown. Am I doing something wrong? Sorry just found this interesting and was trying to understand the solution. – Deepesh Dec 31 '16 at 09:15
  • @Deep you are missing the add and commit after the reset tmp. – VonC Dec 31 '16 at 09:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/131954/discussion-between-deep-and-vonc). – Deepesh Dec 31 '16 at 09:16