我希望能够在我的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.
答案 0 :(得分:6)
这应该合理地运作:
git rev-list --topo-order --reverse mine ^master | head -1
使用您的设置副本进行测试,它会打印您标记为“H”的提交。我并非100%确信它在所有可能的情况下都找到了“最远”的路径,或者这样的概念甚至是定义明确的,所以你可能希望在依赖它之前对你重要的案例进行测试。
(请注意,通常指定限制-1
输出的git rev-list
选项与--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
manual中。
答案 1 :(得分:1)
这大致相当于问题»哪些提交可以从(我的)HEAD到达,但不能从主设备到达?«要回答这个问题,请使用提交范围master..HEAD
。您需要此列表中最早的提交,因此通过尾部管道输出:git rev-list master..HEAD|tail -n1
。
如果您的提交时间戳不是按时间顺序排序的,则可能必须指定转发列表的--topo-order
选项。