@@ -296,12 +296,41 @@ impl CredentialHelper {
296
296
}
297
297
) ) ;
298
298
299
- let mut p = my_try ! ( Command :: new( "sh" ) . arg( "-c" )
300
- . arg( & format!( "{} get" , cmd) )
301
- . stdin( Stdio :: piped( ) )
302
- . stdout( Stdio :: piped( ) )
303
- . stderr( Stdio :: piped( ) )
304
- . spawn( ) ) ;
299
+ // It looks like the `cmd` specification is typically bourne-shell-like
300
+ // syntax, so try that first. If that fails, though, we may be on a
301
+ // Windows machine for example where `sh` isn't actually available by
302
+ // default. Most credential helper configurations though are pretty
303
+ // simple (aka one or two space-separated strings) so also try to invoke
304
+ // the process directly.
305
+ //
306
+ // If that fails then it's up to the user to put `sh` in path and make
307
+ // sure it works.
308
+ let mut cmd = Command :: new ( "sh" ) ;
309
+ cmd. arg ( "-c" )
310
+ . arg ( & format ! ( "{} get" , cmd) ) ;
311
+ . stdin ( Stdio :: piped ( ) )
312
+ . stdout ( Stdio :: piped ( ) )
313
+ . stderr ( Stdio :: piped ( ) ) ;
314
+ let mut p = match cmd. spawn ( ) {
315
+ Ok ( p) => p,
316
+ Err ( e) => {
317
+ debug ! ( "`sh` failed to spawn: {}" , e) ;
318
+ let mut parts = cmd. split_whitespace ( ) ;
319
+ let mut cmd = Command :: new ( parts. next ( ) . unwrap ( ) ) ;
320
+ for arg in parts {
321
+ cmd. arg ( arg) ;
322
+ }
323
+ cmd. arg ( "get" ) ;
324
+ match cmd. spawn ( ) {
325
+ Ok ( p) => p,
326
+ Err ( e) => {
327
+ debug ! ( "fallback of {:?} failed with {}" , e) ;
328
+ return ( None , None ) ;
329
+ }
330
+ }
331
+ }
332
+ } ;
333
+
305
334
// Ignore write errors as the command may not actually be listening for
306
335
// stdin
307
336
{
0 commit comments