git rebase 可以完全删除远程历史记录吗?
当我们考虑在工作中从 SVN 迁移到 git 时,一位同事提出了这样的担忧:恶意或容易发生事故的开发人员可能会使用 git rebase 从我们的共享存储库中删除远程历史记录。
编辑:正如答案中所指出的,也可以使用 git push origin :branch-name 从远程存储库中删除整个分支。
这是一个现实问题吗?如果是这样,我们可以采取什么方法来预防呢?
As we consider moving from SVN to git at work, a coworker has raised the concern that a malicious or accident-prone developer could use git rebase
to delete remote history from our shared repo.
Edit: As pointed out in the answers, entire branches could also be deleted from the remote repo with git push origin :branch-name
.
Is this a realistic problem? If so, what approach can we take to prevent it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我倾向于同意你的同事的观点,这里存在一个问题,因为:
您考虑过
receive.denyNonFastForwards
和receive.denyDeletes
配置参数? AFAICT 这些在 Git 1.6 及以上版本中可用。来自 Pro Git:
正如作者提到的,此规则也可以通过接收挂钩(即 稍后在 Pro Git 中描述)。
这些技术应该可以防止共享存储库中意外(或恶意)丢失历史记录。
I tend to agree with your coworker that there is a problem here because:
Have you considered the
receive.denyNonFastForwards
andreceive.denyDeletes
config parameters? AFAICT these are available in Git 1.6 onwards.From Pro Git:
As the author mentions, this rule can also be enforced via a receive hook (which is described later in Pro Git).
These techniques should protect against accidental (or malicious) lost history in your shared repo.
使用rebase可能会弄乱历史记录,但通常远程repo不会接受修改历史记录的更改(除非你使用git push --force),但更重要的是,具有push权限的开发人员可以完全删除分支(git push起源:分支名称)。所以简单的规则是:
不要让推送权限给你不信任的开发者。
共享存储库时,不要弄乱历史记录,避免对过去的提交使用变基。如果您需要从不同分支添加某些内容,请使用合并或樱桃选择,在这种情况下,历史记录不会受到影响。
您可以维持在共享存储库上不使用“push -f”的策略,在这种情况下,开发人员会知道,如果推送被拒绝,则会出现问题(很可能本地分支未与远程分支保持同步)并且应该在本地解决问题,而不是强制推送。
关于您的问题如何防止 - 使用 Gerrit 修订系统,这就像开发人员的本地存储库和主存储库之间的提交方式,具有良好的 Web 界面进行修订,您可以向任何人授予推送到修订存储库的权限,但更改将在验证和批准后合并到您的主分支中(这需要您的一些权限)通常授予核心开发人员)。您可能会在 Mahara 项目中看到它的样子: https://reviews.mahara.org 在这种特殊情况下,只有 gerrit 机器人可以推送到 master(此处),其他任何人都不允许。
The history can be messed up using rebase, but normally remote repo will not accept the change that modifies the history (unless you use git push --force), but even more, the developer with push permission can delete the branch completely (git push origin :branch-name). So the simple rules are:
Do not let push permission to developers you do not trust.
When the repo is shared, do not mess with a history, avoid using rebase on past commits. Use merge or cherry-pick instead if you need to add something from different branch, in which case the history will not be affected.
You may maintain the policy of not using 'push -f' on shared repo, in which case developer will know that if the push is rejected then something goes wrong (most likely local branch is not up to date with remote) and should resolve the problem locally rather than forcing the push.
Regarding your question how to prevent - use Gerrit revision system, it is like an intermediate step on the way of the commit between developer's local repository and master repo with nice web interface for revision, you may give permissions to push to revision repository to anyone, but the change will be merged into your master branch after verification and approval (which require some permissions you usually grant to core developers). You may see how it looks like on the Mahara project: https://reviews.mahara.org In this particular case, only gerrit bot is allowed to push to master (which is here) and noone else.
企业 Git 服务器有一些扩展,例如 Gerrit,可以检测历史记录重写和分支删除,将它们备份到特殊的引用下,以便在需要时可以恢复它们,并且不会被垃圾收集删除。如果出于法律原因需要,Gerrit 管理员仍然可以删除选定的提交。
There are extensions to enterprise Git servers like Gerrit that will detect history rewrites and branch deletions, will back them up under a special ref so that they can be restored if needed and will not be pruned by garbage collection. Gerrit administrators can still remove selected commits if needed for legal reasons.