在github工作流程中应用于原始贡献者分支时,`git push --force`是否有害?

时间:2017-02-23 02:33:47

标签: git github

假设我们的贡献者正在使用Github工作流程。也就是说,有三个回购:

  • 项目所有者,我们在本地调用"上游"。我们没有写入权限。
  • 我们的公众(github)" fork",我们在本地打电话"起源"。我们将我们的提交推送到此repo并向所有者打开pull请求,让他们将这些提交合并到他们的仓库中。
  • 我们的"本地",私人,回购。我们立即开展工作并从中推送的回购(我们的原始回购)。

让我们说我们在本地创建一个主题分支,进行一系列提交,将这些提交推送到我们的原点,并在Github上打开一个pull请求。 pull请求将列出这些提交,我们等待所有者回复。

想象一下,我们发现所有(或部分)刚推送的提交消息中存在错误。

编辑这些提交消息(使用交互式rebase,例如git rebase -i HEAD~3)然后强制推送这些更改(git push --force)在任何一种情况下都会有害:

  • 所有者尚未合并拉取请求(进入他们的仓库);
  • 所有者已合并拉取请求(进入其回购协议);

我根据对git push --force的一般警告提出要求。例如,在https://help.github.com/articles/changing-a-commit-message/那里......

  

我们强烈反对强制推送,因为这会更改存储库的历史记录。如果强制推送,已经克隆存储库的人必须手动修复其本地历史记录。

但是在github /集成管理器工作流程上下文(而不是集中式工作流程)中,警告似乎并不适用,因为其他人通常不会分支您的项目。

所以一些辅助问题似乎是恰当的:

  • 如果我们只是强制推送改变提交消息的提交,而不是改变实际完成的工作,那么(也)保证安全吗?
  • 在对拉取请求做出决定之前,项目所有者是否从您的(原始)仓库中提取更改?这有关系吗?
  • 使用--force-with-lease(见https://developer.atlassian.com/blog/2015/04/force-with-lease/)会进一步保证安全吗?

1 个答案:

答案 0 :(得分:0)

锐化问题

根据@ torek的有用评论,我会尝试提出问题,并且#34;在Github工作流程中应用于您的原始撰稿人时,git push --force是否有害?&& #34;,在尝试自己回答之前。

考虑两种情况,你可能会想要改变。如果你想:

  • 更改与先前提交相矛盾的文件。
  • 仅更改先前的提交消息。

如果你还没有将提交推送到公共回购公司,那么任何一种变基都不是问题。

但是,考虑一下,当你已经将提交推送到公共仓库并想要修改它们时:

  • 当您想要更改与先前提交相矛盾的文件时,只需将这些更改合并到新的提交(或提交)中,或执行git revert即可撤消更改通过创建新的提交。也就是说,在这种情况下不需要变基。 (当托雷克举例说明拉动请求的协作方法时,我会接受它,就像在Linux邮件列表上一样,torek想要选择这种情况)。

  • 如果您只想更改以前的提交消息。其动机可能是先前的提交消息可能错误地识别已更改的文件,或以其他方式错误地描述提交。您宁愿在历史记录中留下正确的信息,以免混淆未来的读者。

因此,进一步考虑的唯一方案是您只想更改先前的提交消息。然后还有在Github工作流程下要考虑的其他特定方案。那些关于你试图推动重新提交的拉动请求的提交:

  1. 拉取请求已打开。

    一个。并且项目所有者已经从pull请求中提取了提交以评估pull请求。 (再次感谢@torek提醒我这个案例。)

  2. 拉取请求已由项目所有者合并。

  3. 拉取请求已关闭(没有项目所有者合并)。
  4. 这些情况中的任何一种都会造成伤害吗?

    测试问题的实验

    我已经使用Github帐户进行了一些实验,作为针对方案1a的所有者和贡献者。我已经看到它在主人的最后和贡献者的结束时很快就会变得混乱。混乱包含:

    • 虽然我最终可以让双方都恢复到相同的状态,但到达那里变得很棘手。推,拉和合并的正确组合在某种程度上是迷宫。

    • 因为我故意选择看看凌乱的状态是什么样的,而不是按照torek的建议来清理......

        

      如果您使用git rebase切换回原始提交链,并且该消息是唯一发生变化的内容,则rebase将自动解除此胃灼热

      ......我已经看到这个混乱的状态实际上重复了被重新设定的提交;并且不清楚,只需快速查看提交日志......

      [所有者:John Creator;撰稿人:John Luke Bentley]

      Pull request opened and the project owner has pulled down commits from the pull request in order to evaluate the pull request; Commits after interactive rebase, to change message only, have been pushed back up to the pull request; the owner has merged changes; then both parties pull to make their repos into an equivalent state

      ...哪组提交是相关的。所有者的本地回购和贡献者的本地回购都存在这种混淆(因为他们现在处于同等状态)。

    这足以让人不必考虑情景2和3。

    结束答案

    鉴于混乱和混乱,我认为最好遵守一般建议......

      

    不要重命名存储库外部的提交。 (Chacon和Straub 2014,第3章Git Branching,sec.Rebasing,119)......

         

    [你可以]改变你所做的本地更改,但是在推送它们之前还没有分享,以便清理你的故事[如果有必要],但是不要重新推销任何你推到的地方。 (Chacon和Straub 2014,第3章Git Branching,sec.Rebasing,124)。

    简而言之,请避免git push --force(或git push --force-with-lease)......除非您有这样做的特殊原因并知道自己在做什么。

    对于像我这样不知道自己在做什么的新手会转化为两个(相对)简单的规则:

    1. 请不要重新定位本地存储库之外的提交,并且不要使用git push --force(也不要git push --force-with-lease);
    2. 在推送之前仔细检查提交。
    3. 最好查看已经在您的回购邮件之外推送的提交,就像已经发送的电子邮件一样:它们在世界上是好的还是坏的。纠正提交,内容或仅消息的最佳策略是发送额外的附录,如下:

      • 另一个提交(具有自己的ID和时间戳,而不是重新提交的提交);
      • 对拉取请求的评论;或
      • 通过其他介质向所有者发送评论(电子邮件,短信等)。

      我对其他人发表替代答案或提供进一步评论非常开放。

      参考