Git 只允许 Fast-Forward 类型的推送

剩下的最后一项任务是指定只接受 fast-forward 的推送。在 Git 1.6 或者更新版本里,只需要设定receive.denyDeletes 和 receive.denyNonFastForwards 选项就可以了。但是通过挂钩的实现可以在旧版本的 Git 上工作,并且通过一定的修改它它可以做到只针对某些用户执行,或者更多以后可能用的到的规则。

检查这一项的逻辑是看看提交里是否包含从旧版本里能找到但在新版本里却找不到的内容。如果没有,那这是一次纯 fast-forward 的推送;如果有,那我们拒绝此次推送:

[code]# 只允许纯 fast-forward 推送
def check_fast_forward
missed_refs = git rev-list #{$newrev}..#{$oldrev}
missed_ref_count = missed_refs.split(“\n”).size
if missed_ref_count > 0
puts “[POLICY] Cannot push a non fast-forward reference”
exit 1
end
end

check_fast_forward[/code]

一切都设定好了。如果现在运行 chmod u+x .git/hooks/update —— 修改包含以上内容文件的权限,然后尝试推送一个包含非 fast-forward 类型的索引,会得到一下提示:

$ git push -f origin master Counting objects: 5, done. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 323 bytes, done. Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) [POLICY] Cannot push a non fast-forward reference error: hooks/update exited with error code 1 error: hook declined to update refs/heads/master To git@gitserver:project.git ! [remote rejected] master -> master (hook declined) error: failed to push some refs to 'git@gitserver:project.git'

这里有几个有趣的信息。首先,我们可以看到挂钩运行的起点:

Enforcing Policies... (refs/heads/master) (8338c5) (c5b616)

注意这是从 update 脚本开头输出到标准你输出的。所有从脚本输出的提示都会发送到客户端,这点很重要。

下一个值得注意的部分是错误信息。

[POLICY] Cannot push a non fast-forward reference error: hooks/update exited with error code 1 error: hook declined to update refs/heads/master

第一行是我们的脚本输出的,在往下是 Git 在告诉我们 update 脚本退出时返回了非零值因而推送遭到了拒绝。最后一点:

To git@gitserver:project.git ! [remote rejected] master -> master (hook declined) error: failed to push some refs to 'git@gitserver:project.git'

我们将为每一个被挂钩拒之门外的索引受到一条远程信息,解释它被拒绝是因为一个挂钩的原因。

而且,如果那个 ref 字符串没有包含在任何的提交里,我们将看到前面脚本里输出的错误信息:

[POLICY] Your message is not formatted correctly

又或者某人想修改一个自己不具备权限的文件然后推送了一个包含它的提交,他将看到类似的提示。比如,一个文档作者尝试推送一个修改到 lib 目录的提交,他会看到

[POLICY] You do not have access to push to lib/test.rb

全在这了。从这里开始,只要 update 脚本存在并且可执行,我们的仓库永远都不会遭到回转或者包含不符合要求信息的提交内容,并且用户都被锁在了沙箱里面。

REF:http://cwiki.ossez.com/pages/viewpage.action?pageId=7045937