为啥“git submodule add ...”写入stderr而不是stdout?

Posted

技术标签:

【中文标题】为啥“git submodule add ...”写入stderr而不是stdout?【英文标题】:Why does "git submodule add ..." write to stderr rather than stdout?为什么“git submodule add ...”写入stderr而不是stdout? 【发布时间】:2016-09-30 09:12:12 【问题描述】:

消息

Cloning into 'sub-mod'...
done.

在将git submodule add... 命令写入stderr 之后。我希望将消息写入 stdout,因为我不认为它表明命令出现问题。

我可以使用以下命令序列重现这一点:

rm   -rf /tmp/repo /tmp/module
mkdir    /tmp/repo /tmp/module

cd /tmp/module

git init  > /dev/null
echo "foo" > foo;
git add foo > /dev/null
git commit . -m "+ foo" > /dev/null


cd /tmp/repo

git init > /dev/null
git submodule add /tmp/module/ sub-mod 1> /dev/null

如果我将最后一个命令中的重定向更改为... 2> /dev/null,则不会打印任何内容。

【问题讨论】:

【参考方案1】:

这不仅限于子模块,如noted here:

子模块的注册会报告给stderr,因为是 与 Git 中的其他进度报告一致

这有助于我们在以后的补丁中重用 init_submodule function in update_clone 其标准输出将通过管道传输 到 shell,它以一种非常具体的方式从标准输出中读取参数。

你也可以在this recent patch看到它:

将 stdout 的输出重新路由到 stderr,因为它只是提供信息 消息,不被机器消费

我们想从submodule update 的助手中初始化子模块 在以后的补丁中,所述助手的标准输出输出被消耗 submodule update 的部分仍然写在 shell 中。

所以我们必须小心哪些消息在标准输出上。


在 Git 2.35(2022 年第一季度)中,编码指南文档已更新,以阐明我们系统中的标准错误。

参见Eric Sunshine (sunshineco) 的commit e258eb4(2021 年 12 月 2 日)。(由 Junio C Hamano -- gitster -- 合并到 commit 212962d,2021 年 12 月 15 日)

CodingGuidelines: 记录哪个输出到 stdout 与 stderr

签字人:Eric Sunshine签字人:Jeff King

这个项目长期以来一直在实践一个命令将其主要输出发送到标准输出,以便可以将其捕获到文件或通过管道发送,并发出“聊天”消息(例如那些报告进度的消息)到 stderr,这样它们就不会干扰主输出。 但是,这种做法不一定是普遍的;另一种常见的做法是仅将错误消息发送到 stderr,而将所有其他消息发送到 stdout。 因此,通过记录如何在此项目中使用 stdout 和 stderr 来帮助新手。

CodingGuidelines 现在包含在其man page 中:

程序输出

我们区分 Git 命令的主要输出和 输出只是闲聊的反馈(例如,状态 消息、运行脚本或进度显示),以及错误 消息。粗略地说,一个 Git 命令的主要输出是 哪个可能想要捕获到文件或发送到管道;它的 聊天输出不应干扰这些用例。

因此,主输出应发送到标准输出流 (stdout),并且聊天输出应该被发送到标准错误 流(标准错误)。产生主要输出的命令示例 包括git loggit showgit branch --list,它们会生成 在标准输出流上输出。

并非所有 Git 命令都有主输出;这通常是真实的 主要功能是执行动作的命令。一些动作 命令是无声的,而其他命令是健谈的。一个例子 健谈的动作命令是git clone,其“克隆到 ''..." 和 "Checking connectivity..." 状态消息,它 发送到 stderr 流。

来自 Git 命令的错误消息应始终发送到 stderr 流。

【讨论】:

惊讶于他们没有考虑为机器可读输出添加标志... @aleclarson 机器可读输出是 Git 中的默认输出,并转到标准输出。其他任何事情都转到 stderr。 也许吧,但我更喜欢 git status 及其 --porcelain 标志的方法,而不是滥用标准错误。但也许这只是我。 @aleclarson 我明白了。我在***.com/a/6978402/6309 中提出--porcelain 选项。 也许一个特殊字符来识别不应该被机器读取的输出会比滥用 stderr 更好。

以上是关于为啥“git submodule add ...”写入stderr而不是stdout?的主要内容,如果未能解决你的问题,请参考以下文章

git submodule add子模块的添加,--recurse-submodules递归克隆子项目

git submodule add子模块的添加,--recurse-submodules递归克隆子项目

git submodule add子模块的添加,--recurse-submodules递归克隆子项目

你应该同步运行方法吗?为啥或者为啥不?

为啥使用 glTranslatef?为啥不直接更改渲染坐标?

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?