При выполнении следующей команды мне предлагается ввести пароль:
$ git pull
Enter passphrase for key (...)
Когда я пытаюсь показать ту же информацию программно с помощью Apache Commons Exec, программа застревает и ничего не печатает:
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 );
Почему этот пример застрял, не печатая ничего, и при использовании родной консоли он предлагает мне предоставить пароль git?
Это происходит потому, что кодовая фраза SSH должна считываться с pseudo terminal
не из STDIN
. Вы должны создать поток коммуникации псевдо-tty между родительскими (вашими программами) и дочерними (git) процессами и выполнить всю связь по этому потоку. Взгляните на Pseudo терминал, чтобы использовать с ssh в java, чтобы получить идею.
Также следует отметить, что он не git
просит ключевую фразу. git
сам не выполняет никакой аутентификации, просто полагаясь на ssh
(конечно, только для репозиториев, доступных через ssh). Здесь последовательность действий
git
обнаруживает, что данный репозиторий доступен через ssh и вызывает ssh-транспортВы можете взглянуть на pty4j, который использует JNA для реализации терминального и процесса выполнения низкого уровня. Или взгляните на JGit, который представляет собой чистую java-повторную реализацию git, и он вообще не вызывает командную строку git. JGit является базой, например, для плагина Eclipse Git или системы проверки кода Gerrit, поэтому он разработан и отполирован.