无需推动即可回滚主控原点

时间:2017-06-09 15:40:45

标签: git

如果禁用强制推送,有没有办法将origin master回滚到之前的提交? 我有A - > B - > C C是错误提交,顺便说一句,B是合并提交。我希望master origin返回B,但是服务器策略拒绝强制推送。

还有其他办法吗?

1 个答案:

答案 0 :(得分:3)

在进入技术选项之前,我们应该认识到“无力推动”政策意味着你无意做到你所描述的。从裁判的历史中删除提交是“强制推动”所做的事情的关键(超越常规推动)。通常,原始仓库拒绝强制推送是有充分理由的 - 请参阅git rebase文档中的“恢复上游rebase”部分,因为即使您不使用rebase命令,同样的情况也是如此适用。

有些选项可能“足够好”而不是实际删除C;我会回过头来看。

但是好吧,让我们假设无论出于何种原因你(以及你的团队/回购所有者/谁负责决定这是否合适)了解成本并仍然想要这样做,但不能改变你的政策设置服务器正在执行。

还有另一种方法可以删除C 吗?

不简单。无论如何,不​​是将原始回购视为遥控器。根据定义,“强制推送”是从远程参考历史中提交提交的操作。

选项1 :嗯,我不知道您的原始回购是如何托管的。服务器软件是否为您提供了操作仓库的选项?如果是这样,这是你最好的选择。

选项2 :如果您可以直接访问原始仓库 - 如果您可以登录某个允许您将其视为本地仓库的地方 - 那么您可以这样做。该过程与您在本地执行的过程基本相同,除非您可能必须首先创建工作树(因为通常原点是裸仓库)。像

这样的东西
git worktree add /path/to/create/a/worktree/at master
# cd into the new work tree
git reset --hard HEAD^

然后删除工作树(rm -r ...)并清理(git worktree prune),以便git不会担心影响工作树的推送。

选项3 :如果您可以直接访问repo文件,但由于某些原因无法对它们运行git,理论上您可以重写ref本身。直接在git文件上工作是一个危险的游戏,我并不是真的推荐它,但是没有人说我在考虑选项时没有彻底。

除非你对git有足够的了解就可以自己解决这个问题,但这样做可能是个坏主意,所以我继续前进......

选项4 :我想你可以替换整个回购。我们真的到了这里的底部。

那么如果我不能(或决定不)删除C该怎么办?

你可以revert代替它。当您还原提交M时,会创建一个新的提交W,通过创建M来“撤消”所做的任何更改。所以

git revert C

会给你

      (origin/master)
            |
A --- B --- C --- !C <--(master)
     /
... X

其中!CTREE具有相同的B(内容状态)。这可以在没有--force的情况下推送。它是否“足够好”取决于。

如果C包含敏感数据(密码,密钥),您可能真的希望它不在历史记录中。我的建议是更改密码并撤销密钥。 (即使您 从历史记录中移除C,您能否保证没有人复制过它?)

如果C包含大型二进制文件......这是个坏消息。回购将永远受到由此产生的膨胀的负担。用重写的历史记录替换repo是唯一真正的修复(这会让我们回到上面的选项)。

但如果它只是一个“哎呀”,那么将它从历史中删除是可以理解的,但并非必要。不希望在其历史记录中看到C的个人可以考虑使用git replace来“替换”!CB“{1}}”但它可能不值得。 (请注意,replace只会产生对历史记录更改的错觉,并且有一些记录的怪癖;任何决定使用它的人都应该至少阅读该命令的基本文档。)