2

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

场景如下:

对于我们的开发,我们有一个内部“开发存储库” (1),它反映了一个“外部存储库”。这个“开发存储库”会定期更新(git remote updatecron工作中)。我们的开发发生在从外部存储库派生的分支“dev_*”中,但从不直接在外部分支上进行:

存储库架构

将功能添加到的工作流程master

  1. 我们创建一个作为父级dev_master的分支。master
  2. John 克隆存储库development、签出dev_master、处理它,并定期推送回development.
  3. 如果存储库externalmaster更新,那么masterdevelopment(由于上面提到的 cronjob),并且有人可以master在 上合并dev_master,所以我们与external.

我们需要禁止 John 推送到 的分支masterdevelopment这样他的更改不会在从 的定期更新后丢失external

再次,示意图:

存储库摘要


笔记

(1)我发现有些人称这个开发存储库为“暂存存储库”(例如,在How do I setup a staging repository in git?中,出现了非常相似的情况)

4

1 回答 1

3

我使用Server-Side hook禁止这些推送。来自git help hooks

pre-receive
这个钩子由远程存储库上的 git-receive-pack 调用,当在本地存储库上完成 git push 时会发生这种情况。就在开始更新远程存储库上的 refs 之前,调用了 pre-receive 钩子。它的退出状态决定了更新的成功或失败。
[...]
如果钩子以非零状态退出,则不会更新任何参考。如果钩子以零退出,更新钩子仍然可以阻止更新单个参考。
[...]

钩子代码:

#!/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)。

于 2013-01-24T13:11:17.083 回答