seeraven/gitcache

No password prompt on Windows

Closed this issue · 2 comments

When using a password secured ssh key, gitcache does not ask for a password on Windows but simply fails to clone:

2024-04-25 19:19:44 Starting Initial clone of git@github.com:<my repo>.git into D:\gitcache\mirrors\github.com\<my repo>.
Cloning into bare repository 'D:\gitcache\mirrors\github.com\<my repo>\git'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
2024-04-25 19:19:46 Command 'C:\Program Files\Git\cmd\git.exe clone --progress --mirror git@github.com:<my repo>.git D:\gitcache\mirrors\github.com\<my repo>\git' failed with return code 128. Starting retry 1 of 3.

On Linux the password prompt is shown as expected.

Discovered and reported by @Youw

The problem is apparently git for windows. As soon as one redirects stderr it assumes it is running without a console and won't prompt for a password. This is apparently a known bug for over 6 years now: git-for-windows/git#1613

In gitcache we redirect stderr to a pipe to be able to monitor the progress of git and to detect stalled instances, which is quite essential in setups with bad networks and non-interactive usage like in CI/CD.

Therefore, a complete removal of the stderr monitoring should not be an option. But we see two possible workarounds:

  • We could remove the stderr redirect if the user specified an outputtimeout = 0 in the config. Of course this requires some knowledge of the user, so perhaps an information should be printed if we see the answer Permission denied (publickey) in the original output.
  • We could retry automatically without stderr redirection if we see the message Permission denied (publickey) in the output. This would mean we loose always one retry attempt for the first (failing) one, but it wouldn't need any additional configuration.

I've implemented now a workaround for git-for-windows that checks for an authentication error in the stderr and if found disables the stderr monitoring for the next retry.