防止或捕获git历史记录重写的策略

时间:2010-01-18 12:13:52

标签: git

虽然我喜欢git history重写功能,但是如何确保历史记录不被重写。

我们不介意程序员在他们自己的机器上做什么,但我们需要确保不会将版本推送到更改历史记录的服务器。

即我们需要保证过去的特定版本确实是该版本。因此,这将包括阻止某人通过并永久删除历史记录中的文件,或永久更改所有历史记录中的文件。

3 个答案:

答案 0 :(得分:40)

如果你可以跑:

 git config --system receive.denyNonFastforwards true

在服务器上,应该注意重写历史案例被推送到所述服务器 但是,这适用于所有repo,而不适用于特定文件或文件组。

git config

  

receive.denyNonFastForwards

     

如果您重新提交已经推送的提交然后尝试再次推送,或者尝试将提交推送到不包含远程分支当前指向的提交的远程分支,那么您将成为否认。这通常是好政策;但是对于rebase,您可以确定您知道自己在做什么,并且可以使用-f标志强制更新远程分支到您的推送命令。

     

另一种方法是通过服务器端接收挂钩,我稍后会介绍。这种方法可以让您执行更复杂的操作,例如拒绝非快速转发到某个用户子集。


正如 ebneter (谁知道连贯存储库的重要性 - 请参阅有关SVN to Git migrations [现已删除的问题,仅限10K +用户]的回答)评论:

  

您可能还想添加 receive.denyDeletes true ,否则,有人可以删除该分支,然后将其重写的分支推送为新分支,从而有效地重写历史记录。

git config

  

denyNonFastForwards策略的一个解决方法是让用户删除分支,然后使用新引用将其推回。在较新版本的Git(从1.6.1版开始)中,您可以将receive.denyDeletes设置为true:

     

$ git config --system receive.denyDeletes true

     

这会通过全面推送来拒绝分支和标签删除 - 没有用户可以做到。要删除远程分支,必须手动从服务器中删除ref文件。还有更有趣的方法可以通过ACL在每个用户的基础上执行此操作,您将在本章末尾学习。

答案 1 :(得分:3)

如果你没有为receive.denyNonFastForwards使用足够新的git,你可以通过{pre,post}-receive(以及其他)服务器上的钩子强制执行策略,这样可以为特定分支提供更多的粒度等等。

GNOME项目使用了一些很好的例子(包括一个禁止历史记录重写)来管理那里的所有存储库:

https://git.gnome.org/browse/sysadmin-bin/tree/git

我会特别关注pre-receive-check-policy

答案 2 :(得分:0)

如果您不能/不想完全禁用Git历史记录重写,但希望得到有关此类性质的每个更改的通知,并且能够在几年后恢复,那么像Gerrit这样的企业Git服务器的扩展会检测历史记录重写和分支删除,将在特殊引用下备份它们,以便在需要时可以恢复它们,并且不会被垃圾收集修剪。出于法律原因,Gerrit管理员仍可以根据需要删除所选提交。