如何在 git 空存储库中取消上一次提交?

考虑到有几个 git 命令在裸仓库中毫无意义(因为裸仓库不使用索引,也没有工作目录) ,

git reset --hard HEAD^

不是取消这种存储库中上一次更改的解决方案。

在互联网上搜索,我能找到的所有与这个主题相关的东西都是 这个,在其中,我看到了三种做这件事的方法:
1. “手动更新参考文献(涉及管道)”;
2. “ git push -f来自一个非空白存储库”;
3. “ git branch -f this $that”。

你认为哪种解决方案更合适,或者还有什么其他方法可以做到这一点?不幸的是,我找到的关于 git 裸仓库的文档非常糟糕。

39945 次浏览

The git push -f should work fine:
if you clone that bare repo, remove the last commit (git reset --hard HEAD^ as you mention, but in a local non-bare repo) and push back (-f):

  • you don't change any SHA1 for the other commits preceding the one you remove.
  • you are sure you push back the exact content of the bare repo minus the extra commit (because you just cloned it first).

You can use the git update-ref command. To remove the last commit, you would use:

$ git update-ref HEAD HEAD^

Or if you're not in the branch from which you cant to remove the last commit:

$ git update-ref refs/heads/branch-name branch-name^

You could also pass a sha1 if you want:

$ git update-ref refs/heads/branch-name a12d48e2

See the documentation of the git-update-ref command.

If you use the following in a bare repo:

git reset --soft <commit>

then you don't run into the issues you have using --hard and --mixed options in a bare repo since you're not trying to change something the bare repo doesn't have (i.e. working tree and index). In your case specifically you would want to use (from the bare repo):

git reset --soft HEAD^

To switch branches on the remote repo do:

git symbolic-ref HEAD refs/heads/<branch_name>

To see current selected branch use:

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

You can also use git refspec notation and do something like this:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

This forces update of destination branch (as denoted by the ref) to the source commit as denoted by the +<object ref> part.