[英]How do I delete unpushed git commits?

I accidentally committed to the wrong branch. How do I delete that commit?


6 个解决方案



Delete the most recent commit, keeping the work you've done:


git reset --soft HEAD~1

Delete the most recent commit, destroying the work you've done:


git reset --hard HEAD~1



Don't delete it: for just one commit git cherry-pick is enough.


But if you had several commits on the wrong branch, that is where git rebase --onto shines:

但是如果你在错误的分支上犯了几个错误,那就是git rebase的所在:

Suppose you have this:


 x--x--x--x <-- master
            -y--y--m--m <- y branch, with commits which should have been on master

, then you can mark master and move it where you would want to be:


 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
            -y--y--m--m <- y branch, master branch

, reset y branch where it should have been:


 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
            -y--y--m--m <- master branch
                -- y branch

, and finally move your commits (reapply them, making actually new commits)


 git rebase --onto tmp y master
 git branch -D tmp

 x--x--x--x--m'--m' <-- master
            -y--y <- y branch



Do a git rebase -i FAR_ENOUGH_BACK and drop the line for the commit you don't want.

执行git rebase -i FAR_ENOUGH_BACK并删除您不想要的提交的行。



If you want to move that commit to another branch, get the SHA of the commit in question


git rev-parse HEAD

Then switch the current branch


git checkout other-branch

And cherry-pick the commit to other-branch


git cherry-pick <sha-of-the-commit>



For your reference, I believe you can "hard cut" commits out of your current branch not only with git reset --hard, but also with the following command:


git checkout -B <branch-name> <SHA>

In fact, if you don't care about checking out, you can set the branch to whatever you want with:


git branch -f <branch-name> <SHA>

This would be a programmatic way to remove commits from a branch, for instance, in order to copy new commits to it (using rebase).


Suppose you have a branch that is disconnected from master because you have taken sources from some other location and dumped it into the branch.


You now have a branch in which you have applied changes, let's call it "topic".


You will now create a duplicate of your topic branch and then rebase it onto the source code dump that is sitting in branch "dump":


git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

Now your changes are reapplied in branch topic_duplicate based on the starting point of "dump" but only the commits that have happened since "master". So your changes since master are now reapplied on top of "dump" but the result ends up in "topic_duplicate".

现在,根据“dump”的起始点,您的更改被重新应用到branch topic_duplicate中,但只在“master”之后发生的提交。因此,由于master的更改现在在“dump”的顶部重新应用,但结果以“topic_duplicate”结束。

You could then replace "dump" with "topic_duplicate" by doing:


git branch -f dump topic_duplicate
git branch -D topic_duplicate

Or with


git branch -M topic_duplicate dump

Or just by discarding the dump


git branch -D dump

Perhaps you could also just cherry-pick after clearing the current "topic_duplicate".


What I am trying to say is that if you want to update the current "duplicate" branch based off of a different ancestor you must first delete the previously "cherrypicked" commits by doing a git reset --hard <last-commit-to-retain> or git branch -f topic_duplicate <last-commit-to-retain> and then copying the other commits over (from the main topic branch) by either rebasing or cherry-picking.

我想说的是,如果你想更新当前“复制”分支基于不同的祖先必须先删除以前“cherrypicked”提交通过git重置——< last-commit-to-retain >或git分支- f topic_duplicate < last-commit-to-retain >,然后复制其他提交(从主话题分支)垫底术或挑选。

Rebasing only works on a branch that already has the commits, so you need to duplicate your topic branch each time you want to do that.


Cherrypicking is much easier:


git cherry-pick master..topic

So the entire sequence will come down to:


git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

When your topic-duplicate branch has been checked out. That would remove previously-cherry-picked commits from the current duplicate, and just re-apply all of the changes happening in "topic" on top of your current "dump" (different ancestor). It seems a reasonably convenient way to base your development on the "real" upstream master while using a different "downstream" master to check whether your local changes also still apply to that. Alternatively you could just generate a diff and then apply it outside of any Git source tree. But in this way you can keep an up-to-date modified (patched) version that is based on your distribution's version while your actual development is against the real upstream master.


So just to demonstrate:


  • reset will make your branch point to a different commit (--hard also checks out the previous commit, --soft keeps added files in the index (that would be committed if you commit again) and the default (--mixed) will not check out the previous commit (wiping your local changes) but it will clear the index (nothing has been added for commit yet)
  • 重置将使您的分枝点到一个不同的提交(——硬还检查了之前的提交,软不断添加文件索引(如果你再次提交将提交)和默认的(混合)不会查看之前的提交(擦拭你的本地更改)但它会清除指数(没有添加提交)
  • you can just force a branch to point to a different commit
  • 您可以强制一个分支指向另一个提交
  • you can do so while immediately checking out that commit as well
  • 您可以在立即检出该提交的同时这样做
  • rebasing works on commits present in your current branch
  • 基于当前分支中的提交重新设置工作基础
  • cherry-picking means to copy over from a different branch
  • cherry-pick的意思是从另一个分支复制过来

Hope this helps someone. I was meaning to rewrite this, but I cannot manage now. Regards.




If you have a backup of your code (including .git folder), delete the .git folder from your latest codebase. Copy old .git folder to latest codebase. Execute git pull.


Note: Please use this solution only if you are running out of time and are confused a lot.





粤ICP备14056181号  © 2014-2020 ITdaan.com