给定提交哈希,获取指向该提交的所有分支名称的最佳方法是什么?
选项1:蛮力。使用git for-each-ref refs/heads
获取所有分支,过滤提交,并提取分支名称。
选项2:使用git name-rev --name-only
。但是,这仅提供一个分支(如果多个分支指向同一个提交)。
最终我真正想要的是两个提交之间的分支名称的拓扑排序列表(其中具有多个分支的提交将具有多个条目)。似乎git可能会做我想做的事情,而我却找不到合适的命令。
编辑:请注意,我不询问哪些分支包含给定的提交。我想知道哪些分支作为他们的头。
答案 0 :(得分:2)
如果您的Git足够新,git for-each-ref --points-at
可以满足您的需求(适用于refs/heads
命名空间并添加您喜欢的任何格式。)
--points-at
选项是Git 2.7.0中的新选项。在旧版本中,您仍应使用git for-each-ref
,但您需要过滤到那些哈希ID为所需内容的人。
值得注意的是,为了您的最终目标:git log --decorate
将添加引用装饰以提交ID,因此您可以使用git log --decorate --format='%H %d'
。添加--topo-order
和--ancestry-path start..end
以获取包含end
但排除start
且包含start
和的后代的拓扑排序提交end
的祖先。如果您不想要""后代,请忽略--ancestry-path
。部分。 (如果要包含开始提交,请考虑--boundary
但要注意,--boundary
有时会选择太多提交。)
答案 1 :(得分:1)
大多数情况下,执行此操作的方法似乎效率低下,因为它不是由所涉及的数据结构“轻松”实现的操作。您基本上必须迭代所有引用,特别是如果您希望 all 指向提交的分支。简化此操作的命令通过为您提供表达所需内容的语法来实现,但仍然必须遍历引用。好消息是,这听起来比现在更糟糕。
请注意,您的第二种方法还有另一个缺陷:即使没有分支指向它,它也会尝试为提交提供某些名称。因此,master~1
例如是该命令的有效输出。在提交无法访问的情况下,它也可以返回undefined
,但我认为这不是一个可能的用例。
听起来你只希望将直接指向的分支到提交(而不是每个可以到达提交的分支),这有助于消除遍历每个ref历史的潜在需求。
所以,无论如何......是的,你的第一种方法是可行的,有几种可能的改进。
--points-at
选项将为您处理过滤(除非您使用旧版本的git)。
--format
选项可以帮助提取分支名称(尽管据我所知,它并不能让你获得100%的方式,因为你可能想要删除refs/heads/
前缀)。
所以它可能会像
一样聚集在一起git for-each-ref --points-at $sha1 --format='%(refname)` refs/heads | cut -c12-