请注意,使用 Git 2.12(2017 年第一季度,6 年多之后),git 寻呼机会话中的 Ctrl+C 应该表现得更好。
参见Jeff King (peff) 的commit 46df690、commit 246f0ed、commit 2b296c9(2017 年 1 月 7 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 5918bdc,2017 年 1 月 18 日)
execv_dashed_external: 等待孩子信号死亡
键入^C 到pager,这通常不会杀死它,杀死Git 并将寻呼机作为某些进程树结构中的附带损害。
此问题已修复。
您可以使用git -p stash list 之类的命令运行任何虚线外部,命令运行完毕,但寻呼机仍在运行。
简短的版本是一切都应该正常停止(Git和寻呼机)
但详细一点:
当git 运行pager 时,git 进程必须
闲逛并等待pager 完成,即使它
没有更多数据可以提供给它。
这是因为git 将pager 作为子进程生成,因此git 进程是终端上的会话负责人。在它死后,pager 将完成从终端的当前读取(吃掉那个
字符),然后让EIO 尝试再次读取。
注意:EIO(错误 5)代表错误 I/O,并且是(source):
捕捉各种意外硬件错误。它可能来自物理错误,但另外,尝试从标准输入读取的孤立进程(其父进程已死亡)将得到此错误。如果您尝试打开已在使用的 pty 设备,BSD 系统会返回此信息。
尝试从已关闭的流中读取将返回 EIO,磁盘读取或写入超出设备的物理范围。
当进程没有控制 tty 时打开/dev/tty 也会吐回EIO。
所以(在pager 中返回^C):
当您点击^C 时,会将SIGINT 发送到git 和pager,
这是一个类似的情况。
pager 会忽略它,但 git 进程需要等待直到寻呼机完成。我们很久以前在a3da882 (pager: do
wait_for_pager on signal death, 2009-01-22) 中解决了这个问题。
但是当你有一个破折号的外部(或一个指向内置的别名,它将为内置的重新执行 git)时,混合中有一个额外的过程。
例如,运行:
$ git -c alias.l=log l
最终会得到如下进程树:
git (parent)
\
git-log (child)
\
less (pager)
如果您点击^C,SIGINT 会发送给所有用户。寻呼机忽略它,子 git 进程将在 wait_for_pager() 中结束。
但是父 git 进程会死掉,通常的 EIO 麻烦就会发生。
在 Git 2.28(2020 年第三季度)中,当一个别名命令(其输出通过 git 管道传输到寻呼机)被信号杀死时,寻呼机进入一个有趣的状态,该状态已被(再次)纠正。
参见Trygve Aaberge (trygveaa) 的commit c0d73a5、commit e662df7(2020 年 7 月 7 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 05920f0,2020 年 7 月 15 日)
Ctrl+C:等待孩子信号死亡,以获得内置函数的别名
签字人:Trygve Aaberge
当您点击 ^C 时,树中的所有进程都会收到它。
当git 命令使用寻呼机时,git 会忽略这一点并等待寻呼机退出。
但是,当使用别名时,树中有一个不会忽略信号的附加进程。这导致它退出,进而导致寻呼机退出。这修复了内置函数的别名。
这最初在46df6906(execv_dashed_external:等待子信号死亡,2017-01-06)中修复,但被ee4512ed(“trace2:创建新的组合跟踪设施”, 2019-02-22,Git v2.22.0-rc0 -- merge 列在 batch #2) 然后 b9140840 ("git: 避免通过虚线形式调用别名内置函数",2019-07-29, Git v2.23.0-rc1 -- merge)。
还有:
当我们运行外部命令的别名时,我们希望等待该进程退出,即使在收到通常会杀死 git 进程的 ^C 之后也是如此。当进程忽略 SIGINT(例如,寻呼机经常这样做)时,这很有用,然后我们不希望它被杀死。
拥有调用寻呼机的别名可能并不常见,但它可能很有用,例如如果您有一个 git 命令的别名,该命令使用子 shell 作为参数之一(在这种情况下,您必须使用外部命令,而不是内置命令的别名)。
此补丁与之前的提交类似,但之前的提交仅针对内置命令的别名修复了此问题,而此提交对外部命令的别名进行了相同的修复。除了像之前的提交一样在 clean 之后等待之外,这还可以清理子节点(在之前的提交之前已经为内置函数的别名启用),因为 wait_after_clean 依赖于它。最后,虽然之前的提交修复了回归问题,但我认为这一直无法正常工作。
请注意,如果您使用 trace2 来调试情况,则寻呼机现在已正确跟踪。
当用户生成的寻呼机退出时,跟踪日志没有正确记录其退出状态,这已在 Git 2.31(2021 年第一季度)中得到纠正。
参见Ævar Arnfjörð Bjarmason (avar)commit be8fc53、commit 85db79a、commit c24b7f6、commit 61ff12f(2021 年 2 月 2 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit dcb11fc,2021 年 2 月 22 日)
pager:发出信号时正确记录寻呼机退出代码
签字人:Ævar Arnfjörð Bjarmason
当 git 调用一个以非零值退出的寻呼机时,常见的情况是它本身已经返回了正确的 SIGPIPE 失败,但是在 trace2 中记录的退出代码总是被错误地报告1支持>.
修复该问题并在日志中记录正确的退出代码。
由于这为我们提供了在我们最近添加的需要 !MINGW 先决条件的测试之外进行测试的东西,让我们重构测试以在 MINGW 上运行并实际检查 SIGPIPE 之外的 MINGW。
wait_or_whine() 仅使用来自 finish_command_in_signal() 的真正 "in_signal" 调用,而 finish_command_in_signal() 又仅在 pager.c 中使用。
“in_signal && !WIFEXITED(status)”的情况不在测试范围内。
在这种情况下,让我们记录默认值 -1 以作为衡量标准。
- 退出代码的错误记录似乎被复制/粘贴到ee4512e中的
finish_command_in_signal()(“trace2:创建新的组合跟踪设施”,2019-02-22,Git v2.22.0-rc0 - - merge 在batch #2 中列出)