git:找到`the`中不存在的最早的`mine`提交

buk*_*zor 3 git branch git-branch

我希望能够在我的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
Run Code Online (Sandbox Code Playgroud)

我想要一个命令,它会指向H(或B),给定HEADmaster.请注意,一个简单的git merge-base master HEAD给我F.

use*_*342 6

这应该合理地工作:

git rev-list --topo-order --reverse mine ^master | head -1
Run Code Online (Sandbox Code Playgroud)

使用您的设置的副本进行测试,它会打印您标记为"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手册中进行了说明.