![](/img/trans.png)
[英]git: How do I get the hash of the latest commit in the current branch when in detached HEAD state?
[英]How to find the current git branch in detached HEAD state
通过执行以下任一操作,我可以找到当前的 git 分支名称:
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.
我目前的工作解决方案是这样的:
git show-ref | grep $(git log --pretty=%h -1) | sed 's|.*/\(.*\)|\1|' | sort -u | grep -v HEAD
它显示在其 HEAD 提示上具有最后一次提交的任何分支名称。 这很好用,但我觉得 git-fu 更强大的人可能有更漂亮的解决方案?
更瓷器的方式:
git log -n 1 --pretty=%d HEAD
# or equivalently:
git show -s --pretty=%d HEAD
refs 将以(HEAD, master)
格式列出 - 如果您打算在脚本中使用它而不是供人类消费,则必须对其进行一些解析。
你也可以自己更干净地实现它:
git for-each-ref --format='%(objectname) %(refname:short)' refs/heads | awk "/^$(git rev-parse HEAD)/ {print \$2}"
好处是可以在单独的行上获取候选参考,没有额外的字符。
我需要为 Jenkins 提供一些不同的解决方案,因为它没有分支的本地副本。 所以当前提交必须与远程分支匹配:
git ls-remote --heads origin | grep $(git rev-parse HEAD) | cut -d / -f 3
或没有网络:
git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p'
还值得注意的是,当您在同一提交中有多个分支负责人时,这可能会返回多个分支名称。
更新:
我刚刚注意到 Jenkins 设置了GIT_BRANCH
环境变量,其中包含一个类似origin/master
的值。 这也可用于在 Jenksin 中获取 git 分支:
echo $GIT_BRANCH | cut -d / -f 2
git branch --contains HEAD
明显丢弃(无分支)。 当然,您可能会得到任意数量的分支,这些分支可以描述当前的 HEAD(当然包括没有分支,这取决于您如何进入无分支),这些分支可能已快速合并到本地分支中(许多很好的原因之一)为什么你应该总是使用git merge --no-ff
)。
一个sed
解决方案:
git log -1 --pretty=%D HEAD | sed 's/.*origin\///g;s/, .*//g'
这使用log
来检查最后一项是否存在于分支上。 然后sed
找到以origin/
sed
的分支并删除该短语及其之前的所有内容。 然后sed
再次删除任何可能的附加列出的分支(逗号及其后的所有内容)。 最后一个log
被用作健全性检查的原因是为了确保这个分离的 HEAD 不是已知分支 HEAD 之上的提交。
如果这是空的,可以实现故障安全逻辑来标记分支“分离”(或“未定义”?)或确保它是最新的或回滚到已知 HEAD 的尖端。
如果您在分支上,则git symbolic-ref HEAD
返回refs/heads/branchname
否则返回错误。
这是git nthlastcheckout
,它从引用日志中获取您用于第 n 次最后一次结帐的确切字符串:
git config --global alias.nthlastcheckout '!nthlastcheckout'"() {
git reflog |
awk '\$3==\"checkout:\" {++n}
n=='\${1-1}' {print \$NF; exit}
END {exit n!='\${1-1}'}'
}; nthlastcheckout \"\$@\""
例子:
$ git nthlastcheckout
master
$ git nthlastcheckout 2
v1.3.0^2
我在 bitbucket 管道上工作的最短时间:
git show -s --pretty=%D HEAD | awk '{gsub("origin/", ""); print $2}'
我更喜欢使用这个:
git branch --remote --contains | sed "s|[[:space:]]*origin/||"
如果分支的头部被签出以及当前签出是一个分离的头部并且不需要网络访问时,它工作正常。
这是我在我的一个项目中使用的:
const { execSync } = require('child_process');
const getBranchName = () => {
let branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
if (branch === 'HEAD') branch = execSync(`git branch -a --contains HEAD | sed -n 2p | awk '{ printf $1 }'`).toString().trim();
return branch;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.