我在 Windows 7 / XP 上遇到了一个奇怪的 Git Bash 问题。它曾经工作得很好,但最近我发现在我执行git diff
or之后git log
,Git Bash 变得无法使用:在 diff/log 之后,即使在我返回命令提示符后,Bash 仍然突然并且显然自发地重复相同的命令,没有提示并且当我正在输入后续命令时。
有没有其他人有这个问题?任何建议都将不胜感激,因为目前这确实限制了 Git Bash 的用处。
你必须使用q
退出 git 的寻呼机。使用 Ctrl-C 只会在 Windows 上引起问题。
Ctrl-C 不应该退出寻呼机(它不会在 linux 系统上)。当您在 Windows 上按 Ctrl-C 时(我想是 msysgit?),您以某种方式“从外部”杀死进程(即来自 cmd.exe)。我不知道发生这种情况的确切原因。
正如我过去遇到过类似的问题:尝试以q
随机顺序反复按和 Ctrl-C,如果幸运的话,你会再次得到工作提示;)[我知道没有更好的解决方案——但它为我工作……]
请注意,使用 Git 2.12(2017 年第一季度,6 年后),git 寻呼机会话中的Ctrl+C应该表现得更好。
请参阅Jeff King ( )的commit 46df690、commit 246f0ed、commit 2b296c9(2017 年 1 月 7 日) 。(由Junio C Hamano 合并——在提交 5918bdc中,2017 年 1 月 18 日)peff
gitster
execv_dashed_external
:等待信号死亡的孩子
键入
^C
topager
,这通常不会杀死它,杀死 Git 并将寻呼机作为某些进程树结构中的附带损害。
这已得到修复。
您可以使用类似命令运行任何虚线外部,git -p stash list
命令完成运行,但寻呼机仍在运行。
简短的版本是一切都应该正常停止(Git和寻呼机)
但详细地说:
当
git
运行 apager
时,重要的是 git 进程要等待pager
它完成,即使它没有更多数据可以提供给它。
这是因为作为一个孩子git
产生pager
,因此该git
进程是终端上的会话领导者。在它死后,pager
它将完成从终端的当前读取(吃掉一个字符),然后EIO
再次尝试读取。
注意:(EIO
错误 5)代表错误 I/O,并且是(来源):
包罗万象的各种意外硬件错误。它可能来自物理错误,但另外,尝试从标准输入读取的孤立进程(其父进程已死亡)将得到此错误。如果您尝试打开已在使用的 pty 设备,BSD 系统会返回此信息。
尝试从已关闭的流中读取将返回 EIO,磁盘读取或写入超出设备的物理边界也会返回。当进程没有控制 tty 时的
打开也会吐回来。/dev/tty
EIO
所以(回到^C
a pager
):
当您点击
^C
时,会发送SIGINT
到git
和 ,pager
情况类似。忽略它,但该
过程需要等待直到寻呼机完成。我们很久以前在a3da882 中解决了这个问题(寻呼机:在信号死亡时执行 wait_for_pager,2009-01-22)。pager
git
但是当你有一个破折号的外部(或一个指向内置的别名,它将为内置的重新执行 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 ( ) 的提交 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
并实际检查.SIGPIPE
MINGW
仅使用来自 from
wait_or_whine()
的 true 调用,而from又仅在中使用。"in_signal"
finish_command_in_signal()
pager.c
"
in_signal && !WIFEXITED(status)
" 的情况不包括在测试中。
在这种情况下,让我们记录默认值 -1 以获得良好的衡量标准。