2017-01-09 20 views
3

给定两个git提交,我怎么能确定,理想与管道命令,它们之间的历史是线性的?如何确定git历史是否线性?

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

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

,而不是这样的:

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

回答

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 
+0

[prahla文卡塔(HTTP:/ /stackoverflow.com/a/41546204/86072)给出了一个更好的变体。 '--min-parents'实际上是'git rev-list'命令的一个标志,'git rev-list'有一个内置的'--count'标志(用于统计所选提交的数量)。 – LeGEC

+0

注意'--min-parents'和'--count'处理与'git log'共享,但'--count'对'git log'没有意义(所以它只是被忽略)。 – torek

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
git rev-list --min-parents=2 --count A..G 

会给出具有多个父提交的数量。 计数'0'表示线性历史记录。

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留下所有的BCDEFG,都CF是合并的提交。

如果你想测试限制为“是的A后代和祖先的G,包括G但不包括A本身提交”,添加--ancestry-path的检查合并:

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

这将算在你的榜样非线性嵌入的循环,但算上我的第二个片段的线性(在上图提交CF都不是A后裔,例如)。我的第一个案例在这里不会被认为是线性的,因为选择了G并且是合并提交,所以对于这种特殊情况,您将不得不使用A..G^@作为您的范围。 (这是从早期轻微的修正:我们要所有父母G,不只是第一个,我们将依靠--ancestry-path挑右一个(或多个)。)