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

5
我希望能够通过服务器端钩子(更新钩子)阻止用户删除远程git分支。
我已经在更新钩子中编写了shell脚本来实现这一点。
现在我可以阻止所有用户删除远程git分支,但我想授予特定用户删除权限,为了做到这一点,我们需要在服务器端钩子中获取试图执行删除操作的用户信息(用户名、用户邮件地址)?
在客户端钩子中,我们有$USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL等变量以获取用户信息,但它们在服务器端钩子中无法使用。
我们是否有其他选项来在服务器端钩子中获取用户信息?
3个回答

7

示例钩子代码

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

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 "                                         "

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Surendra Reddy
$USER、$GIT_AUTHOR_NAME、$GIT_AUTHOR_EMAIL 用于获取客户端钩子的详细信息,但在服务器端钩子中无法使用。 - Surendra Reddy
你可以通过限制允许的协议为ssh来控制它,这意味着服务器必须对您进行身份验证,而不管传递给服务器的值如何,身份验证是通过ssh密钥完成的。如何实现取决于您的中央仓库。 - CodeWizard
1
我为你写了一个例子,演示如何通过日志命令在服务器端获取它。 - CodeWizard

1

0

在服务器端,您可以使用 git cat-file commit SHA 获取正在尝试推送的 commit

话虽如此,它有一个标题,提供了这样的信息。这可能是错误的或者可能被篡改,但这在服务器端是可用的。

像这样的东西就可以了。在下面的代码中,关注三个相关变量:$CATAUTHOREMAIL$CATAUTHOR$CATEMAIL

# --- Command line arguments
refname="$1"
oldrev="$2"
newrev="$3"

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的启发,因为它只适用于客户端,而不是服务器端。而我需要从服务器端获取“某些东西”。它并不是绝对可靠,但非常有用。

  • 如果你分析提交头,你可以获取更多信息;例如,你还有“提交者的姓名”,这不一定是提交的作者。

  • 上面代码中的循环将遍历所有提交。你可能只想获取最后(最近)一次提交的作者,就像代码使用那个if [ -z "$CATAUTHOREMAIL ]那样,或者你可能想将它们全部保存在一个数组或其他东西中。这取决于你根据自己的需求更改此模板。

  • 我使用了grep author,但如果在提交消息中出现单词author,它会出错...所以,你可能需要找到一个更好的过滤器,例如,将提交的头与正文分开;也就是说,第一个空行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接