当我们考虑在工作中从SVN转移到git时,同事已经提出了一个问题,即恶意或容易发生事故的开发人员可以使用git rebase
从我们的共享仓库中删除远程历史记录。
编辑:正如答案中所指出的,也可以使用git push origin :branch-name
从远程仓库中删除整个分支。
这是一个现实的问题吗?如果是这样,我们可以采取什么方法来防止它呢?
答案 0 :(得分:6)
我倾向于同意你的同事这里有问题,因为:
您是否考虑过receive.denyNonFastForwards
和receive.denyDeletes
配置参数? AFAICT可以在Git 1.6开始使用。
来自Pro Git:
如果您重新提交已经推送的提交然后尝试推送 再次,或以其他方式尝试将提交推送到远程分支 不包含远程分支当前指向的提交, 你会被拒绝的。这通常是好政策;但在这种情况下 在这种情况下,你可以确定你知道自己在做什么,能做什么 使用
-f
标志强制更新远程分支到您的推送命令。禁用强制更新远程分支的功能 非快进参考,设置
receive.denyNonFastForwards
你能做到这一点的另一种方法是通过服务器端接收挂钩,我稍后会介绍。这种方法可以让您执行更复杂的操作,例如拒绝非快速转发到某个用户子集。
正如作者所提到的,此规则也可以通过接收挂钩(described later in Pro Git)强制执行。
这些技术可以防止共享仓库中的意外(或恶意)丢失历史记录。
答案 1 :(得分:3)
历史记录可以使用rebase搞砸了,但通常远程仓库不会接受修改历史记录的更改(除非你使用git push --force),但更多的是,具有推送权限的开发人员可以完全删除分支(git push origin:branch-name)。所以简单的规则是:
不要让您不信任的开发者拥有推送权限。
当共享repo时,不要弄乱历史记录,避免在过去的提交中使用rebase。如果您需要添加来自不同分支的内容,请使用merge或cherry-pick,在这种情况下,历史记录不会受到影响。
您可以维持不对共享仓库使用'push -f'的策略,在这种情况下,开发人员会知道如果推送被拒绝则出现问题(很可能是本地分支不是最新的远程)并且应该在本地解决问题而不是强制推送。
关于如何防止的问题 - 使用Gerrit修订系统,它就像是开发人员本地存储库和主存储库之间提交方式的中间步骤,具有良好的Web界面进行修订,您可以授予权限推送到任何人的修订存储库,但更改将在验证和批准后合并到您的主分支(这需要您通常授予核心开发人员的一些权限)。您可能会看到Mahara项目的样子:https://reviews.mahara.org在这种特殊情况下,只允许gerrit bot推送到master(这是here)而不是其他人。
答案 2 :(得分:1)
像Gerrit这样的企业级Git服务器可以检测历史记录重写和分支删除,它们将在特殊引用下备份它们,以便在需要时可以恢复它们,并且不会被垃圾回收修剪。出于法律原因,Gerrit管理员仍可以根据需要删除所选提交。