确定提交之间的关系

zeb*_*h49 8 git bash

在线性历史中,两个提交A和B可以具有三种状态之一:

  • A和B是相同的提交
  • 严格在B之前
  • B严格在A之前

Git的非线性历史允许四个附加选项

  • A和B共享父母和孩子
  • A和B共享父母而不是孩子
  • A和B分享孩子而不是父母
  • A和B没什么共享

我不确定如何在不使用嫁接点的情况下实现最后两个,但它可能会发生.

我不确定如何完成的是以一种简单的方式确定这种关系 - 目前我只能想到一个有点奇怪的rev-list解决方案,其中一个人单独测试每个案例:

[[ "$a" = "$b" ]] && echo "same"
git rev-list "$b" | grep -q "$a" && echo "a before b"
git rev-list "$a" | grep -q "$b" && echo "b before a"
cat <(git rev-list "$a") <(git rev-list "$b") | sort | uniq -cd | grep -q 2 && echo "A and B share parents"
cat <(git rev-list --children "$a") <(git rev-list --children "$b") | sort | uniq -cd | grep -q 2 && echo "A and B share children"
Run Code Online (Sandbox Code Playgroud)

这样做必须有更好,更好的方式,那又是什么呢?

kir*_*gin 7

检查父子关系很容易,使用git merge-base.如果结果是您的某个提交,则它是父级,另一个是子级.

我建议忽略当提交没有共同祖先时的情况.当然,这可能发生,但我不知道任何有效的用例.我的意思是,你正在为一个真实的项目解决一个真正的问题,我相信你可以认为这不会发生.BTW,merge-base将以错误退出,这是合并库不存在的唯一情况,因此您仍然可以检测到这种情况.

寻找孩子的承诺是不可能的.Absoultely.你不能可靠地做到这一点.提交具有"父"引用,但它没有"子"引用.rev-list --children做一件完全不同的事情,它与你想要的东西无关.你必须改进你的问题.

我可以建议使用git branch --contains <commit>或者git tag --contains <commit>只列出那些可以从中提交的分支/标签.

或者,您可以查看git for-each-ref它将允许您测试是否可以从任何分支/标记访问提交.