38

我在 Windows 7 / XP 上遇到了一个奇怪的 Git Bash 问题。它曾经工作得很好,但最近我发现在我执行git diffor之后git log,Git Bash 变得无法使用:在 diff/log 之后,即使在我返回命令提示符后,Bash 仍然突然并且显然自发地重复相同的命令,没有提示并且当我正在输入后续命令时。

有没有其他人有这个问题?任何建议都将不胜感激,因为目前这确实限制了 Git Bash 的用处。

4

2 回答 2

56

你必须使用q退出 git 的寻呼机。使用 Ctrl-C 只会在 Windows 上引起问题。

Ctrl-C 不应该退出寻呼机(它不会在 linux 系统上)。当您在 Windows 上按 Ctrl-C 时(我想是 msysgit?),您以某种方式“从外部”杀死进程(即来自 cmd.exe)。我不知道发生这种情况的确切原因。

正如我过去遇到过类似的问题:尝试以q随机顺序反复按和 Ctrl-C,如果幸运的话,你会再次得到工作提示;)[我知道没有更好的解决方案——但它为我工作……]

于 2011-10-01T18:43:32.760 回答
2

请注意,使用 Git 2.12(2017 年第一季度,6 年后),git 寻呼机会话中的Ctrl+C应该表现得更好。

请参阅Jeff King ( )的commit 46df690commit 246f0edcommit 2b296c9(2017 年 1 月 7 日) 。(由Junio C Hamano 合并——提交 5918bdc中,2017 年 1 月 18 日)peff
gitster

execv_dashed_external:等待信号死亡的孩子

键入^Cto pager,这通常不会杀死它,杀死 Git 并将寻呼机作为某些进程树结构中的附带损害。
这已得到修复。

您可以使用类似命令运行任何虚线外部,git -p stash list命令完成运行,但寻呼机仍在运行。

简短的版本是一切都应该正常停止(Git和寻呼机)

但详细地说:

git运行 apager时,重要的是 git 进程要等待pager它完成,即使它没有更多数据可以提供给它。
这是因为作为一个孩子git产生pager,因此该git进程是终端上的会话领导者。在它死后,pager它将完成从终端的当前读取(吃掉一个字符),然后EIO再次尝试读取。

注意:(EIO错误 5)代表错误 I/O,并且是(来源):

包罗万象的各种意外硬件错误。它可能来自物理错误,但另外,尝试从标准输入读取的孤立进程(其父进程已死亡)将得到此错误。如果您尝试打开已在使用的 pty 设备,BSD 系统会返回此信息。
尝试从已关闭的流中读取将返回 EIO,磁盘读取或写入超出设备的物理边界也会返回。当进程没有控制 tty 时的
打开也会吐回来。/dev/ttyEIO

所以(回到^Ca pager):

当您点击^C时,会发送SIGINTgit和 ,pager情况类似。忽略它,但该
过程需要等待直到寻呼机完成。我们很久以前在a3da882 中解决了这个问题(寻呼机:在信号死亡时执行 wait_for_pager,2009-01-22)pagergit

但是当你有一个破折号的外部(或一个指向内置的别名,它将为内置的重新执行 git)时,混合中有一个额外的过程。
例如,运行:

$ git -c alias.l=log l

最终会得到一个进程树,如:

  git (parent)
    \
     git-log (child)
      \
       less (pager)

如果你打^CSIGINT去他们所有人。寻呼机忽略它,子 git 进程将在 wait_for_pager() 中结束。
但是父 git 进程会死掉,并且会发生通常的 EIO 麻烦。


在 Git 2.28(2020 年第三季度)中,当一个别名命令(其输出通过 git 管道传输到寻呼机)被信号杀死时,寻呼机进入了一个有趣的状态,该状态已被纠正(再次)。

请参阅Trygve Aaberge ( ) 的提交 c0d73a5提交 e662df7(2020 年 7 月 7 日(由Junio C Hamano 合并 -- --提交 05920f0中,2020 年 7 月 15 日)trygveaa
gitster

Ctrl+C:等待孩子信号死亡以获取内置函数的别名

签字人:Trygve Aaberge

当您点击 ^C 时,树中的所有进程都会收到它。
git命令使用寻呼机时,git 会忽略这一点并等待寻呼机退出。

但是,当使用别名时,树中还有一个不会忽略信号的附加进程。这导致它退出,进而导致寻呼机退出。这修复了内置函数的别名。

这最初在46df6906中修复(execv_dashed_external:等待子信号死亡,2017-01-06),但被ee4512ed(“ trace2:创建新的组合跟踪设施”,2019-02-22,Git v2.22.0-rc0 - -合并在批次 #2中列出),然后是 b9140840(“ git:避免通过虚线形式调用别名内置函数”,2019-07-29,Git v2.23.0-rc1 --合并)。

和:

当我们运行外​​部命令的别名时,我们希望等待该进程退出,即使在收到通常会杀死 git 进程的 ^C 之后也是如此。当进程忽略 SIGINT(例如寻呼机经常这样做)时,这很有用,然后我们不希望它被杀死。

拥有调用寻呼机的别名可能并不常见,但它可能很有用,例如,如果您有一个使用子 shell 作为参数之一的 git 命令的别名(在这种情况下,您必须使用外部命令,而不是内置的别名)。

此补丁与之前的提交类似,但之前的提交仅针对内置命令的别名修复了此问题,而此提交对外部命令的别名进行了相同的修复。除了像之前的提交一样在 clean 之后等待之外,这还可以清理子节点(在之前的提交之前已经为内置函数的别名启用),因为wait_after_clean依赖于它。最后,虽然之前的提交修复了回归,但我认为这一直没有正常工作。


请注意,如果您使用trace2来调试情况,那么现在可以正确跟踪寻呼机。

当用户生成的寻呼机退出时,跟踪日志没有正确记录其退出状态,这已在 Git 2.31(2021 年第一季度)中得到纠正。

请参阅Ævar Arnfjörð Bjarmason ( ) 的提交 be8fc53提交 85db79a提交 c24b7f6提交 61ff12f(2021 年 2 月 2 日(由Junio C Hamano 合并 -- --dcb11fc 提交中,2021 年 2 月 22 日)avar
gitster

pager:发出信号时正确记录寻呼机退出代码

签字人:Ævar Arnfjörð Bjarmason

当 git 调用一个以非零退出的寻呼机时,常见的情况是SIGPIPE它本身已经返回了正确的失败,但是在 trace2 中记录的退出代码总是被错误地报告为1
修复该问题并在日志中记录正确的退出代码。

由于这为我们提供了在最近添加的需要先决条件的测试之外进行测试的东西,!MINGW让我们重构测试以在其上运行MINGW并实际检查.SIGPIPEMINGW

仅使用来自 fromwait_or_whine()的 true 调用,而from又仅在中使用。"in_signal"finish_command_in_signal()pager.c

" in_signal && !WIFEXITED(status)" 的情况不包括在测试中。
在这种情况下,让我们记录默认值 -1 以获得良好的衡量标准。

  1. 退出代码的错误记录似乎被复制/粘贴到finish_command_in_signal()ee4512e 中trace2:创建新的组合跟踪设施”,2019-02-22,Git v2.22.0-rc0 --批次 #2中列出的合并
于 2017-01-22T12:45:35.903 回答