我希望能够在我的 git-graph 中找到上游不存在的最长路径。这条路的一端显然是HEAD,所以这很容易。另一端是我最早的提交,上游不存在。我不知道如何找到这个。
图
[otherguy] H--I--J
/
[master] A--B--C--M1--D--E--M2--F--G
[mine] H---I--M3---J---K---M4--M--HEAD
我想要一个命令,它将我指向 H(或 B),给定HEAD
和master
.请注意,一个简单的git merge-base master HEAD
给了我 F。
这应该合理地工作:
git rev-list --topo-order --reverse mine ^master | head -1
使用设置的副本进行测试后,它会打印您标记为"H"的提交。我不是 100% 相信它会在所有可能的情况下找到"最远"的路径,或者这样的概念甚至是明确定义的,所以你可能想在依赖它之前在对你很重要的情况下对其进行测试。
(请注意,通常指定用于限制输出git rev-list
-1
选项不能很好地与--reverse
结合,因此需要head -1
。
更新:
一些解释:
git rev-list mine ^master
请求可从mine
访问的提交,但不能从master
访问。在您的情况下,我们请求所有以HEAD
开头的提交,不包括可从G
访问的提交,这给出了提交(M, M4, K, J, M3, I, H)
的列表,我们选择最后一个。需要
--topo-order
来确保提交的拓扑顺序(提交始终出现在其父提交之前),而不是默认的时间顺序。我们还指定--reverse
,因为我们需要最后一个。commit1 ^commit2
也可以拼写为commit2..commit1
,这是commit1
是commit2
的后代时的首选语法。在这种情况下,mine
和master
已经分道扬镳,所以更清楚地说明我们想要什么。还允许多个排除项,例如git log branch1 ^branch2 ^branch3
。这适用于所有采用范围的 git 命令,并记录在git rev-parse
手册中。
这主要等同于问题»哪些提交可以从(我的)HEAD访问,但不能从master访问?要回答这个问题,请使用提交范围master..HEAD
。你想要这个列表中最早的提交,所以通过 tail:git rev-list master..HEAD|tail -n1
管道输出。
如果提交时间戳未按时间顺序排序,则可能需要指定 rev-list 的--topo-order
选项。