Skip to content

Commit

Permalink
compat/terminal.c: only use the Windows console if bash 'read -r' fails
Browse files Browse the repository at this point in the history
Accessing the Windows console through the special CONIN$ / CONOUT$ devices
doesn't work properly for non-ASCII usernames an passwords.

It also doesn't work for terminal emulators that hide the native console
window (such as mintty), and 'TERM=xterm*' is not necessarily a reliable
indicator for such terminals.

The new shell_prompt() function, on the other hand, works fine for both
MSys1 and MSys2, in native console windows as well as mintty, and properly
supports Unicode. It just needs bash on the path (for 'read -s', which is
bash-specific).

On Windows, try to use the shell to read from the terminal. If that fails
with ENOENT (i.e. bash was not found), use CONIN/OUT as fallback.

Note: To test this, create a UTF-8 credential file with non-ASCII chars,
e.g. in git-bash: 'echo url=http://täst.com > cred.txt'. Then in git-cmd,
'git credential fill <cred.txt' works (shell version), while calling git
without the git-wrapper (i.e. 'mingw64\bin\git credential fill <cred.txt')
mangles non-ASCII chars in both console output and input.

Signed-off-by: Karsten Blees <blees@dcon.de>
  • Loading branch information
kblees authored and dscho committed Sep 24, 2024
1 parent 781e463 commit fc0ca2b
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions compat/terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ static char *shell_prompt(const char *prompt, int echo)
strvec_pushv(&child.args, read_input);
child.in = -1;
child.out = -1;
child.silent_exec_failure = 1;

if (start_command(&child))
return NULL;
Expand Down Expand Up @@ -478,11 +479,14 @@ char *git_terminal_prompt(const char *prompt, int echo)
static struct strbuf buf = STRBUF_INIT;
int r;
FILE *input_fh, *output_fh;

#ifdef GIT_WINDOWS_NATIVE
const char *term = getenv("TERM");

if (term && starts_with(term, "xterm"))
return shell_prompt(prompt, echo);
/* try shell_prompt first, fall back to CONIN/OUT if bash is missing */
char *result = shell_prompt(prompt, echo);
if (result || errno != ENOENT)
return result;

#endif

input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);
Expand Down

0 comments on commit fc0ca2b

Please sign in to comment.