如何在服务器端 git 挂钩中获取推送用户信息?

How can I get push user information in server side git hook?

我想阻止用户使用服务器端挂钩(更新挂钩)删除远程 git 分支。

我已经在更新挂钩中编写了 shell 脚本来实现这一点。
现在我可以阻止所有用户删除远程git分支,但我想给特定用户删除权限,以为此,我们需要获取谁在服务器端挂钩中尝试删除操作的用户信息(用户名、用户邮箱)?

我们有 $USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL 等变量来获取客户端挂钩中的用户信息,但它们在服务器端挂钩中没有用。

我们是否有任何其他选项来在服务器端挂钩中获取用户信息?

Sample hook code

请记住,每个人都可以在提交中伪造电子邮件:

git commit -c user.name ... -c user.email ...

为了避免它,请访问您的中央存储库文档并阅读用户权限(每个服务器之间有所不同)并从那里提取有关如何获取用户详细信息的信息。

#!/bin/sh
#

# Extract the desired information from the log message
# You can also use the information passed out by the central repo if its available

# %ae = Extract the user email from the last commit (author email)
USER_EMAIL=$(git log -1 --format=format:%ae HEAD)

# %an = Extract the username from the last commit (author name)
USER_NAME=$(git log -1 --format=format:%an HEAD)

# or use those values if you have them:
# $USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL

#
#... Check the branches and whatever you want to do ...
#

# personal touch :-)
echo "                                         "
echo "                   |ZZzzz                "
echo "                   |                     "
echo "                   |                     "
echo "      |ZZzzz      /^\            |ZZzzz  "
echo "      |          |~~~|           |       "
echo "      |        |-     -|        / \      "
echo "     /^\       |[]+    |       |^^^|     "
echo "  |^^^^^^^|    |    +[]|       |   |     "
echo "  |    +[]|/\/\/\/\^/\/\/\/\/|^^^^^^^|   "
echo "  |+[]+   |~~~~~~~~~~~~~~~~~~|    +[]|   "
echo "  |       |  []   /^\   []   |+[]+   |   "
echo "  |   +[]+|  []  || ||  []   |   +[]+|   "
echo "  |[]+    |      || ||       |[]+    |   "
echo "  |_______|------------------|_______|   "
echo "                                         "
echo "                                         "

这里我得到了解决方案。

https://github.com/jakubgarfield/Bonobo-Git-Server/issues/494

我们使用 bonobo git 服务器作为版本控制。

在服务器端你可以得到试图用git cat-file commit SHA

推送的commit

就是说,它有一个 HEADER 可以为您提供此类信息。这可能是错误的或者我被篡改了,但是在服务器端是可用的。

像这样就可以了。在以下代码中,请注意三个相关变量:$CATAUTHOREMAIL$CATAUTHOR$CATEMAIL.

# --- Command line arguments
refname=""
oldrev=""
newrev=""

echo
echo '*** Checking your push update...'

MISSREVS=`git rev-list ${oldrev}..${newrev}`
CATAUTHOREMAIL=""
CMTMSG=""
for RV in ${MISSREVS} ; do
    if [ -z "$CATAUTHOREMAIL" ] ; then
        CATAUTHOREMAIL=`git cat-file commit ${RV} | grep author`
    fi  
    CMTMSG="$CMTMSG "`git cat-file commit ${RV} | sed '1,/^$/d'`
done

REMSG="author (.*) <"
[[ $CATAUTHOREMAIL =~ $REMSG ]]
CATAUTHOR="${BASH_REMATCH[1]}"
REMSG="author.*<(.*)>.*"
[[ $CATAUTHOREMAIL =~ $REMSG ]]
CATEMAIL="${BASH_REMATCH[1]}"
echo "*** Last commit author = $CATAUTHOR"
echo "*** Last commit email = $CATEMAIL"

这很有用。我写这个答案的灵感来自@codewizard 的答案,因为它只适用于客户端,不适用于服务器端。我需要服务器端的 "something"。不是fool-proof,但是很有用

  • 如果你分析提交header,你可以获取更多信息;例如,您还有 "commiter's name" 不一定是提交的作者。

  • 上面代码的循环将迭代所有提交。您可能只想获取最后(最近)提交的作者,就像代码对 if [ -z "$CATAUTHOREMAIL ] 所做的那样,或者您可能希望将它们全部保存在一个数组或其他东西中。您可以根据需要更改此模板。

  • 我使用了 grep author,但是如果在提交消息中出现 author 这个词,它就会中断......所以,你可能想要找到更好的过滤器,例如,将 header 与提交的 body 分开;即第一个空行。