防止或追赶git历史重写的策略
虽然我喜欢git历史重写function,但是如何确保历史不会被重写。
我们不介意程序员在自己的机器上做什么,但是我们需要确保一个版本不会推送到改变历史logging的服务器上。
即我们需要保证过去的某个版本确实是那个版本。 因此,这将包括阻止某人通过并永久删除历史logging中的文件,或在所有历史logging中永久更改文件。
如果你可以运行:
git config --system receive.denyNonFastforwards true
在服务器上,这应该照顾重写历史案件被推送到所述服务器。
但是,这是所有回购,而不是一个特定的文件或一组文件。
git config
:
receive.denyNonFastForwards
如果您重新提交已经推送的提交,然后尝试再次推送,或者尝试将提交推送到远程分支(不包含远程分支当前指向的提交)的远程分支,则会被拒绝。 这通常是很好的政策; 但是在rebase的情况下,您可能会确定您知道自己在做什么,并可以使用
-f
标志强制更新远程分支到您的push命令。另一种方法是通过服务器端的接收挂钩,我会稍微介绍一下。 这种方法可以让你做更复杂的事情,例如拒绝某些用户的非快速转发。
作为ebneter (谁知道一个连贯的存储库的重要性 – 请参阅SVN到Git迁移的答案[现在删除的问题,只有10K +用户])评论:
您可能还想添加
receive.denyDeletes true
,否则,有人可以删除该分支,然后将其重写的分支作为新分支,有效地重写历史logging。
git config
:
denyNonFastForwards策略的解决方法之一是用户删除分支,然后用新引用将其重新推回。 在较新版本的Git中(从版本1.6.1开始),可以将
receive.denyDeletes
设置为true:
$ git config --system receive.denyDeletes true
这样一来,就会拒绝分支和标签的删除 – 用户无法做到这一点。 要删除远程分支机构,您必须手动从服务器中删除ref文件。 还有一些更有趣的方法可以通过ACL在每个用户的基础上做到这一点,正如您将在本章最后学到的一样。
如果你没有为receive.denyNonFastForwards
使用一个足够新的git,你可以通过服务器上的{pre,post}-receive
(除其他之外)钩子来强制执行策略,这允许特定分支的粒度更细一些等等。
一些很好的例子(包括一个禁止历史重写的例子)被GNOME项目用来pipe理所有的仓库:
https://git.gnome.org/browse/sysadmin-bin/tree/git
我特别看在接收前检查政策 。
如果你不能/完全不希望禁用Git历史重写,但希望得到关于这种性质的每一个变化的通知,甚至可以在几年后恢复,那么企业Git服务器的扩展,如Gerrit将检测历史重写和分支删除,将在特殊的参考下支持它们,以便在需要时可以恢复它们,不会被垃圾收集修剪。 如果法律原因需要,Gerritpipe理员仍然可以删除选定的提交。