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



我有一个场景,在bitbucket上我已经分配了分支权限,但当用户在本地执行提交并试图将其推送到特定分支时,他会在推送时知道错误,因此切换到其他分支并再次进行提交是一种返工。所以,我正在考虑像预推送或预提交这样的git挂钩,它可以在实际提交之前限制用户。有人能帮助我在这种情况下实现正确的客户端钩子吗?为什么要使用这个钩子?PS:不能实现任何服务器端挂钩。

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

一如既往,客户端挂钩只为选择使用它们的用户提供便利。听起来这对您的用例来说很好,但请记住,这确实意味着必须为每个克隆进行设置,这意味着权限逻辑必须对每个克隆可见(可能是复制的,既为了简单,又为了避免破坏git独立于中央服务器操作的能力(。

那么,你从哪里开始呢?

pre-commit是挂得最低的果实。"意外"更新ref的典型方法是,您将其签出并commit;并且第一个可以捕捉到它的时间点(如果需要,可以中止它(是pre-commit。您必须确定将更新哪个分支(如果有的话(——我认为您应该使用.git/HEAD

与Mark Adelsberger一样,我认为您希望使用预提交来尽早发现客户端不在正确分支上的事实。

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

#!/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文章与此相关,下面是一篇。在所有情况下,都没有直接的方法来做到这一点

最新更新