【问题标题】:git pushes incorrect commit SHA when working via SSHgit 在通过 SSH 工作时推送不正确的提交 SHA
【发布时间】:2017-07-05 13:58:28
【问题描述】:

背景: 操作系统:Windows Git版本:2.11.0

根据我们的政策,我们是: 1.在未推送的提交的提交消息中添加几个字段在推送前 2. 远程验证推送的提交消息是否包含必填字段

我们正在通过 pre-push 挂钩期间触发的“git --filter-branch --msg-filter”编辑提交消息。

当尝试通过 SSH 推送时,git 在重新编写之前推送提交 SHA。 例如:

  1. 未推送的提交 SHA 为:38dad1575a3c4239c967564c21347aad3d5b2a55
  2. 运行 git push
  3. 预推送运行并重写提交。
  4. 现在我的提交 SHA 是:8115fdfb3be86a6b51284cd1d278bd55017990ce。
    以前的提交 38dad1575a3c4239c967564c21347aad3d5b2a55 现在存储在 /refs/original/refs 下
  5. 由于提交 38dad1575a3c4239c967564c21347aad3d5b2a55(未编辑的提交)在其提交消息中不包含必要的字段,因此推送到 repo 失败。

此行为仅在通过 SSH 工作时发生。对于使用 HTTPS 的用户,一切正常。

我们将不胜感激。

谢谢!

【问题讨论】:

    标签: git ssh hook git-push


    【解决方案1】:

    作为一种一般规则,钩子本身是不允许修改提交的。有些特定情况是明确允许的,有些是偶然发生的,但是一旦提交实际上存在,它不能被更改。 git filter-branchgit commit --amend 实际上不会更改任何提交;相反,它添加了一个类似于原始提交的 new 提交,但具有您对其所做的任何更改。这个新的提交有一个新的、不同的哈希 ID。

    令人惊讶的不是 ssh 失败了,而是 https 成功了。这只是运气,有人可能会说它奏效不幸运气。 pre-push 钩子只是为了说“是的,这个推送是允许的”或“不,这个推送是被禁止的”。它不应该更改名称到提交 ID 的映射。显然,实际发生的情况是,基于 http 的推送最终会重复名称到 ID 的映射并获取新的 ID,而基于 ssh 的推送则坚持最初获得的 ID。

    现在,您实际上可以完成所有这些工作了:

    • 在pre-push钩子中,检查是否允许push。
      • 如果是,请通过。
      • 如果不是,准备拒绝它。进行允许的新提交,并且可以选择推送该提交(递归地,在外部 git push 期间运行内部 git push——递归将终止,因为刚刚进行的 new 提交将是允许,以便在内部推送期间不会运行此逻辑分支)。然后打印一条错误消息,指出(以及为什么)原始推送被拒绝,以及“内部”推送是否完成,如果成功,是否成功,它的 ID 是什么以及用户如何使用它。最后,拒绝推送。

    避免这种递归方法有几个原因:(a)它违反了任何有经验的 Git 用户的期望,他们不希望自己的提交被替换和推送; (b) 如果它出错——例如,如果递归没有立即终止——它可能会非常出错。 (b) 部分可以通过 pre-push 钩子中的聪明才智来缓解(例如,将环境变量导出到内部推送,注意正在发生递归,如果要递归,如果设置了这个变量,则会大声失败)。 (a) 部分也许是可以原谅的,因为 pre-push 钩子毕竟是用户必须首先设置的东西。

    即使您处理了这些反对意见,还有一个避免它的理由:它会使外部(非递归)推送失败。即使内部推送成功,用户也会看到推送失败。这至少会有点令人困惑。

    【讨论】:

      猜你喜欢
      • 2013-07-22
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2013-10-12
      • 1970-01-01
      • 2021-06-18
      • 2021-05-12
      相关资源
      最近更新 更多