我如何确定git历史是否是线性的?

时间:2017-01-09 10:03:17

标签: git

鉴于两个git提交,我如何确定(最好是使用管道命令)它们之间的历史是否是线性的?

换句话说,我想知道我是否有这个:

A-B-C-D-E-F-G

而不是:

   /-C-\
A-B     -E-F-G
   \-D-/

4 个答案:

答案 0 :(得分:3)

git log --min-parents=2只显示至少有2个父母的提交(例如:合并提交)

你可以运行:

# for esthetics : --oneline will output one single line per filtered commit
git log --oneline --min-parents=2 A..G

# if output is empty : linear history

# and :
git log --oneline --min-parents=2 A..G | wc -l

# should give you the number of merge commits between A and G

答案 1 :(得分:3)

git rev-list --min-parents=2 --count A..G

将提供具有多个父级的提交数。 计数“0”表示线性历史记录。

答案 2 :(得分:0)

如果您愿意在比瓷器更高级别的事情上妥协,可以使用gitpython,寻找与一个或多个父母的提交。

import git


def is_linear(commit):
    ncommits = len(commit.parents)
    if ncommits == 0:
        return True
    elif ncommits == 1:
        return is_linear(commit.parents[0])
    else:
        return False

repo = git.Repo('.')
print is_linear(repo.commit())

答案 3 :(得分:0)

“之间”是图表中的一个滑动概念。

如果你有类似你的例子,LeGEC's answer很好(虽然我会稍微简化一点git rev-list --count --min-parents=2 A..G并检查非零结果。)

但假设图片段看起来像这样:

A--B--C
       \
        G
       /
D--E--F

A..G是否被视为线性?这里A是根提交,但它并不重要,我们也可以使用B..GC..G。这里的问题是还有另一个根提交D,可以从G访问,但不是A的后代。作为“G可到达的提交集合中的合并提交的提交,不包括从A可到达的提交”,它本身就是G。或者:

A--B--C--G
     /
 D--F
   /
  E

此处有三个根提交,ADE。可以从G减去可从A到达的设置的提交集离开了BCDE,{{ 1}}和F以及GC都是合并提交。

如果您希望将测试约束为“F的后代和A的祖先,包括G但不包括G本身”的提交,请添加{{ 1}}检查合并:

A

这会将您示例中的嵌入循环计为非线性,但将第二个片段计为线性(提交--ancestry-pathgit rev-list --count --min-parents=2 --ancestry-path A..G 不是最后一个图中C的后代,实例)。我的第一个案例在此处不会被视为线性,因为选择了提交F并且是合并提交,因此对于这种特殊情况,您必须使用A作为范围。 (这是前面的一个小小修正:我们想要 G的所有父母,而不仅仅是第一个;我们将依靠A..G^@选择正确的一个({1}} 。)