问题描述
--contains
中的 git for-each-ref
选项有什么作用?
如果它的 revlist 在命令行上的 --contains
选项之后指定了提交,它是否只返回一个引用? (例如,git for-each-ref refs/heads --contains feature/test
是否只返回那些在其 revlist 中包含提交 feature/test
的头?(即它们与第一次提交之间的提交列表,即 git rev-list <ref>
))?
Git 文档(v. 2.31.1;参见 here)实际上已经过时:底部的 Notes
部分指出您可以使用 --merged
和 --no-merged
选项一起使用,但这与 this commit 不兼容。
文档中提供的定义是模棱两可的:它重复使用了“包含”这个词,但没有阐明其含义。引用是仅指向一个 SHA 的名称。 “包含”的概念表明引用指的是多次提交,这仅在其 git rev-list
的上下文中才有意义。
一个提交可以在另一个提交之后或之前(简单地通过提交时间),但是如果它不能从那个提交访问(即如果提交没有合并到它的分支中),那么提交不知道它,所以不能说它“包含”它。
这就是为什么 --merged
和 --no-merged
在一起是有意义的:它会返回可从(至少一个)--merged
到达的提交,而没有 --no-merged
。>
“包含”是什么意思?...“有直系父母 X”? “有祖先X”? “有表哥X”?
更新:
看来我使用的是旧版本的 Git。同时使用 --merged
和 --no-merged
在 v2.28.1 中不兼容,但现在在 v2.31.1 中兼容。因此,Git 文档并没有过时。
this commit 似乎也是在 2017 年 3 月 21 日制作的,远早于 v2.31.1(不确定它到底是用哪个版本提交的)。
其次,@LeGEC 的回答似乎是有道理的(相对于 --contains
/--no-contains
的意思是“给我在他们之后提交此提交的引用”和--merged
/--no-merged
表示“给我在提交之前的引用”。
不过,如果可以进一步澄清 Git 文档,那就太好了。像他们那样在定义中使用这个词是非常含糊的。
因为 Git 是一个有向无环图 (DAG),提交以链表方式指向一个方向的其他提交:在时间上向后指向它们的祖先。因此,名称 --merged
/--no-merged
及其在“可达性”方面的描述是有道理的。
“contains”是指“after andreachable”(即子项),还是简单的“after”(即,稍后提交)?
由于这是一个管道命令(在自定义脚本中使用),我需要确切地知道它的作用以及它是如何工作的,以便我的脚本不会有任何意外的副作用。
解决方法
也许我误解了您的问题,如果相关,请更新您的问题。
documentation 给出了这些选项的正确(但可能是简洁的?)描述,
这是一种不同的表达方式:
-
--merged develop
表示“在develop
之前” -
--no-merged master
表示“不在master
之前” -
--contains feature1
表示“在feature1
之后” -
--no-contains feature2
表示“不在feature2
之后”
这 4 个选项实际上是兼容的:
git for-each-ref --merged develop --no-merged master --contains feature1 --no-contains feature2
将列出以下引用:
- 已合并到
develop
,但尚未合并到master
, - 包含
feature1
(例如:feature1
以某种方式合并到它们中),并且还不包含feature2
[更新] 一个引用指向一个提交,一个提交有指向它的父项的指针。有了这个关系,以 git 形式提交一个图(实际上是一个 DAG)。
“合并在”(或我不正确的“在前”)表示“是……的祖先”,“包含”(或我不正确的“在后”)表示“是……的后代”。
你提到git rev-list
:如果git rev-list commitB
列出了commitA
的sha,那么你可以说:
-
commitB
包含commitA
-
commitA
合并到commitB