给定两个git提交,我怎么能确定,理想与管道命令,它们之间的历史是线性的?如何确定git历史是否线性?
换句话说,我想知道我是否有这样的:
A-B-C-D-E-F-G
,而不是这样的:
/-C-\
A-B -E-F-G
\-D-/
给定两个git提交,我怎么能确定,理想与管道命令,它们之间的历史是线性的?如何确定git历史是否线性?
换句话说,我想知道我是否有这样的:
A-B-C-D-E-F-G
,而不是这样的:
/-C-\
A-B -E-F-G
\-D-/
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
如果您乐意在比瓷器更高的级别上妥协,您可以使用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())
git rev-list --min-parents=2 --count A..G
会给出具有多个父提交的数量。 计数'0'表示线性历史记录。
“之间”是图表中的滑动概念。
如果你有类似你的例子,LeGEC's answer是好的(虽然我会稍微简化为git rev-list --count --min-parents=2 A..G
并检查非零结果)。
但是假设图形片段看起来是这样的:
A--B--C
\
G
/
D--E--F
是A..G
被认为是线性?这里A
是一个根提交,但它并不重要,我们也可以使用B..G
或C..G
。这里的问题是还有另一个根提交,D
,可从G
到达,但不是A
的后代。提交集合中的提交“可从G
到达,不包括可从A
到达的提交”的提交集合是G
本身。或者:
A--B--C--G
/
D--F
/
E
这里有三根承诺,A
,D
和E
。该组的承诺,从G
可达零下设定到达从A
留下所有的B
,C
,D
,E
,F
和G
,都C
和F
是合并的提交。
如果你想测试限制为“是的A
后代和祖先的G
,包括G
但不包括A
本身提交”,添加--ancestry-path
的检查合并:
git rev-list --count --min-parents=2 --ancestry-path A..G
这将算在你的榜样非线性嵌入的循环,但算上我的第二个片段的线性(在上图提交C
和F
都不是A
后裔,例如)。我的第一个案例在这里不会被认为是线性的,因为选择了G
并且是合并提交,所以对于这种特殊情况,您将不得不使用A..G^@
作为您的范围。 (这是从早期轻微的修正:我们要所有父母G
,不只是第一个,我们将依靠--ancestry-path
挑右一个(或多个)。)
[prahla文卡塔(HTTP:/ /stackoverflow.com/a/41546204/86072)给出了一个更好的变体。 '--min-parents'实际上是'git rev-list'命令的一个标志,'git rev-list'有一个内置的'--count'标志(用于统计所选提交的数量)。 – LeGEC
注意'--min-parents'和'--count'处理与'git log'共享,但'--count'对'git log'没有意义(所以它只是被忽略)。 – torek