2010-01-18 26 views
37

虽然我喜欢git历史重写功能,但是如何确保历史不会被重写。防止或捕获git历史重写的策略

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

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

回答

38

如果你可以运行:

git config --system receive.denyNonFastforwards true 

在服务器上,应当照顾改写历史的情况下被推到上述服务器。
但是,这是所有回购,而不是一个特定的文件或文件组。

git config

receive.denyNonFastForwards

如果变基承诺你已经推,然后尝试再次推,或以其他方式试图推动一个承诺不包含远程分支远程分支当前指向的提交,您将被拒绝。这通常是很好的政策;但是在重新绑定的情况下,您可以确定您知道自己在做什么,并可以使用-f标志强制更新远程分支到您的push命令。

另一种方法是通过服务器端的接收挂钩来完成,我将稍微介绍一下。这种方法可以让你做更复杂的事情,例如拒绝某些用户的非快速转发。


由于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以每个用户的身份执行此操作,正如您在本章最后所学到的一样。

+4

注意:Git1.6或更新版本... – VonC 2010-01-18 12:25:20

+6

您可能还想添加receive.denyDeletes true,否则,某人可以删除该分支,然后将其重写的分支作为新分支,有效地重写历史记录。 – ebneter 2010-01-26 02:46:18

+0

@ebneter:很棒的提示。我编辑了我的答案以包含它。谢谢。 – VonC 2010-01-26 05:04:59

3

如果不使用新的git足以为receive.denyNonFastForwards,您可以通过{pre,post}-receive(等)挂钩的服务器,允许特定的分支机构等多一点点的粒度上执行政策。

一些很好的例子(包括一个禁止历史重写)用于由GNOME项目来管理所有的仓库那里:

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

我想看看尤其是pre-receive-check-policy

0

如果你不能/不想禁用Git历史重写,但希望得到关于这种性质的每一次变化的通知,并且能够在数年后恢复,那么企业Git服务器的扩展就会检测到历史记录重写和分支删除,将在特殊的引用下备份它们,以便在需要时可以恢复它们,并且不会被垃圾回收修剪。出于法律原因,Gerrit管理员仍然可以删除选定的提交。