如何找到当前处于分离HEAD状态的git分支
我可以通过执行以下任一操作找到当前的 git 分支名称:
git branch | awk '/^\*/ { print $2 }'
git describe --contains --all HEAD
但是当处于分离的 HEAD 状态时,例如在 Jenkins maven build(或在 Travis git fetch 中),这些命令不起作用。
我当前的工作解决方案是这样的:
git show-ref | grep $(git log --pretty=%h -1) | sed 's|.*/\(.*\)|\1|' | sort -u | grep -v HEAD
它显示其 HEAD 尖端上有最后一次提交的任何分支名称。这工作正常,但我觉得具有更强 git-fu 的人可能有更漂亮的解决方案?
I can find the current git branch name by doing either of these:
git branch | awk '/^\*/ { print $2 }'
git describe --contains --all HEAD
But when in a detached HEAD state, such as in the post build phase in a Jenkins maven build (or in a Travis git fetch), these commands doesn't work.
My current working solution is this:
git show-ref | grep $(git log --pretty=%h -1) | sed 's|.*/\(.*\)|\1|' | sort -u | grep -v HEAD
It displays any branch name that has the last commit on its HEAD tip. This works fine, but I feel that someone with stronger git-fu might have a prettier solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
显然是丢弃(没有分支)。当然,您可能会得到任意数量的分支,这些分支可以描述当前的 HEAD(当然包括没有分支,具体取决于您如何进入无分支),这些分支可能已快进合并到本地分支(这是许多好的理由之一)为什么你应该总是使用 git merge --no-ff )。
Obviously discarding (no branch). Of course, you may get an arbitrary number of branches which could describe the current HEAD (including of course none depending on how you got onto no-branch) which might have be fast-forward merged into the local branch (one of many good reasons why you should always use
git merge --no-ff
).sed
解决方案:它使用
log
检查最后一项是否存在于分支上。然后,sed
找到以origin/
开头的分支,并删除该短语及其之前的所有内容。然后 sed 再次删除任何可能的附加列出的分支(逗号及其后面的所有内容)。最后一个log
被用作健全性检查,以确保此分离的 HEAD 不是已知分支 HEAD 之上的提交。如果这是空的,则可以实现故障安全逻辑来将分支标记为“分离”(或“未定义”?)或确保它是最新的或回滚到已知 HEAD 的尖端。
A
sed
solution:This uses
log
to check the last item for its presence on a branch. Thensed
finds the branch preceded byorigin/
and removes the phrase and everything before it. Thensed
does another removal of any possible additional listed branches (comma and everything after it). The reason lastlog
was used as a sanity check to ensure this detached HEAD is not a commit above known branch HEADs.If this is empty, failsafe logic can be implemented to label the branch "detached" (or "undefined"?) or to ensure it's up-to-date or rolled back to the tip of a known HEAD.
我更喜欢使用这个:
如果签出分支的头部以及当前签出是分离的头部并且不需要网络访问,则它可以正常工作。
I prefer to use this one:
It works fine if the head of a branch is checked out as well as when the current checkout is a detached head and it requires no network access.
这是 git nthlastcheckout ,它从引用日志中获取您用于第 n 次最后结帐的确切字符串:
示例:
Here's
git nthlastcheckout
, it gets the exact string you used for your nth last checkout from the reflog:Examples:
我在 bitbucket 管道上工作的最短:
The shortest I got working on bitbucket pipelines:
这是我在我的一个项目中使用的:
This is what I am using in one of my projects:
对于任何尝试从 Gradle 中执行此操作的人(例如,通过您自己的自定义任务、插件等),您可以使用 Grgit 插件,提供 Gradle-Git 桥梁。事实上,如果你正在使用 Nebula Release 插件,那么 Grgit 已经是存在于您的构建中。
因此,使用 Grgit,解析指向当前分离的
HEAD
的远程分支如下所示:For anyone attempting to do this from within Gradle (say, via your own custom task, plugin, etc..) you can use the Grgit Plugin, which provides a Gradle-Git bridge. In fact, if you are using the Nebula Release plugin, then Grgit is already present in your build.
And so with Grgit, resolving the remote branch that points to your current detached
HEAD
looks like this:更简洁的方式:
引用将以
(HEAD, master)
的格式列出 - 如果您打算在脚本中使用它而不是供人类使用,则必须对其进行一些解析。您还可以自己更干净地实现它:
好处是将候选引用放在单独的行上,没有额外的字符。
A more porcelain way:
The refs will be listed in the format
(HEAD, master)
- you'll have to parse it a little bit if you intend to use this in scripts rather than for human consumption.You could also implement it yourself a little more cleanly:
with the benefit of getting the candidate refs on separate lines, with no extra characters.
我需要为 Jenkins 提供一些不同的解决方案,因为它没有分支的本地副本。因此,当前提交必须与远程分支匹配:
或没有网络:
还值得注意的是,当同一提交中有多个分支头时,这可能会返回多个分支名称。
更新:
我刚刚注意到 Jenkins 设置了 GIT_BRANCH 环境变量,其中包含像 origin/master 这样的值。这也可以用来在 Jenksin 中获取 git 分支:
I needed a bit different solution for Jenkins because it does not have local copies of the branches. So the current commit must be matched against the remote branches:
or without network:
It's also worth noting that this might return multiple branch names when you have multiple branch heads at the same commit.
UPDATE:
I just noticed that Jenkins sets
GIT_BRANCH
environment variable which contains a value likeorigin/master
. This can be used to get git branch in Jenksin too: