Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git hooks strip ANSI sequences #4308

Open
1 task done
clemyan opened this issue Feb 22, 2023 · 2 comments
Open
1 task done

Git hooks strip ANSI sequences #4308

clemyan opened this issue Feb 22, 2023 · 2 comments

Comments

@clemyan
Copy link

clemyan commented Feb 22, 2023

  • I was not able to find an open or closed issue matching what I'm seeing

Setup

  • Which version of Git for Windows are you using? Is it 32-bit or 64-bit?
# Tested with both released version on winget, and portable version of latest snapshot
$ git --version --build-options

git version 2.39.2.windows.1
cpu: x86_64
built from commit: a82fa99b36ddfd643e61ed45e52abe314687df67
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon

$ git --version --build-options

git version 2.39.1.windows.1.536.g49a8ec9dac.20230214182258
cpu: x86_64
built from commit: 49a8ec9dac3cec6602f05fed1b3f80a549c8c05c
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
  • Which version of Windows are you running? Windows 10 Home 22H2 Build 19045.2604 (64-bit)
$ cmd.exe /c ver

Microsoft Windows [Version 10.0.19045.2604]
  • What options did you set as part of the installation? Or did you choose the
    defaults?
# One of the following:
> type "C:\Program Files\Git\etc\install-options.txt"
> type "C:\Program Files (x86)\Git\etc\install-options.txt"
> type "%USERPROFILE%\AppData\Local\Programs\Git\etc\install-options.txt"
> type "$env:USERPROFILE\AppData\Local\Programs\Git\etc\install-options.txt"
$ cat /etc/install-options.txt

Editor Option: VIM
Custom Editor Path:
Default Branch Option:
Path Option: Cmd
SSH Option: OpenSSH
Tortoise Option: false
CURL Option: OpenSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Git Pull Behavior Option: Merge
Use Credential Manager: Enabled
Performance Tweaks FSCache: Enabled
Enable Symlinks: Disabled
Enable Pseudo Console Support: Disabled
Enable FSMonitor: Disabled

Details

  • Which terminal/shell are you running Git from? e.g Bash/CMD/PowerShell/other

Issue exists when using CMD (10.0.19045.2604) and PowerShell (7.3.2), but does not exist when using git-bash.

$ git init
$ nano .git/hooks/pre-commit # Create pre-commit hook
$ git commit --allow-empty

.git/hooks/pre-commit

#!/bin/sh
printf 'ANSI NOT \x1B[4DWORKING PROPERLY\n'
exit 1
  • What did you expect to occur after running these commands?

Prints ANSI WORKING PROPERLY

  • What actually happened instead?

Prints ANSI NOT WORKING PROPERLY

image


Investigation

ANSI sequences are not stripped if stdout is redirected to /dev/tty or if output is redirected to stderr

#!/bin/sh
exec > /dev/tty
printf 'ANSI NOT \x1B[4DWORKING PROPERLY\n'
exit 1
# ANSI WORKING PROPERLY
#!/bin/sh
printf 'ANSI NOT \x1B[4DWORKING PROPERLY\n' 1>&2
exit 1
# ANSI WORKING PROPERLY

So probably related to #2914?

@dscho
Copy link
Member

dscho commented Feb 22, 2023

FWIW I can reproduce it: the pre-commit hook strips the ANSI sequence. And I can confirm that git -c alias.x="!.git/hooks/pre-commit" x does handle the ANSI sequence.

So probably related to #2914?

Most likely. Here's hoping for a happier ending in this here ticket.

Maybe this comment is still relevant. If a pre-commit.exe hook is installed that is actually an MSYS program (compiled using /usr/bin/gcc.exe in Git for Windows' SDK, not /mingw64/bin/gcc.exe), we should be able to determine the values of isatty(2) and isatty(1) according to the MSYS2 runtime (which is what is implicitly done in that Bash script because the Bash is also an MSYS program). (And the NtQueryObject() trick mentioned in this ticket might be useful here, too.)

To be honest, I am not quite certain that we can fix this issue easily because the dup2() call is done in git.exe, which is not an MSYS program, and hence it may be impossible to propagate the "TTY-ness" of the file descriptor in git.exe...

But before deciding to give up too rashly, I would like to understand in more depth what is going on here (and more importantly what is not going on here but is expected to go on by the MSYS2 runtime).

@clemyan
Copy link
Author

clemyan commented Feb 22, 2023

I'm kinda out of my depth here. I have not done any C programming with Windows stuff (or serious C programming at all) so I have not yet fully understood how C library calls and MSYS2 and the Windows APIs interact. But I think this is what you want to test?

pre-commit.c

#include <unistd.h>
#include <stdio.h>

int main() {
        printf("isatty(0) = %d\n", isatty(0));
        printf("isatty(1) = %d\n", isatty(1));
        printf("isatty(2) = %d\n", isatty(2));
        printf("ANSI NOT \x1B[4DWORKING PROPERLY\n");
        return 1;
}

In Git for Windows' SDK:

Clement MINGW64 ~/Documents/git-test
$ ll
total 1
-rw-r--r-- 1 Clement 197121 233 Feb 22 23:26 pre-commit.c

Clement MINGW64 ~/Documents/git-test
$ /usr/bin/gcc pre-commit.c -o pre-commit.exe

Clement MINGW64 ~/Documents/git-test
$ ll
total 65
-rw-r--r-- 1 Clement 197121   233 Feb 22 23:26 pre-commit.c
-rwxr-xr-x 1 Clement 197121 63440 Feb 22 23:27 pre-commit.exe*

Clement MINGW64 ~/Documents/git-test
$ ./pre-commit.exe
isatty(0) = 1
isatty(1) = 1
isatty(2) = 1
ANSI WORKING PROPERLY

Then copy the pre-commit.exe into .git/hooks/pre-commit.exe


Results

PowerShell 7.3.2

PS> git commit --allow-empty      
isatty(0) = 0
isatty(1) = 0
isatty(2) = 1
ANSI NOT WORKING PROPERLY

CMD

CMD> git commit --allow-empty
isatty(0) = 0
isatty(1) = 0
isatty(2) = 1
ANSI NOT WORKING PROPERLY

Git-bash

GIT-BASH$ git commit --allow-empty
isatty(0) = 0
isatty(1) = 1
isatty(2) = 1
ANSI WORKING PROPERLY

To be honest I don't even know how to interpret these results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants