git:post-receive钩子中的空参数

17

我正在基于contrib目录下的post-receive-email脚本编写后置接收钩子,但是似乎oldrevnewrev参数为空。

该脚本如下:

#!/bin/bash

oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)

这个脚本是在推送时运行的,但是所有的$1$2$oldrev$newrev都是空的。我需要配置一些东西才能使它正常运行吗?

(如果有影响)此存储库是由gitolite创建的。

5个回答

54

我在搭建持续集成服务器时遇到了这个问题。由于参数不是通过命令行传递给 post-receive 的,而是通过 STDIN 传递的,因此您必须使用 read 命令来获取它们。以下是我的做法:

#!/bin/sh
read oldrev newrev refname
BRANCH=${refname#refs/heads/} 
curl --request POST "http://my.ci.server/hooks/build/myproject_$BRANCH"

13

虽然信息是通过 STDIN 传递的,但没有参数。 要从 bash 中读取该信息,请执行以下操作:

read oldrev newrev refname
echo "Old revision: $oldrev"
echo "New revision: $newrev"
echo "Reference name: $refname"

我只是在总结已经发布的答案。


9
post-receive钩子不接受任何参数。引用手册(已加重)的说法:
此钩子由远程仓库上的git-receive-pack调用,当在本地仓库上执行git push时会发生这种情况。它在所有引用都被更新后在远程仓库上执行一次。
此钩子对于接收操作只执行一次。它不带任何参数,但在其标准输入上获取与pre-receive钩子相同的信息。
此钩子不影响git-receive-pack的结果,因为它在真正的工作完成后调用。
这取代了post-update钩子,因为它除了名称外还获取所有引用的旧值和新值。
标准输出和标准错误输出都转发到另一端的git send-pack,因此您可以为用户简单地回显消息。
默认的post-receive钩子为空,但是在git分发的contrib/hooks目录中提供了一个名为post-receive-email的示例脚本,用于实现发送提交电子邮件。

3
弗朗索瓦脚本的更详细版本如下:
#!/bin/bash

JENKINS_URL="http://192.168.1.116/jenkins"
GIT_URL="git@bitbucket.org:nuclos/nuclos.git"

# remove all spaces and newlines from ARG
trim() {
  local ARG="$1"
  shift
  echo -e "$ARG" | tr -d "[:space:]\n" 
}

# unique sort ARG items separated by newlines
unique() {
  local ARG="$1"
  shift
  echo -e "$ARG" | sort -u -i
}

# cut first and last character from ARG
cutfl() {
  local ARG="$1"
  shift
  local LEN="${#ARG}"
  let LEN="$LEN - 2"
  echo "${ARG:1:$LEN}"
}
BRANCHES=""
while read oldrev newrev refname; do
  BRANCH=`trim ${refname#refs/heads/}`
  if [ -n "$BRANCH" ]; then
    BRANCHES+="${BRANCH}\n"
  fi
done

BRANCHES=`unique "$BRANCHES" | tr '\n' ','`
BRANCHES=`cutfl "$BRANCHES"`
echo wget -q -O - "$JENKINS_URL/git/notifyCommit?url=$GIT_URL&branches=$BRANCHES"
at "now + 5 minutes" <<END
wget -q -O - "$JENKINS_URL/git/notifyCommit?url=$GIT_URL&branches=$BRANCHES"
END

这个版本可以处理多个分支,并且每个分支只触发一次构建。


1
实际上,我不接受“它不需要参数”的说法,因为示例脚本post-receive.sample有以下注释:
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master

4
它通过标准输入接收参数,这就是被接受的答案所提到的内容。 - Viktor Stískala
1
这个脚本的注释中也提到了。 - sappjw

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