我必须为受控git存储库的某些远程分支配置只读访问权限。
方案如下:
对于我们的开发,我们有一个内部“开发存储库”(1),它反映了“外部存储库”。此“开发存储库”定期更新(git remote update
作业中的cron
。我们的开发发生在来自外部存储库的分支“dev_ *”派生中,但永远不会指向外部分支上的:
向master
添加功能的工作流程:
dev_master
分支,其中master
为父级。development
,检出dev_master
,对其进行操作,并定期推送回development
。external
更新master
,master
中的development
也是如此(由于上面提到的cronjob),有人可以合并master
在dev_master
上,我们与external
保持同步。我们需要禁止John推送到master
的分支development
,因此在external
定期更新后,他的更改不会丢失。
再次,原理图:
(1)我发现有些人将此开发存储库称为“staging repository”(例如,在How do I setup a staging repository in git?中,已经呈现了非常类似的情况)
答案 0 :(得分:3)
我使用Server-Side hook禁止这些推送。来自git help hooks
:
的预接收
这个钩子由远程存储库上的git-receive-pack调用,这发生在 git push在本地存储库上完成。就在开始更新refs之前 远程存储库,调用预接收挂钩。它的退出状态决定了 更新成功或失败。
[...]
如果钩子以非零状态退出,则不会更新任何引用。如果钩 如果退出为零,则更新仍可以防止更新单个引用 钩。
[...]
钩子代码:
#!/bin/bash
# Read the branches of the remote repository
remote_branches=$(git ls-remote --heads | sed "s,.*\(refs/heads/\),\1,")
function forbid_push_to_remote_branches()
{
while read old_value new_value ref_name
do
# Test for existence of [$ref_name] in remote
for remote_branch in $remote_branches
do
if [[ $remote_branch == $ref_name ]]
then
invalid_refs="$invalid_refs [$remote_branch]"
break
fi
done
done
# if remote read-only branches found, exit with non-zero
# and list these branches
if [[ -n $invalid_refs ]]
then
echo "ERROR: You are trying to push to remote branch(es):" >&2
echo " $invalid_refs" >&2
return 1
else
return 0
fi
}
forbid_push_to_remote_branches
exit $?
此代码必须复制到服务器中的文件$(bare_repo_path.git)/hooks/pre-receive
(没有pre-receive.sample
)。