在使用 git 的时候大部分时候都是通过 git rev-parse <branch-name> 来获取某个分支名对应的 commit id 但是一直没遇到通过 commit id 来获取分支名的场景。在学习 git rebase 命令的时候突然想知道有没有这个命令。于是就开始问 chatgpt 了。
最开始,我问 chatgpt :
git rev-pase <branch-name>这个命令可以根据分支名获取对应的commit id,有没有相反的命令:根据commit id获取对应的分支名?
chatgpt 跟我说:
可以通过
git branch --contains <commit-id>这个命令来实现。
很明显这个命令不是我想要的,我需要是精确匹配,也就是 branch-name 通过 git rev-parse 解析后,刚好等于我指定的 commit-id 。于是我纠正 chatgpt ,让它给我提供一个可以精确匹配的方案。
于是 chatgpt 又给出了一个解决方案:
git show-ref | grep <commit-id>
这个方案确实可以满足我的需求,但是我总觉得不是最优解。于是我继问:
你上面的命是可以实现的。但有没有更高效的命令,像
git rev-parse一样直接获取。而不是需要我自己去grep
接着 chatgpt 又给出一个解决方案:
git name-rev --name-only <commit-id>如果这个 commit id 正好对应某个分支的最新 commit,这个命令会返回对应的分支名。
然而,
git name-rev会尝试找到最接近的引用(分支或标签)来命名 commit,因此如果 commit 不正好是某个分支的 HEAD,返回的结果可能会是一个基于最接近引用的名称(例如master~2表示 master 分支倒数第二个 commit)。 如果你需要更加精确地确定某个 commit id 是否正好对应于某个分支的 HEAD,可以使用以下命令:git for-each-ref --format='%(refname)' refs/heads/ | while read ref; do if [ "$(git rev-parse $ref)" = "<commit-id>" ]; then echo $ref fi done
很明显,这个方案越来越复杂了,还不如最开始的 git show-ref | grep <commit-id> 简洁。然后我又追问 chatgpt :
脚本太复杂了,就没有更简洁的命令吗?
最后 chatgpt 终于给出了我满意的答案:
确实可以简化查询是否有分支的 HEAD 完全匹配指定的 commit ID。以下是一个更简洁的命令:
git branch --points-at <commit-id>这个命令会列出所有分支,它们的 HEAD 完全匹配指定的 commit ID。
假设你的 commit ID 是
abc123,你可以运行以下命令:git branch --points-at abc123这将列出所有 HEAD 指向
abc123的分支。这样,你就可以直接找到那些分支的 HEAD 完全匹配特定的 commit ID,而不需要编写复杂的脚本。
最后,我查了一下,git branch --points-at 替换成 git tag --points-at 就可以处理 tag 相关的查询了。
