我在当前分支中有一些提交。我想将所有提交转换为一次提交并删除所有这些提交。所以我使用了以下命令
- git rebase -i HEAD~9
- 编辑了对 Squash 的所有提交,除了最旧的 Pick 并保存
- 给出具体评论并保存
- git 推送
我运行了“git Push”,而不是 git commit,然后强制推送。
现在,它已经创建了一个新的提交,并 merge 了所有以前的提交。但它并没有删除所有以前的提交。我已经进入远程状态。
在 rebase 之前,以下是我的分支中的提交 ID
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>
在 rebase 之后,提交 ID 已添加到现有提交 ID 中,这是所有上述提交 ID 的 merge
commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>
因此,请帮助我如何删除以前的提交,并确保只有一个压缩的提交被推送到远程。有没有办法从这里恢复或修复这个问题?
最佳答案
没有任何删除旧提交。1 Rebase 会生成新提交,但旧提交仍然存在。做出新的提交后,我们现在告诉拥有其他 Git 存储库的其他人获取这些新提交(或者将它们发送给使用其他 Git 存储库的其他人) git push
) ...然后我们告诉他们:并停止使用旧的提交,因为这些是新的和改进的替换提交。
如果您使用git push
要将这些提交发送到某个共享存储库,通常必须使用 git push --force
或git push --force-with-lease
实现“并停止使用旧的提交”部分。
你所做的——你没有这么说,但人们意外地这样做是很常见的——是进行新的和改进的提交,将它们发送到另一个 Git 存储库,然后 merge 旧的提交和新的改进的提交。所以您现在在您的存储库中拥有两组。
要解决此问题,您必须从您正在使用的提交集中 pop merge 提交本身。也就是说,您想要“删除” merge 。正如我们已经指出的,这实际上是不可能的,但是您不必从存储库中消除 merge 提交;您只需停止使用它。
允许您停止使用某些特定提交的 Git 命令是 git reset
。使用 git reset
有一些主要缺点:
要停止使用某些提交,您还必须停止使用该分支上的所有后续提交。
如果其他人(其他 Git 存储库)有该提交,他们可以将其返还给您的 Git,您的 Git 会很乐意将其添加回来:Git just < em>喜欢添加提交,并且不愿意停止使用提交,这就是为什么 merge 很容易而重置很困难。
但是,如果您确保没有未提交的工作,则可以安全地运行 git reset --hard
现在。运行git log --graph
(或参见 Pretty Git branch graphs )以验证 merge 提交是否是分支的tip,并查看 merge 的第一个父级是否是您想要的提交新的提示(这似乎是可能的),或者 merge 的第二个父级是否是您想要作为新提示的提示(可能性较小,但有可能)。然后:
git reset --hard HEAD~1
会将分支名称移回当前提交的第一个父级。如果这不是正确的提交(如果您需要第二个父级),您将运行:
git reset --hard HEAD^2
(或在 CMD.EXE
、 git reset --hard HEAD^^2
中)。您必须首先仔细查看提交图(请参阅链接的问题及其答案),以验证 merge 提交实际上位于当前分支的顶端,并且 merge 提交的第一个或第二个父级是您< em>想要在提示处。
如果情况并非如此,请考虑运行:
git log --decorate --oneline --graph
并将一些输出(有问题的提交部分)剪切并粘贴到您的问题中。
1这并不完全正确,但没有“删除提交”命令。相反,我们放弃旧的提交 - 停止使用它们 - 最终 Git 决定它们不仅现在没有被使用,而且甚至找不到,Git 最终会自行删除它们。或者,有时并非如此。除非我们深入研究维护 Git 命令,否则我们无法真正控制这一点。
关于Git 交互式 rebase 没有删除我的其他提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69849237/