确定提交之间的关系

时间:2013-06-13 16:37:27

标签: git bash

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

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

Git的非线性历史允许另外四个选项

  • A和B共享父母和孩子
  • A和B共享父母但不是孩子
  • A和B分享一个孩子而不是父母
  • A和B分享任何内容

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

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

[[ "$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"

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

1 个答案:

答案 0 :(得分:7)

检查父子关系很简单,请使用git merge-base。如果结果是你的一个提交,那么它是父母,另一个是孩子。

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

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

我建议的是使用git branch --contains <commit>git tag --contains <commit>,它只会列出您可以从中提交的分支/标记。

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