【问题标题】:What Does `--contains` Option Do in `git for-each-ref`?`--contains` 选项在`git for-each-ref` 中有什么作用?
【发布时间】:2021-08-02 04:13:31
【问题描述】:

--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。在 v2.28.1 中同时使用 --merged--no-merged 是不兼容的,但现在在 v2.31.1 中是兼容的。因此,Git 文档并没有过时。

似乎this commit 是在 2017 年 3 月 21 日制作的,远远早于 v2.31.1(不确定它到底是哪个版本)。

其次,@LeGEC 的回答似乎是有道理的(vis-a-vis --contains/--no-contains 的意思是“给我有这个提交的参考 在他们之后”和--merged/ --no-merged 的意思是“给我有这个提交的参考文献在他们之前”。

不过,如果能进一步澄清 Git 文档,那就太好了。像他们所做的那样使用定义中的词是非常模糊的。

因为 Git 是有向无环图 (DAG),所以提交指向一个方向的链表方式中的其他提交:时间倒退到它们的祖先。因此,--merged/--no-merged 的名称及其对“可达性”的描述是有意义的。

“包含”是指“在并且可到达之后”(即子级),还是简单地“在”(即在较晚的时间提交)?

由于这是一个管道命令(用于自定义脚本),我需要确切地知道它的作用和工作原理,这样我的脚本就不会产生任何意外的副作用。

【问题讨论】:

  • 你检查documentation了吗? "--contains[=] 仅列出包含指定提交的引用(如果未指定,则为 HEAD)。"
  • 你不是在混用其他命令吗?或者您能否提供一个指向您的信息来源的链接?与git for-each-ref--merged--no-merged 是兼容选项;添加了--contains-no-contains,因为它们增加了描述新事物的可能性。
  • @LeGEC 请查看此提交:github.com/git/git/commit/…。从 v2.31.1 开始,将 --merged--no-merged 一起使用变得不兼容。 git-scm.com 上的文档实际上已经过时(请参阅 git-scm.com/docs/git-for-each-ref)。如果您尝试按照页面底部注释中提到的方式同时运行两者,则不再有效。
  • @LasseV.Karlsen 是的,但是“包含”是什么意思?这个术语是模棱两可的,因为 ref 是一个 SHA(它是一个指向 SHA 的名称)。 “包含”的想法表明将有多个提交与单个 ref 相关联,这仅在其 git rev-list 的上下文中才有意义。否则,一个 ref 要么是 SHA,要么不是 SHA(它不包含或指向多个 SHA)。
  • @LeGEC 不,你错了。我已经明白了。您是说--contains 仅在引用的 parents 之一是--contains 之后列出的那个时才返回引用?这与它是任何 ref 的 祖先 不同。提交也确实“包含”了它的所有祖先,而不仅仅是它的父母。如果--contains 仅表示“裁判的父母”,文档需要澄清这一点。

标签: git options git-plumbing


【解决方案1】:

也许我误解了您的问题,如果相关,请更新您的问题。


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

[update] 一个 ref 指向一个 commit,一个 commit 有指向它的 parents 的指针。有了这种关系,git 中的提交形成了一个图(实际上是一个 DAG)。

“merged in”(或我不正确的“comes before”)表示“是”的祖先,“contains”(或我不正确的“comes after”)表示“是”的后代。

你提到git rev-list:如果git rev-list commitB列出了commitA的sha,那么你可以说:

  • commitB 包含 commitA
  • commitA 合并到 commitB

【讨论】:

  • 其实请看这个commit:github.com/git/git/commit/...。从 v2.31.1 开始,将 --merged--no-merged 一起使用是不兼容的(我已经测试过,它不再适用于我)。因此, git-scm.com 上的文档实际上已经过时(参见 git-scm.com/docs/git-for-each-ref)。如果您尝试按照页面底部注释中提到的方式同时运行两者,则不再有效。
  • 文档没有这样解释(即“来之后”或“来之前”)。他们重用这个词本身(即它“包含”或“不包含”提交)。这个术语是模棱两可的,因为 ref 是一个 SHA(它是一个指向 SHA 的名称)。 “包含”的想法表明有多个提交与单个 ref 相关联,这仅在其 git rev-list 的上下文中才有意义。一个提交可以在另一个提交之后或之前,但如果无法从该提交访问(未合并到其分支中),则它不会出现在 revlist 中,也不会被它“包含”。
  • 请查看我更新的问题。如果这可以为​​您澄清问题,请支持我的问题。
  • 对于“是祖先”测试,Git 只是尝试从声称的后代中找到声称的祖先。 (警告:最近,Git 增加了创建额外提交图缓存数据的能力,以帮助加快速度;新代码更加精美。)请注意,“相同提交”被认为是祖先。对于“提交 Y 是否是提交 X 的后代”,Git 只是简单地反转测试并尝试“提交 X 是否是 Y 的祖先”。因此,日期戳是无关紧要的,以任何图形优化代码中的任何错误为模。
  • (在过去一年左右的时间里,Git 邮件列表上有很多补丁包含对花哨代码的修复,其中修复计算“更正的提交日期”,其中提交日期早于他们的祖先提交在辅助数据中得到更正提交日期,因为使用实际日期值非常诱人。给定正确的更正提交日期,这些应该可以工作。问题是这些是 32 位字段,但日期/时间戳是 64 位!)
猜你喜欢
  • 2011-01-02
  • 2019-10-31
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多