4

I have made several commits to my local branch estimation and pushed them to the remote branch estimation.

Now, I want to remove the last 3 commits completely.

I tried to do git reset HEAD^ and git reset HEAD --hard 3 times but when I tried to push the changes, it complained about tip of the HEAD not aligned.

How do I do it?

EDIT:

The history looks like following:

commit e572aab4e18

commit e21e7310bc4

commit 4f372a513da

commit 31a4ac607ae

commit a1a6e3f02dd

I would like to remove top 4 and go back to commit a1a6e3f02dd and make both local and remote branch on same HEAD.

1

3 Answers 3

5

If you already pushed the commits (and don't want to do a force-push and overwrite data in the remote repository, there are a couple things you can do):

You can use git revert instead of git reset:

$ git revert ~4..HEAD

Or you can use git checkout and then commit the changes:

$ git checkout ~3 -- .
$ git commit

git revert will do 3 separate revert commits. The git checkout method will allow you to revert the changes in just one single commit.

In your case, you could do this:

$ git reset --hard $REMOTE/$BRANCH
$ git checkout a1a6e3f02dd -- .
$ git commit
6
  • Thanks Mipadi. I am little confused so I have provided more information. Can you please have a look at it
    – chintan s
    Commented Jun 29, 2016 at 18:23
  • @chintans: Updated my answer.
    – mipadi
    Commented Jun 29, 2016 at 18:37
  • Thanks but now my branch is a1a6e3f02dd but I want to just remove all the 4 commits completely so my local remote brach both point a1a6e3f02dd.
    – chintan s
    Commented Jun 29, 2016 at 18:48
  • @chintans: Since you already did a reset locally, you'll have to reset instead to the HEAD of your remote branch, then do git checkout and git commit. Answer updated.
    – mipadi
    Commented Jun 29, 2016 at 18:50
  • He wants to rewrite history through force-push. He doesn't want to add 4 new "revert" commits on top of his existing history. p.s. I recommend squashing a sequence of reverts into a single commit with "git rebase -i". Commented Jun 29, 2016 at 18:55
3

First: You should only do this for a branch that you're not sharing; if the branch is checked out by others, this process will put their local copies out of sync with the remote and they won't be able to just push commits to the branch anymore. This can be sorted out but it's potentially a mess.

Given that, if I understand you correctly, you're in this situation:

xxxxxxx Bad commit #3
yyyyyyy Bad commit #2
zzzzzzz Bad commit #3
wwwwwww This and everything before it are fine

You want to drop the commits after wwwwwwww and fix the remote branch to match.

First, back up the branch you're doing surgery on so you can restore it if you mess up, and then switch back to the branch you want to remove commits from.

git checkout -b broken-estimation
git checkout estimation

Run git log to find the SHA1 of the first commit you want to keep. Once you have that SHA1, reset the branch to that:

git reset --hard kkkkkkk

where kkkkkk is the SHA1 of the first commit you want to keep on the branch.

Run git log again to ensure you've got the desired SHA1 as the tip of this branch; it should be the first commit you see in the git log output. If you've not trimmed off enough commits, redo the git reset --hard with the proper SHA1 to remove more commits.

If you removed too many commits, restore the estimation branch from the backup you took:

git checkout -B estimation broken-estimation

and redo the git log to find the SHA1 of the commit you want at the tip, followed by git reset --hard kkkkkkk (with kkkkkkk being the SHA1 you actually wanted) to drop the undesired commits following that commit.

Once you've got the branch in the desired state, you can push the fixed branch to the remote, replacing the old version:

git push -f the_proper_remote estimation

Once you're certain that your repairs are correct, you can delete the backup copy of the branch:

git branch -d broken-estimation
0
0

You can do it in three commands:

First, rewrite the history of the remote branch:

git push origin +a1a6e3f02dd:estimation

Note, the "+" causes it to be a "force-push". This command says "force a1a6e3f02dd to be the tip of the origin/estimation branch."

Once that's done, you just need to get your local "estimation" branch synchronized with the remote one:

git checkout estimation
get reset --hard origin/estimation

And you're done! But be forewarned: 'git reset --hard' will blast away any uncommitted work you have in that project.

If others are also working with the 'estimation' branch, and they have already pulled your 4 "bad" commits into their branches, then there is going to be a bit of a coordination mess. But in my experience all the warnings and admonishments about "never rewrite history of shared branches" is overblown. It should be restated: never rewrite history of long-lived shared branches.

Not the answer you're looking for? Browse other questions tagged or ask your own question.