git客户端挂钩,仅允许访问允许的分支

时间:2018-07-13 10:31:46

标签: git bitbucket githooks

我有一种方案,其中我在bitbucket上分配了分支权限,但是当用户在本地执行提交并尝试将其推送到特定分支时,他在推送时就知道了错误,因此对于他切换到其他分支,然后再次提交。因此,我想到了像pre-push或pre-commit这样的git钩子,它可以在实际提交之前限制用户。有人可以在这种情况下实施正确的客户端挂钩吗?为什么要使用该挂钩? PS:无法实现服务器端挂钩。

2 个答案:

答案 0 :(得分:2)

这不是一个容易解决的客户端挂钩问题。与服务器端不同,在服务器端,您希望每次写入都以收到的推送形式进行,而在客户端,用户可以通过多种方式与本地存储库进行交互。我知道没有一个钩子能抓住所有人。实际上,其中一些可能根本不会被任何钩子抓住。 (我想不出一种检测本地reset或快速合并的方法。如果您的工作流程如此,开发人员通常不会做这些事情,那当然会有所帮助。)

与往常一样,客户端挂钩仅是选择使用它们的用户的便利。听起来这对您的用例来说很好,尽管请记住,这确实意味着必须为每个克隆进行设置,并且这意味着权限逻辑必须可见(为了简化和避免破坏git的能力,必须对其进行复制。每个克隆都独立于中央服务器进行操作。

那么,您将从哪里开始?

嗯,pre-commit是挂得最少的水果。 “偶然地”更新参考的典型方法是,将其签出,然后commit;并且您可以捕获(并根据需要中止)的第一个时间点是pre-commit。您必须确定将更新哪个分支(如果有的话)-我认为您应该为此使用.git/HEAD

答案 1 :(得分:2)

就像Mark Adelsberger一样,我认为您想使用pre-commit来抓住这样一个事实,即客户尽早不在正确的分支机构上。

这是一个预提交脚本的示例,用于检测分支是否受保护。

#!/bin/sh

# Generic function to verify if a word is part of a list of words (space-separated)
contains() {
    # 1 is the element to verify
    local element=$1
    shift
    # All other arguments are part of the list that may contain the element or not
    # so you don't need to quote the arg when calling this function
    local list="$@"

    case $list in
        $element                        |\
        $element[[:blank:]]*            |\
        *[[:blank:]]$element            |\
        *[[:blank:]]$element[[:blank:]]*)
            # The element is contained in the list
            return 0
            ;;
    esac
    # The element is not contained in the list
    return 1
}

# Space-separated list of branches that should not be committed on
protected_branches='devtool master'
current_branch=$(git rev-parse --abbrev-ref HEAD)

contains $current_branch $protected_branches
if [ $? -eq 0 ]; then
    echo The current branch $current_branch is protected! Create your own before committing.
    exit 1
fi

要解决将挂钩推向客户端的问题,有几个与此相关的SO帖子,here is one。在所有情况下,都没有直接的方法。