git-查找从中创建分支的提交
即使分支已经合并,也能找到创建分支的提交(理想情况下仅是提交哈希)吗 例如:git-查找从中创建分支的提交,git,branch,Git,Branch,即使分支已经合并,也能找到创建分支的提交(理想情况下仅是提交哈希)吗 例如: master A-B-C-D-E \ / feature F-G 功能分支已合并到主中,但它仍然存在,可以签出到。我想发现,功能分支从A开始(免责声明:主题外答案-不处理已合并的分支) 如果feature和master尚未合并,您只需获取它们的“合并基础”(): 它将输出提交的长格式散列。分支实际上没有父分支。(相关:)您可以很容易地找到 A < /COD>的散列,但请考虑此图:
master A-B-C-D-E
\ /
feature F-G
功能
分支已合并到主
中,但它仍然存在,可以签出到。我想发现,功能
分支从A
开始(免责声明:主题外答案-不处理已合并的分支)
如果
feature
和master
尚未合并,您只需获取它们的“合并基础”():
它将输出提交
的长格式散列。分支实际上没有父分支。(相关:)您可以很容易地找到<代码> A < /COD>的散列,但请考虑此图:
H--I--L--N--O--R---T--U <-- master
\ \ \ /
J--K--M--P--Q--S <-- feature
我们可以从提交E
(主机提示)开始,然后返回提交D
(合并)。我们知道,当它的一个父项是功能
的提示时,我们已经点击了D
,即,是commitG
。然后,我们从commitD
获取两个父哈希ID:
git rev-parse <hash-of-D>^@
它生成所有合并提交哈希ID的列表,这些ID可通过遍历master
的第一个父后代访问。(您可能想要也可能不想要——第一个父级
;如果您一直在大量使用git pull
,那么master
的第一个父级链接可能会受到某种程度的损坏。)也就是说,这给了我们在这里的两个图中提交哈希T
和D
(可能更多)。如果省略了--第一个父级
,请考虑其他分支已合并到主级
,并从有问题的功能
分支提交的情况,然后决定是否需要--拓扑顺序
接下来,遍历这些提交,获取其父哈希:
looking_for=$(git rev-parse feature) # this is the hash ID we're looking for
found=false
for hash in (output of above git rev-list); do
set -- $(git rev-parse ${hash}^@)
case $# in
2) # two parents, good
if [ $2 == $looking_for ]; then found=true; break; fi;;
*) # more than two parents, we might go wrong
echo "commit $hash has $# parents, help"; exit 1;;
esac
done
if ! $found; then
echo "unable to find the commit hash you were looking for"
exit 1
fi
此时,由于set
解析参数的方式,您在$1
和$2
中有了所需的提交对,因此:
# found the desired commit pair, so now just invoke git merge-base
set -- $(git merge-base --all $1 $2)
case $# in
1) echo "the commit you are looking for is $1"; exit 0;;
*) echo "I found $# candidate commits $@"; exit 1;;
esac
当分支尚未合并时,此操作有效。但是对于已经合并的分支,它显示了分支中最后一次提交的哈希(G
hash)。你说得对,这不是针对合并的分支,我必须进一步搜索,因为你想要的确实更难获得。同时,我也进行了编辑,以避免误导人们。
git rev-list --merges --first-parent master
looking_for=$(git rev-parse feature) # this is the hash ID we're looking for
found=false
for hash in (output of above git rev-list); do
set -- $(git rev-parse ${hash}^@)
case $# in
2) # two parents, good
if [ $2 == $looking_for ]; then found=true; break; fi;;
*) # more than two parents, we might go wrong
echo "commit $hash has $# parents, help"; exit 1;;
esac
done
if ! $found; then
echo "unable to find the commit hash you were looking for"
exit 1
fi
# found the desired commit pair, so now just invoke git merge-base
set -- $(git merge-base --all $1 $2)
case $# in
1) echo "the commit you are looking for is $1"; exit 0;;
*) echo "I found $# candidate commits $@"; exit 1;;
esac