我认为您可能在此处误用“分离的 HEAD”一词来指代悬空提交(我的答案基于该假设)。
首先,我们需要一个存储库中所有提交的列表,包括当前无法从任何分支、标签或其他引用访问的“悬空”提交。在某些时候,git cat-file 开发了使这变得非常容易的选项:
git cat-file --batch-check --batch-all-objects
如果您的git 版本没有这些选项,则有other ways to get a list of all objects。
以上将产生如下输出:
2bd7a7d258cb8c0f529e267e72c37bfee2be3a92 tree 32
2d83b892c0922c9168d3c474e73da24301bc86bf tree 64
3eda82acd62f56b19d88a80650ed88428be8ac9b commit 231
42dae79fef2ede926a081821e6a7cf89387cd9f0 tree 66
5e9fac93b855f5cf5ed44969cf9cc53121195377 blob 29
b01735609620636d7b0179a940f7409a32041f87 commit 182
我们只对提交感兴趣,所以我们会通过 awk 过滤它:
$ git cat-file --batch-check --batch-all-objects | awk '$2 == "commit" {print $1}'
3eda82acd62f56b19d88a80650ed88428be8ac9b
b01735609620636d7b0179a940f7409a32041f87
现在,对于每次提交,我们需要先提取顶层树 id:
git show --quiet --format='%T' <commit id>
然后递归列出该树中包含的所有树:
git ls-tree -r -t <tree id>
综合起来,我们得到:
#!/bin/sh
git cat-file --batch-check --batch-all-objects |
awk '$2 == "commit" {print $1}' |
while read cid; do
tree=$(git show --quiet --format='%T' $cid)
echo $cid $tree
git ls-tree -r -t $tree |
awk -v cid=$cid '$2 == "tree" {print cid,$3}'
done
这将为发现的每个树对象输出一行格式:
<commit id> <tree id>
所以您的问题的答案是将上述脚本的输出通过管道传输到grep <tree id>(或修改脚本以仅输出您想要的特定信息)。