1

Assume I have a git alias like this:

[alias]
    abortalias = "! f() { \
        read -p '> Press ctrl+c to cancel'; \
        echo '> This should never be seen'; \
    }; \
    f"

And run git abortalias, then press ctrl+c when prompted. I'm expecting the script to cancel, instead what happens is that I pop out to the terminal, and my next input will trigger this error:

$ environment: line 0: read: read error: 0: Input/output error
> This should never be seen

This is also reproducible by adding a sleep 5 instead of the read -p command and exiting during the sleep. The script will still resume.

Edit: Upon further testing, this only seems to happen inside a MINGW64 shell. Running from Powershell or CMD works just fine. Has to be some Windows quirk then I guess.

Edit 2: Specifically, it's git bash (MINGW64), ran through Visual Studio Code that's causing this issue. Running it in git bash (MINGW64) alone works, and running it in VSCode with another terminal works.

I've opened an issue in the VSCode repo meanwhile: https://github.com/microsoft/vscode/issues/149155

Sid
  • 1,709
  • 1
  • 10
  • 17
  • 1
    I cannot reproduce your observation when I invoke `git abortalias` from a CMD. The command does not continue. – j6t May 10 '22 at 09:03

1 Answers1

1

Ctrl-C on Windows is a fake. It kills only the process that is started from the command line, but does not propagate through to child processes. Hence, the shell and other child processes that are spawned by git abortalias keep doing their thing without being interrupted.

Your best bet is to write defensive shell scripts:

[alias]
    abortalias = "! f() { \
        read -p '> Press ctrl+c to cancel' && \
        echo '> This should never be seen'; \
    }; \
    f"

Note the && after the read command.

j6t
  • 9,150
  • 1
  • 15
  • 35
  • I can cancel a normal bash script containing that code just fine though, it's only git that's causing problems. Your suggestion to use `&&` stopped the second line from being printed, but I still get an error next time I type into the terminal. What's "defensive shell scripts"? – Sid May 10 '22 at 09:31
  • Upon further testing, this only seems to be happening inside a MINGW64 shell, everywhere else I run it it acts like it should. – Sid May 10 '22 at 09:39
  • `git.exe` is not a MinGW64 program. MinGW64 programs, such as bash, do their own emulation of POSIXy behavior. `git.exe` does not cooperate with them. That may be the reason for the behavior difference depending on which kind of program invokes which other kind. – j6t May 10 '22 at 10:27
  • 2
    "Defensive shell scripts" do all the necessary error checking. Chaining commands with `&&` is one method to ensure that a script stops at the first error. – j6t May 10 '22 at 10:29