1

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?

Fagner Brack
  • 2,365
  • 4
  • 33
  • 69

1 Answers1

2

This happens because the SSH passphrase is supposed to be read from a pseudo terminal not from STDIN. 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 on ssh (of course, only for repositories, accessible via ssh). Here's the sequence of actions

  1. git detects that a given repository is accessible via ssh and invokes ssh transport
  2. ssh transport detects whether ssh authentication agent is running on the computer or not.
  3. If the agent is not detected (your case), then the transport switches to basic console-based authentication. ssh expects a "real console", so simple stdin/stdout redirection is not enough.
  4. or if the ssh agent is running then all key verification is passed to the agent.
  5. There could be different alternative agent implementations. Some simply ask user for a password to unlock a ssh key, other keep a set of pre-unlocked keys in memory etc. And depending on agent nature it may display password prompt in console or open a new separate window with a prompt. Check this page, particularly the part about putty/pageant to get the idea how SSH authentication can be set up on Windows.

You 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.

Community
  • 1
  • 1
user3159253
  • 16,836
  • 3
  • 30
  • 56
  • Any idea of how could I solve all issues regarding git handling in java without having to understand low level stuff like this? A library perhaps? – Fagner Brack Nov 27 '14 at 19:37
  • After your edit: JGit is exactly what I am using right now :D, thanks! – Fagner Brack Nov 27 '14 at 23:42
  • Ok :) Please do remember that jgit uses [jsch](http://www.jcraft.com/jsch/) to perform all ssh-related operations like `git push` and `git fetch`. Which in turn demands [JSch Agent proxy](http://www.jcraft.com/jsch-agent-proxy/) to use auth agents like `ssh-agent` or `pageant` for handling SSH key authentication (a nice feature since it allows to avoid necessity of entering a passphrase each time you need to interact a remote repository) – user3159253 Nov 28 '14 at 00:08
  • Are you saying that `$ git pull` is not going to work unless I integrate with the tools you mentioned? Or all this works out of the box and you are just enhancing your JGit suggestion with additional info? – Fagner Brack Nov 28 '14 at 00:54
  • :-) Well, `git pull` (that is java methods logically equivalent to `git pull`) will work, because `jsch` is a dependency of `jgit`, and thus it is probably already on your computer, thanks to maven. `jsch-agent-proxy` is an optional dependency, so likely you need to explicitly configure its usage in your application – user3159253 Nov 28 '14 at 02:17
  • Yeah I had to configure it using a JschConfigSessionFactory. I am not sure if there is an easiest way for me to do it other than get this recipe and apply it: https://github.com/web-stories/release/blob/da834874ab6b081658d9ec50054b7698505edc7c/src/main/java/org/webstories/release/git/GitCommands.java#L49-L76 – Fagner Brack Nov 28 '14 at 02:46