When executing the following command, I am prompted to type the password:
$ git pull
Enter passphrase for key (...)
When I try to show the same information programatically using Apache Commons Exec, the program gets stuck and doesn't print anything:
CommandLine cmd = new CommandLine( "git" );
cmd.addArgument( "pull" );
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler( new PumpStreamHandler( System.out, System.err, System.in ) );
executor.execute( cmd );
Why does the example get stuck without printing anything, and while using the native console it prompts me to provide the git password?
This happens because the SSH passphrase is supposed to be read from a
pseudo terminal
not fromSTDIN
. You have to create a pseudo tty communication stream between parent (your program) and child (git) processes and perform entire communication over that stream. Take a look at Pseudo terminal to use with ssh in java to get the idea.Also it should be noted that it's not
git
asks for passphrase.git
itself doesn't perform any authentication, simply relying onssh
(of course, only for repositories, accessible via ssh). Here's the sequence of actionsgit
detects that a given repository is accessible via ssh and invokes ssh transportYou may take a look at pty4j which uses JNA to implement terminal and process execution low level stuff. Or take a look at JGit which is a pure-java re-implementation of git, and it doesn't invoke command line git at all. JGit is a base for e.g Eclipse Git plugin or Gerrit Code review system so it's elaborated and polished.