如何在Jenkins Pipeline中识别合并提交?

4

当我将某些分支合并到主分支(在 GitHub 上)时,jenkins pipeline 就会触发。

有没有一种方法可以通过 git 的任何命令在 Jenkins 当前执行期间识别“这是一个合并提交”?(不是 webhook - 我正在寻找另一种解决方案)

简单来说:我有提交 ID 为 28c7be3b705fb517b09067e059fdlskkdjsa7ce0fd3 的提交,我想知道这个提交是否为合并请求(PR)到主分支。

2个回答

2
一种简单的方法是:检查此提交是否有第二个父提交。
if git rev-parse --verify -q $commitid^2 > /dev/null; then
   echo "commit $commitid is a merge commit"
else
   echo "commit $commitid is a simple commit"
fi
  • --verify 验证是否提供了一个参数,并且该参数可以转换为原始的20字节SHA-1,以便访问对象数据库。如果是,则将其发出到标准输出;否则,报错。
  • -q 仅在 --verify 模式下有意义。如果第一个参数不是有效的对象名称,则不输出错误消息;相反,静默地退出并具有非零状态。
  • $commitid 提交的长或短SHA-1哈希值。
  • ^2 符号 ^ 表示“该提交对象的第一个父对象”,加上 2 就变成了“该提交对象的第二个父对象”,因此 ^n = “该提交对象的第 n 个父对象”,如果提交没有第 n 个父对象,则命令返回值为 128(否则为 0)。
  • 在您的情况下,您不需要输出,因此可以将其重定向到 /dev/null -- 成功时,此命令将输入转换为其完整sha并将其打印在stdout上。

完整的 git rev-parse 文档可在此处找到。


如果您想检查 $commitid 是否是 Github 的一个 Pull requests 的一部分,那么这是一个不同的要求。

拉取请求信息的一部分(例如:特定 PR 指向的提交)存储在 git 中,但您将需要使用 Github API(链接在此处)来访问其他信息(例如:PR 状态、作者、讨论反馈等)

Github 为每个拉取请求创建以 refs/pull/ 为前缀的引用;对于拉取请求 {xx},该拉取请求的头存储在 refs/pull/{xx}/head 中,如果 PR 被合并,则合并结果存储在 refs/pull/{xx}/merge 中。

您可以使用它来查找当前提交是否是拉取请求的头:

# fetch references starting with 'refs/pull/...',
# store them locally next to the remote branches : 'refs/remotes/origin/pull/...'
#   (note: you can choose whatever pattern you want to store these references locally)
git fetch origin "+refs/pull/*:refs/remotes/origin/pull/*"

# check if one of these refs point to $commitid :
git for-each-ref --points-at "$commitid" refs/remotes/orign/pull

# you can use '--format' to customize the output :
# for example you can remove the leading 'refs/remotes/origin/pull' to have a shorter output :
$ git for-each-ref --format="%(refname:lstrip=4)" --points-at "$commitid" refs/remotes/orign/pull
42/head    # <- this means it is the current head of PR #42

现在您可以使用API来检查PR#42是否仍然处于打开状态:
curl \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/{myuser}/{myrepo}/pulls/42

谢谢。您能解释一下这些参数吗? 当我打开 GitHub 中的 PR 事件时,Jenkins 会说它是合并提交 - 实际上并不是。如何解决这种情况? - Jon Sud
更新了这个答案,并加入了@Max建议的解释。 - LeGEC

1
我想扩展LeGEC的答案
if git rev-parse --verify -q $commitid^2 > /dev/null; then
   echo "commit $commitid is a merge commit"
else
   echo "commit $commitid is a simple commit"
fi
  • --verify 验证是否提供了正好一个参数,且该参数可以转换为原始的20字节SHA-1,以便用于访问对象数据库。如果是,则将其发射到标准输出;否则出现错误。
  • -q 仅在--verify模式下有意义。如果第一个参数不是有效的对象名称,则不输出错误消息;相反,安静地退出并带有非零状态。
  • $commitid 表示一个提交的长或短SHA-1哈希。
  • ^2 符号^表示“该提交对象的第一个父节点”,加上2表示“该提交对象的第二个父节点”,所以^n代表“该提交对象的第n个父节点”,如果提交没有第n个父节点,则命令返回值为128(否则为0)。

完整文档可在此处找到。


您可以更新答案以添加所有参数。 - lucasvc
@Max:我在我的答案中复制了你的解释,谢谢。 - LeGEC

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