如何在中央“开发存储库”中配置只读分支?

时间:2013-01-24 13:11:17

标签: git

我必须为受控git存储库的某些远程分支配置只读访问权限。

方案如下:

对于我们的开发,我们有一个内部“开发存储库”(1),它反映了“外部存储库”。此“开发存储库”定期更新(git remote update作业中的cron。我们的开发发生在来自外部存储库的分支“dev_ *”派生中,但永远不会指向外部分支上的

Repositories schema

master添加功能的工作流程:

  1. 我们创建了一个dev_master分支,其中master为父级。
  2. John克隆存储库development,检出dev_master,对其进行操作,并定期推送回development
  3. 如果存储库external更新mastermaster中的development也是如此(由于上面提到的cronjob),有人可以合并masterdev_master上,我们与external保持同步。
  4. 我们需要禁止John推送到master的分支development,因此在external定期更新后,他的更改不会丢失。

    再次,原理图:

    Repositories summary


    注释

    (1)我发现有些人将此开发存储库称为“staging repository”(例如,在How do I setup a staging repository in git?中,已经呈现了非常类似的情况)

1 个答案:

答案 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)。