查找最初出现提交的分支 (git/Jenkins/CD)
Finding the branch where a commit originally appears (git/Jenkins/CD)
我正在设计一个 Jenkins 构建系统,它会在任何标签被推送到存储库时触发。从那里,我们想知道标签引用的提交被推送到哪个分支。从那里,我根据该分支名称启动其他 Jenkins 构建。除了找出标记了哪个分支之外,此管道中的所有内容都很简单。
基本上,我的团队制作并正在使用 production
和 staging
分支 - 当开发人员将东西合并到 production
或 staging
中并想要发布时,他们将标记一个版本号,并将其推出。然后,Jenkins 可以在生产分支上使用该标签更新生产服务器,以及使用标签登台到暂存分支。如果 master
被标记,那么我将启动 CI 构建和测试。
我一直在测试此博客 post 中的方法: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 的新手,但据我所知,这是因为提交是在一个分支中进行的,然后合并到另一个分支中。
那么我的问题是,如果我有标签,我能否可靠地找到提交最初被推送到的分支的名称?此外,这是一种明智的做法吗?
这在一般情况下是不可能的。如果不选择一些 "original" 并使其保留日志,"Was originally pushed to" 甚至没有明确定义。
这是一个例子。假设我创建分支 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
以指向它的请求,以及 delete refs/heads/sneak
和 refs/heads/gotcha
。结果是:
C
/ \
A--B---E <-- master
\ /
D
C
和 D
提交了哪些分支 and/or 推进?好吧,在我们覆盖并删除它之前,我们在服务器上保存了大约六毫秒的信息。
更糟的是,也许我推送的地方是推送镜像,真正的服务器更靠后。推送镜像可能已经有两三秒的信息了,有足够的时间去抓它......但是推送镜像和真实之间的link (端点)服务器出现问题,在那三秒钟内我覆盖了它,因此推送镜像最终将提交 C
、D
和 E
发送到真实服务器,通过一个请求,更新 refs/heads/master
以指向提交 E
.
现在,如果我们将"originally pushed to"定义为"sent to the push mirror"、和我们让推送镜像保留一个日志,日志将显示我最初要求提交 C
进入 sneak
并提交 D
进入 gotcha
。假设推送镜像和最终中央服务器之间出现 link-down 故障,该日志是 唯一 包含此信息的地方。你可以安排一个侧通道来检索这个,但是 none 是内置到 Git 中的(即使日志记录也有问题:你可以尝试使用 Git 的 reflogs 但它们可能不够细粒度,如果你关心每秒多次推送和真正严格的排序)。
裸存储库(和推送镜像)默认不启用引用日志,但您可以通过简单的 git config
.
启用它们
综上所述...
主要担心的是提交可以在零个、一个或多个分支上。1诀窍是 不依赖于分支名称 除非你是控制这些名称的人。您可以短暂地控制 pre-receive
和 post-receive
挂钩中的分支名称,但使用起来很棘手。
你最好的选择是根本不依赖名称,而是需要一些单独的指示符,例如嵌入在提交消息本身中的字符串(你可以有一个预接收挂钩来检查它) .或者,您可以简单地要求您的标签 names 具有明确定义的格式:
production-v1.0.1
staging-v3.7
或其他什么。标记的名称告诉您该特定提交的目的是什么,并且完全独立于任何包含的分支。
1在 no 分支上的提交有些不寻常,但很容易创建:只需标记分支尖端提交,然后删除分支名称。您可以推送标签,并且提交会通过标签进入接收服务器,但没有分支。
我正在设计一个 Jenkins 构建系统,它会在任何标签被推送到存储库时触发。从那里,我们想知道标签引用的提交被推送到哪个分支。从那里,我根据该分支名称启动其他 Jenkins 构建。除了找出标记了哪个分支之外,此管道中的所有内容都很简单。
基本上,我的团队制作并正在使用 production
和 staging
分支 - 当开发人员将东西合并到 production
或 staging
中并想要发布时,他们将标记一个版本号,并将其推出。然后,Jenkins 可以在生产分支上使用该标签更新生产服务器,以及使用标签登台到暂存分支。如果 master
被标记,那么我将启动 CI 构建和测试。
我一直在测试此博客 post 中的方法: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 的新手,但据我所知,这是因为提交是在一个分支中进行的,然后合并到另一个分支中。
那么我的问题是,如果我有标签,我能否可靠地找到提交最初被推送到的分支的名称?此外,这是一种明智的做法吗?
这在一般情况下是不可能的。如果不选择一些 "original" 并使其保留日志,"Was originally pushed to" 甚至没有明确定义。
这是一个例子。假设我创建分支 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
以指向它的请求,以及 delete refs/heads/sneak
和 refs/heads/gotcha
。结果是:
C
/ \
A--B---E <-- master
\ /
D
C
和 D
提交了哪些分支 and/or 推进?好吧,在我们覆盖并删除它之前,我们在服务器上保存了大约六毫秒的信息。
更糟的是,也许我推送的地方是推送镜像,真正的服务器更靠后。推送镜像可能已经有两三秒的信息了,有足够的时间去抓它......但是推送镜像和真实之间的link (端点)服务器出现问题,在那三秒钟内我覆盖了它,因此推送镜像最终将提交 C
、D
和 E
发送到真实服务器,通过一个请求,更新 refs/heads/master
以指向提交 E
.
现在,如果我们将"originally pushed to"定义为"sent to the push mirror"、和我们让推送镜像保留一个日志,日志将显示我最初要求提交 C
进入 sneak
并提交 D
进入 gotcha
。假设推送镜像和最终中央服务器之间出现 link-down 故障,该日志是 唯一 包含此信息的地方。你可以安排一个侧通道来检索这个,但是 none 是内置到 Git 中的(即使日志记录也有问题:你可以尝试使用 Git 的 reflogs 但它们可能不够细粒度,如果你关心每秒多次推送和真正严格的排序)。
裸存储库(和推送镜像)默认不启用引用日志,但您可以通过简单的 git config
.
综上所述...
主要担心的是提交可以在零个、一个或多个分支上。1诀窍是 不依赖于分支名称 除非你是控制这些名称的人。您可以短暂地控制 pre-receive
和 post-receive
挂钩中的分支名称,但使用起来很棘手。
你最好的选择是根本不依赖名称,而是需要一些单独的指示符,例如嵌入在提交消息本身中的字符串(你可以有一个预接收挂钩来检查它) .或者,您可以简单地要求您的标签 names 具有明确定义的格式:
production-v1.0.1
staging-v3.7
或其他什么。标记的名称告诉您该特定提交的目的是什么,并且完全独立于任何包含的分支。
1在 no 分支上的提交有些不寻常,但很容易创建:只需标记分支尖端提交,然后删除分支名称。您可以推送标签,并且提交会通过标签进入接收服务器,但没有分支。