虽然我喜欢git history重写功能,但是如何确保历史记录不被重写。
我们不介意程序员在他们自己的机器上做什么,但我们需要确保不会将版本推送到更改历史记录的服务器。
即我们需要保证过去的特定版本确实是该版本。因此,这将包括阻止某人通过并永久删除历史记录中的文件,或永久更改所有历史记录中的文件。
答案 0 :(得分:40)
如果你可以跑:
git config --system receive.denyNonFastforwards true
在服务器上,应该注意重写历史案例被推送到所述服务器 但是,这适用于所有repo,而不适用于特定文件或文件组。
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管理员仍可以根据需要删除所选提交。