为了避免在使用(python)脚本检出某个git SHA时出现不必要的分离HEAD,我想检查一个分支,如果该SHA恰好是分支的当前HEAD。
理想情况下,我想为git提供SHA,如果SHA在分支的当前提示上,则返回分支名称,否则返回错误。
git describe --all --exact-match <SHA>
非常接近是我需要的,只是它主要针对标签,所以如果分支和标签指向我的SHA (例如,经常发生在我们的发布分支中),只给出了标记。这没用,因为签出标签会导致分离的HEAD(即使分支指向同一个SHA)。
注意,我不想git branch --contains
- 我不需要知道哪些分支包含我的提交。
如果没有像git describe
那样的命令,只是对于分支,我知道我可以通过git show-ref
对分支SHA进行交叉检查。不过,这不是最优雅的解决方案。
我也可以做git name-rev --name-only <hash>
,但是我必须手动检查~
个字符的输出,如果有一个git命令可以做同样的事情,这会感觉不自在。
答案 0 :(得分:8)
您可以尝试这样的事情:
git for-each-ref --format="%(refname:short) %(objectname)" 'refs/heads/' |
grep SHA1 | cut -d " " -f 1
这应该会为您提供当前位于修订版SHA1
的分支列表。
答案 1 :(得分:2)
如果您打算使用python,我会这样做:
import subprocess
def get_name(target):
p = subprocess.Popen(['git', 'for-each-ref', 'refs/heads/'], stdout=subprocess.PIPE)
for line in p.stdout:
sha1, kind, name = line.split()
if sha1 != target:
continue
return name
return None
另一个选择是使用eval的力量来构建字典:
d = '{' + subprocess.check_output(['git', 'for-each-ref', '--python', '--format=%(objectname): %(refname),', 'refs/heads/']) + '}'
name = eval(d)[sha1]
答案 2 :(得分:2)
随着即将推出的git 2.7(2015年第4季度),您将获得更完整版的git for-each-ref
,现在支持--points-at
git for-each-ref --points-at <branch_name>
使用doc:
--points-at <object>:
仅列出指向给定对象的引用。
这将允许检查提交是否是该列表的一部分。
请参阅commit 4a71109,commit ee2bd06,commit f266c91,commit 9d306b5,commit 7c32834,commit 35257aa,commit 5afcb90,..., commit b2172fd(2015年7月7日)和commit af83baf(2015年7月9日)Karthik Nayak (KarthikNayak
)。
(Junio C Hamano -- gitster
--合并于commit 9958dd8,2015年10月5日)
“
git tag -l
”和“git branch -l
”的某些功能已经完成 可用于“git for-each-ref
”,以便最终统一 在后续工作中,可以在所有三个方面共享实施 一两个系列。
* kn/for-each-tag-branch:
for-each-ref: add '--contains' option
ref-filter: implement '--contains' option
parse-options.h: add macros for '--contains' option
parse-option: rename parse_opt_with_commit()
for-each-ref: add '--merged' and '--no-merged' options
ref-filter: implement '--merged' and '--no-merged' options
ref-filter: add parse_opt_merge_filter()
for-each-ref: add '--points-at' option
ref-filter: implement '--points-at' option
答案 3 :(得分:1)
对于我的情况,我想知道HEAD是否指向分支 post-checkout 然后如果指向分支则退出0,或者如果不指向分支则退出非零,假设结账成功,很可能是分离的HEAD状态。 git symbolic-ref --short HEAD
执行此操作,并在指向分支时返回分支的名称。显然,有更好的解决方案可以满足OP的需求,但我想把它放在以防万一有人想要利用这些信息。
答案 4 :(得分:1)
要获取提交或标记引用的分支名称,我想出了这个.gitconfig
:
[alias]
branch-name = !"git for-each-ref --format=\"%(refname:short) %(objectname)\" 'refs/heads/' | sed -En 's/^(\\S+)\\s+'\"$(git rev-parse \"$1\" 2>/dev/null)\"'$/\\1/p' | grep . || { echo \"$1: not a branch\" >&2; false;}
例如:
$ git branch-head-name da8ecd90
master
边缘案例:
注意:不带.gitconfig
字符串引号的别名是:
branch-name=!git for-each-ref --format="%(refname:short) %(objectname)" 'refs/heads/' | sed -En 's/^(\S+)\s+'"$(git rev-parse "$1" 2>/dev/null)"'$/\1/p' | grep . || { echo "$1: not a branch" >&2; false;}
答案 5 :(得分:0)
我认为解决方案之一,可能不是很优雅,但非常可靠:列出所有分支branch --contains $sha
,然后检查git rev-parse $branch
== $sha
。
答案 6 :(得分:0)
grep:
怎么样?grep -R [sha] .git/refs/heads/
或者,因为您是从python脚本调用它,为什么不创建一个搜索这些文件的函数,并根据需要返回分支名称或异常。
答案 7 :(得分:0)
尝试这样的方法来测试每个分支提示哈希对你给定的$ sha:
git branch -a| cut -d " " -f 2,3 | xargs -n 1 git rev-parse | grep $sha
或只是本地
git branch | xargs -n 1 git rev-parse | grep $sha