如何在Git中获取分支头列表?

zujrkrfu  于 2023-03-06  发布在  Git
关注(0)|答案(2)|浏览(173)

我试图在Git中得到一个分支头列表。到目前为止,我发现git log --simplify-by-decoration似乎包含了所有分支并显示了头,但它也显示了一个额外的提交,这对我来说是无用的。有没有更好的方法来做这件事,或者这是我应该使用的?
所以说清楚点:我希望有一个输出,它能给出我本地仓库中所有分支的头,基本上,我只需要每个头的哈希值,但是我可以从我得到的任何输出中正则化它。

mefy6pfw

mefy6pfw1#

您应该能够使用git show-ref命令。git-show-ref documentation

git show-ref --heads -s
00jrzges

00jrzges2#

如果你在一个大型仓库上使用git show-ref --heads -s,一个有分支或标签以外的引用的仓库(比如gerrit repository),请确保使用Git 2.37(Q3 2022)。
"git show-ref --heads"(man)(和"--tags")仍然在 * 所有 * 引用上迭代,只是为了丢弃指定区域之外的引用,Git 2.37(Q3 2022)对此进行了修正。
参见Taylor Blau ( ttaylorr )commit c0c9d35(2022年6月3日)。
(由Junio C Hamano -- gitster --合并到commit 2246937,2022年6月13日)

builtin/show-ref.c:避免使用--heads--tags进行过度迭代

签署人:泰勒·布劳
show-ref--heads--tags选项结合使用时,它可以避免迭代它不关心的存储库引用部分。
但是它没有利用这种潜在的优化。
当这个命令被重新引入358ddb6(添加,2006年9月15日,Git v1.4.4-rc1--merge)(添加"git show-ref"(man)内置命令,2006年9月15日)时,for_each_ref_in()确实存在。
但是,由于大多数存储库没有太多(任何?)不是分支或标记的引用,这在实践中几乎没有什么区别。
尽管对于分支和标签(或者,更可能是服务器操作员,许多隐藏引用)的存储库来说,这会造成很大的不同。
例如,一个仓库有500,000个"隐藏"引用(所有引用的形式都是"refs/__hidden__/N"),只有一个分支:

git commit --allow-empty -m "base" &&
seq 1 500000 | sed 's,\(.*\),create refs/__hidden__/\1 HEAD,' |
  git update-ref --stdin &&
git pack-refs --all

在我的机器上,输出单个分支的存在性目前需要大约50ms。
这些时间的绝大部分都浪费在迭代那些我们知道要丢弃的引用上。
相反,教导show-ref,当分别给定--heads和/或--tags时,它只能迭代"refs/heads"和/或"refs/tags"。
一些有趣的小事情要注意:

  • 无论给出哪种选择,我们都可以完全避免通用的for_each_ref()调用,因为我们知道它不会给我们任何我们已经过滤掉的引用。
  • 我们可以对for_each_fullref_in()进行两次单独的调用(并且避免,比方说,更专门化的for_each_fullref_in_prefixes(),因为我们知道每一次调用所枚举的引用集是不相交的,所以我们永远不会在两次调用中看到相同的引用。
  • 我们必须使用"fullref"变体(而不仅仅是for_each_branch_ref()for_each_tag_ref()),因为我们希望在show-ref的输出中出现完全限定的引用名称。

heads_onlytags_only被置位时,我们可以完全消除builtin/show-ref.c::show_ref()中的strcmp()调用,因为我们知道show_ref()永远不会看到非分支或标记引用。
不幸的是,我们不能使用for_each_fullref_in_prefixes()来增强show-ref的模式匹配,因为show-ref模式在 * 后缀 * 上匹配(例如,模式"foo"显示"refs/heads/foo"、"refs/tags/foo"等,而不是"foo/*")。
尽管如此,在我们上面的合成示例中,这提供了显著的加速("git"大约是v2.36,"git.compile"是这个补丁):

$ hyperfine -N 'git show-ref --heads' 'git.compile show-ref --heads'
Benchmark 1: git show-ref --heads
  Time (mean ± σ):      49.9 ms ±   6.2 ms    [User: 45.6 ms, System: 4.1 ms]
  Range (min … max):    46.1 ms …  73.6 ms    43 runs

Benchmark 2: git.compile show-ref --heads
  Time (mean ± σ):       2.8 ms ±   0.4 ms    [User: 1.4 ms, System: 1.2 ms]
  Range (min … max):     1.3 ms …   5.6 ms    957 runs

Summary
  'git.compile show-ref --heads' ran
   18.03 ± 3.38 times faster than 'git show-ref --heads'

相关问题