[英]How do I find if a git SHA points to a branch HEAD?
To avoid unnecessarily detached HEADs when checking out a certain git SHA with a (python) script, I'd like to check out a branch instead, if that SHA happens to be the current HEAD of a branch. 为了避免在使用(python)脚本检出某个git SHA时不必要的分离HEAD,我想检查一个分支,如果该SHA恰好是分支的当前HEAD。
Ideally, I want to feed git an SHA, and it returns a branch name if the SHA is on a branch's current tip, or error out if not. 理想情况下,我想给git一个SHA,如果SHA在分支的当前提示上,则返回分支名称,否则返回错误。
git describe --all --exact-match <SHA>
very nearly is what I need, only that it is primarily aimed at tags, and so if a branch and a tag point at my SHA (which often happens in our release branches, for example), only the tag is given. git describe --all --exact-match <SHA>
非常接近我所需要的,只是它主要针对标签,所以如果分支和标签指向我的SHA(通常发生在我们的发布分支中,例如),只给出标签。 This is not useful, because checking out the tag leads to a detached HEAD (even if a branch points at the same SHA). 这没用,因为签出标签会导致分离的HEAD(即使分支指向同一个SHA)。
Note, I don't want to do git branch --contains
- I don't need to know which branches contain my commit. 注意,我不想做
git branch --contains
- 我不需要知道哪些分支包含我的提交。
If there's no command like git describe
, just for branches, I know I can cross-check my SHA against branch SHAs via git show-ref
. 如果没有像
git describe
这样的命令,只是对于分支,我知道我可以通过git show-ref
交叉检查我的SHA对分支SHA。 That's not the most elegant solution, though. 不过,这不是最优雅的解决方案。
I could also do git name-rev --name-only <hash>
, but I'd have to manually check the output for ~
characters, which feels unelegant if there's a git command somewhere to do the same thing. 我也可以做
git name-rev --name-only <hash>
,但是我必须手动检查~
字符的输出,如果有一个git命令在某处做同样的事情,感觉很不雅。
You could try something like this: 你可以尝试这样的事情:
git for-each-ref --format="%(refname:short) %(objectname)" 'refs/heads/' |
grep SHA1 | cut -d " " -f 1
That should give you a list of branches that are currently at the revision SHA1
. 这应该为您提供当前位于修订版
SHA1
的分支列表。
If you are going to use python, this is what I would do: 如果你打算使用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
Another option is to use the power of eval to construct a dictionary: 另一个选择是使用eval的力量来构造字典:
d = '{' + subprocess.check_output(['git', 'for-each-ref', '--python', '--format=%(objectname): %(refname),', 'refs/heads/']) + '}'
name = eval(d)[sha1]
With the upcoming git 2.7 (Q4 2015) you will get a more complete version of git for-each-ref
, which now support the --points-at
随着即将推出的git 2.7(2015年第4季度),您将获得更完整版的
git for-each-ref
,现在支持--points-at
git for-each-ref --points-at <branch_name>
With the doc: 随着文档:
--points-at <object>:
Only list refs which points at the given object.
仅列出指向给定对象的引用。
That will allow to check if a commit is part of that list or not. 这将允许检查提交是否是该列表的一部分。
See commit 4a71109 , commit ee2bd06 , commit f266c91 , commit 9d306b5 , commit 7c32834 , commit 35257aa , commit 5afcb90 , ..., commit b2172fd (07 Jul 2015), and commit af83baf (09 Jul 2015) by Karthik Nayak ( KarthikNayak
) . 请参阅提交4a71109 , 提交ee2bd06 , 提交f266c91 , 提交9d306b5 , 提交7c32834 , 提交35257aa , 提交5afcb90 ,..., 提交b2172fd (2015年7月7日),并提交af83baf (2015年7月9日)作者: Karthik Nayak(
KarthikNayak
) 。
(Merged by Junio C Hamano -- gitster
-- in commit 9958dd8 , 05 Oct 2015) (由Junio C
gitster
合并- gitster
- in commit 9958dd8 ,2015年10月5日)
Some features from "
git tag -l
" and "git branch -l
" have been made available to "git for-each-ref
" so that eventually the unified implementation can be shared across all three, in a follow-up series or two.来自“
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
For my case, I wanted to know if HEAD pointed to a branch post-checkout and then exit 0 if pointing to a branch, or exit non-zero if not pointing to a branch, which is most likely detached HEAD state assuming the checkout succeeded. 对于我的情况,我想知道HEAD是否指向分支后检查 ,然后如果指向分支则退出0,或者如果不指向分支则退出非零,这很可能是分离的HEAD状态,假设结账成功。
git symbolic-ref --short HEAD
does this and also returns the name of the branch when pointing to one. git symbolic-ref --short HEAD
执行此操作,并在指向一个分支时返回分支的名称。 Obviously, there's better solutions for what the OP needs, but I wanted to throw this in just in case anyone wanted to make use of the information. 显然,有更好的解决方案可以满足OP的需求,但我想把它放在以防任何人想要利用这些信息的情况下。
To get the branch names referenced by a commit or tag, I came up with this .gitconfig
: 为了获得提交或标记引用的分支名称,我想出了这个
.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;}
Eg: 例如:
$ git branch-head-name da8ecd90
master
Edge cases: 边缘情况:
Note: the alias without .gitconfig
string quoting is: 注意:没有
.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;}
我认为解决方案之一,也许不是很优雅,但相当可靠:是列出所有分支branch --contains $sha
然后检查git rev-parse $branch
== $sha
。
What about grep : 怎么样grep:
grep -R [sha] .git/refs/heads/
Or since you are calling it from a python script, why not just create a function that searches through those files, and returns the branch name or exception as you wanted. 或者,因为您是从python脚本调用它,为什么不创建一个搜索这些文件的函数,并根据需要返回分支名称或异常。
try something like this to test each branch tip hash against your given $sha: 尝试这样的东西来测试你给定的$ sha的每个分支提示哈希:
git branch -a| cut -d " " -f 2,3 | xargs -n 1 git rev-parse | grep $sha
or just local 或者只是当地的
git branch | xargs -n 1 git rev-parse | grep $sha
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.