让我们假设你在git中有以下结构
A <-- refs/heads/somebranch
|
B
| \
C D <-- refs/tags/TAG1
| |
E F
| | \
G H I <-- refs/heads/branch1
|
J <-- refs/heads/master
现在我想查找历史记录中包含提交B
的所有引用。
所以如果我能做到这样会很好
$ git refs --contains B
refs/tags/TAG1
refs/heads/branch1
refs/heads/master
我看了一下git decumentation,发现git branch -a --contains <commit_id>
列出了包含commit_id
的所有分支。
$ git branch -a --contains 4af9822
master
remotes/origin/someBranch
...
我找到了命令git tag --contains 9338f2d
$ git tag --contains 9338f2d
someTag
anotherTag
...
当然我可以这样做,
$ git branch -a --contains 4af9822 && git tag --contains 9338f2d
但是有一个命令可以一次打印所有引用吗?
答案 0 :(得分:8)
要添加到torek的答案,git 2.7(2015年第4季度)将提供更完整版本的git for-each-ref
,现在支持--contains
git for-each-ref --contains <SHA1>
请参阅commit 4a71109,commit ee2bd06,commit f266c91,commit 9d306b5,commit 7c32834,commit 35257aa,commit 5afcb90,{{3} },commit d325406,commit 6841104,commit b2172fd,...,commit b2172fd(2015年7月7日)和commit b2172fd(2015年7月9日){{3 }}。
(commit af83baf合并于Karthik Nayak (KarthikNayak
),2015年10月5日)
来自&#34;
git tag -l
&#34;的一些功能和&#34;git branch -l
&#34;已经成了 可用于&#34;git for-each-ref
&#34;这样最终统一了 在后续工作中,可以在所有三个方面共享实施 一两个系列。
* 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
请注意,启动Git 2.13(2017年第2季度),最终支持git for-each-ref --no-contains <SHA1>
!
请参阅Junio C Hamano -- gitster
--,commit 9958dd8,commit 7505769,commit 783b829,commit ac3f5a3,commit 1e0c3b6,commit 6a33814,{{3} (2017年3月24日),commit c485b24,commit eab98ee,commit bf74804,commit 7ac04f1(2017年3月23日)和commit 682b29f,commit 4612edc,{ {3}},commit b643827(2017年3月21日)commit 17d6c74
(commit 8881d35合并于commit b084060,2017年4月11日)
答案 1 :(得分:5)
[编辑,2015年10月:现在有了VonC's new answer},但没有内置任何内容,但使用git branch -a --contains
和git tag --contains
应该可以帮助您您通常会发现“有趣”的参考文献。
有一种(非内置的)方法可以找到所有这些引用。每当你询问“所有引用”时,你应该看git for-each-ref
。它允许您迭代所有引用或所有引用的一部分:
$ git for-each-ref
996b0fdbb4ff63bfd880b3901f054139c95611cf commit refs/heads/master
740c281d21ef5b27f6f1b942a4f2fc20f51e8c7e commit refs/remotes/origin/maint
996b0fdbb4ff63bfd880b3901f054139c95611cf commit refs/remotes/origin/master
7327a17171fc87d5f8f5c790eb1ba1d0e031482d commit refs/remotes/origin/next
[... snip]
efe35e936c6c32a7630086a84b2c3b3471ea534f tag refs/tags/v2.0.1
b4463ead04f1801104502ea087dbb6bdd21b4ef1 tag refs/tags/v2.0.2
3c81e95201ece182e799709c91b15a3501919d26 tag refs/tags/v2.0.3
(在这种情况下,我在git本身的存储库上运行git for-each-refs
,没有其他参数,因此它产生默认输出。)
您现在要做的就是在原始参考上运行--contains
检测器。虽然没有将此作为动词的管道命令,--contains
很容易在git merge-base
中使用--is-ancestor
表示为测试。正如git branch
documentation notes,--contains
只是测试上面显示的refs/heads/
或refs/remotes/
引用左侧的分支 - 尖端 - SHA-1是否是后代的指定的提交。 “是一个后代”实际上与“是它的祖先”的测试相同,参数被交换:
$ git branch --contains 996b0fd^
* master
$ git rev-parse 996b0fd^
6da748a7cebe3911448fabf9426f81c9df9ec54f
由于master
为996b0fd...
,--contains
与996b0fd
及其第一个父6da748a...
匹配,因此我们可以判断我们是否有{{1}正确的参数:
git merge-base --is-ancestor
请注意$ git merge-base --is-ancestor 6da748a 996b0fd && echo ok
ok
被认为是其自身的祖先:
996b0fd
所以你需要做的就是将$ git merge-base --is-ancestor 996b0fd 996b0fd && echo ok
ok
和一个运行git for-each-ref
的shell命令或循环串在一起。