Git 如何防止 public 提交的本地修改

Git how to prevent local modification of public commits

我已经在我的 git 中央回购服务器上添加了 receive.denyNonFastforwards 和 receive.denyDeletes。现在,如果提交已经被推送到中央仓库(就像 mercurial 默认情况下所做的那样),我想阻止本地历史修改,我想我可以使用一个钩子,但我找不到任何例子。

这是一个奇怪的配置吗?

这听起来像是任何使用 git 的人都应该激活的基本保护措施,我对缺少示例挂钩感到非常惊讶。

您可以使用 Client-Side Hooks, much like you would with Server-Side Hooks 防止修改本地历史记录。

Here 是客户端挂钩代码的一些示例。该页面的末尾附近是一个 pre-rebase 脚本,它执行的操作与您正在寻找的内容接近。

请注意,不能将客户端挂钩添加到存储库中,以便在下游存储库中自动设置它们:

Because hooks aren’t transferred with a clone of a project, you must distribute these scripts some other way and then have your users copy them to their .git/hooks directory and make them executable. You can distribute these hooks within the project or in a separate project, but Git won’t set them up automatically.

Mercurial 提供了一些方法来处理可变的 chagenset(您可以 reorder/rewrite 的变更集)。例如 ChangeSet Evolution plugin.

服务器端git的可能性更小(你可以用问题中提到的两个配置拒绝push --force

您不能轻易地在客户端实施挂钩,因为它需要被激活,并且可以用 git commit --no-verify 绕过。

但是在Git1.8.5之前,有一个pre-rebase client hook called .

在Git1.8.5之后,可以作为客户端a git push --force-with-lease:

You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.

这允许在客户端有一些自由,并在服务器端提供更安全的强制推送。

这看起来非常接近,即使与 Strategy for Preventing or Catching Git History Rewrite

不是同一个问题

总而言之,您可以启用

git config --system receive.denyNonFastforwards true

git config --system receive.denyDeletes true

或者写一个 post 接收钩子来拒绝任何你认为是重写的东西