3

问题描述

我让自己陷入了一个 gitpickle。这张图片说明了我自己所处的情况:

开发提交

不出所料,我现在无法推送绿色提交,因为非快进更新被拒绝。在遥控器上,我尝试签出 dev 分支,这样我就可以执行git reset --hard HEAD~1命令来删除远程上的提交,但它是一个裸仓库,所以我无法签出 dev 分支。当前分支始终是“master”。我的目标只是删除遥控器上的红色提交,以便我可以推送绿色提交。

问题

如何删除远程 dev 分支上的红色提交,而无需检查远程上的 dev 分支?

笔记

  • 我不想强制推送,因为其他存储库从遥控器拉出,我不想破坏它们。但是,我知道还没有人从遥控器中拉出,所以我可以删除红色提交。
  • 我现在看到,将来,git revert当需要撤消的提交已经被推送时,我应该使用该命令。
  • 我还有一个主分支、发布分支和各种功能分支,为了简化图像,我省略了这些分支。让我知道它们是否相关,我会添加它们。

相关问题

我已经查看了这些问题(以及更多问题),但我认为它们没有解决我当前的问题,因为要么我不知道如何应用他们的解决方案来删除远程上的提交,要么他们没有为裸回购工作。

“Git 推送非快进更新被拒绝”是什么意思?
如何撤消 Git 中的最后一次提交?
如何在不签出的情况下快速转发分支
重新设置分支而不签出

4

1 回答 1

2

我不想强制推送,因为其他存储库从遥控器拉出,我不想破坏它们。但是,我知道还没有人从遥控器中拉出,所以我可以删除红色提交。

强制推动仍然正是您想要在这里做的事情。强制推送不会神奇地破坏所有相关方的远程存储库;相反,当使用 force 标志推送时,您只是告诉 Git 更新分支指针,即使这意味着需要进行非快进更改。

想象一下,这是您在(裸机)遥控器上的情况:

A -- B -- C -- D
               ↑
             master

请记住,分支只是存储库历史记录中提交的指针。现在你想要推送一个作为其父级的提交EC所以在第一步中,你只需传输提交:

            /-- E
           /
A -- B -- C -- D
               ↑
             master

现在,您还告诉遥控器更新其master分支,使其指向E. 在正常情况下,Git 会拒绝这样做,因为master不能快进到E. 所以,相反,你将不得不强制推送它,告诉 Git 忽略这个事实。所以远程存储库将如下所示:

              master
                ↓
            /-- E
           /
A -- B -- C -- D

因此,除非某些其他分支指向D(直接或间接),否则该提交现在“丢失”并且最终将被垃圾收集。

通常,您希望避免这样做,因为每个知道提交D(并且有一个指向它的本地分支)的人都会遇到新远程的问题。例如,如果我的旧本地master指向D,我将不得不手动重置我的分支,master以便改为指向E。所以通常,规则是永远不要删除我们曾经推送的任何内容(我们从技术上讲是D从历史中删除)。

但是,如果您确定没有人 fetched D,那么这没有任何问题。那些从未有过的人D不会意识到D消失了,并认为master一直都是这样。并且在强制推送之前存在并且稍后仍然存在的所有其他提交不会改变任何关于这种情况的内容。重要的是仅通过强制推送“删除”的提交。

于 2015-03-11T09:47:23.890 回答