我正在设计一个Jenkins构建系统,当任何标记被推送到repo时触发。从那里,我们想知道标签所引用的提交被推送到哪个分支。从那里,我基于该分支名称启动其他Jenkins构建。除了找出标记了哪个分支外,此管道中的所有内容都很简单。
基本上,我的团队制作了并且目前正在使用production
和staging
分支 - 当开发人员将内容合并到production
或staging
时,想要发布,他们会标记版本号,然后将其推出。然后,Jenkins可以在生产分支上使用该标记更新生产服务器,并使用标记登台到分段分支。如果master
被标记,那么我将启动CI构建和测试。
我一直在这篇博客文章中测试方法:http://johndstein-blog.logdown.com/posts/428667提供以下内容:
export HASH=$(git rev-parse HEAD)
export BRANCH=$(basename $(git branch -r --contains ${HASH}))
export TAG=$(basename $(git describe --all --exact-match ${HASH}))
echo "HASH: $HASH"
echo "BRANCH: $BRANCH"
echo "TAG: $TAG"
但这在100%的时间内都不起作用 - 对于某些回购,当运行第2行(抓取分支)时 - 我得到多个分支,并且它出错了。我对git很新,但据我所知,这是因为提交是在一个分支中进行并合并到另一个分支中。
我的问题是,如果我有标签,我能否可靠地找到最初推送到的分支的名称?而且,这是一种聪明的方式吗?
答案 0 :(得分:1)
一般情况下这是不可能的。 “最初被推到”甚至没有明确定义,如果没有选择一些“原创”并使其保持原木。
这是一个例子。假设我创建了分支sneak
和gotcha
:
C <-- sneak
/
A--B <-- master
\
D <-- gotcha
现在,如果我git push
这些分支中的一个或两个,接收Git存储库将获得两个提交C
和D
以及更新名称refs/heads/sneak
的请求和refs/heads/gotcha
。到目前为止,一切似乎都很好。但现在我这样做而不是推动,或者在推得足够快之后非常迅速,以至于你无法进入看我在做什么:
$ git push origin sneak:sneak gotcha:gotcha &&
> git checkout master &&
> git merge sneak gotcha &&
> git push origin master:master :sneak :gotcha
git merge
使章鱼合并(当然我已经安排成功,否则这需要我太长时间来欺骗你:-))。 push
步骤然后将提交E
发送到服务器,同时请求更新refs/heads/master
以指向它,以及删除 refs/heads/sneak
和refs/heads/gotcha
。结果是:
C
/ \
A--B---E <-- master
\ /
D
提交和/或推送了哪些分支C
和D
?好吧,在我们覆盖并删除它之前,我们在服务器上有大约6毫秒的信息。
更糟糕的是,我推送的地方可能是推镜,而真正的服务器又回来了。推镜可能有两到三秒钟的信息,有足够的时间来抓取它...但是推镜和真实(终点)服务器之间的链接是起作用,在这三秒钟内我覆盖了它,这样推镜就可以通过一个请求将提交C
,D
和E
发送到真实服务器更新refs/heads/master
以指向提交E
。
现在,如果我们将“最初推送到”定义为“发送到推送镜像”,和我们使推送镜像保留日志,日志将显示我最初要求提交{ {1}}转到C
并提交sneak
以转到D
。假设推送镜像和最终中央服务器之间出现链路断开故障,该日志就是唯一的位置,并带有此信息。你可以安排一个侧面通道来检索这个,但是这些都没有内置到Git中(即使是日志记录也有问题:你可以尝试使用Git的reflogs但是它们可能不够精细,如果你关心多次推送第二,真正严格的订购)。
默认情况下,裸存储库(和推送镜像)不启用Reflog,但您可以使用简单的gotcha
启用它们。
要担心的主要事实是提交可以在零,一个或多个分支上。 1 诀窍是不依赖于分支名称除非你是控制这些名字的人。您可以在git config
和pre-receive
挂钩中对分支名称进行简短的控制,但使用起来很棘手。
最好的办法是不要依赖名称,而是要求一些单独的指示符,例如嵌入在提交消息本身中的字符串(并且您可以使用预接收挂钩来检查这一点)。或者,您可以简单地要求您的标记名称具有明确定义的格式:
post-receive
或其他什么。标签的名称告诉您特定提交的意图是什么,并且完全独立于任何包含分支。
1 提交 no 分支有点不寻常,但很容易创建:只需标记分支提示,然后删除分支名称。您可以推送标记,并使用标记将提交转发到接收服务器,但不使用分支。