2014-11-24 1 views
1

При выполнении следующей команды, я предложено ввести пароль:Почему команда «git pull» exec застревает и ничего не печатает?

$ 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?

ответ

2

Это происходит потому, что кодовая фраза SSH должна считаться с pseudo terminal не с STDIN. Вы должны создать поток коммуникации псевдо-tty между родительскими (вашими программами) и дочерними (git) процессами и выполнить всю связь по этому потоку. Взгляните на Pseudo terminal to use with ssh in java, чтобы получить эту идею.

Также следует отметить, что это не git запрашивает кодовую фразу. git сам не выполняет никакой аутентификации, просто полагаясь на ssh (конечно, только для репозиториев, доступных через ssh). Вот последовательность действий

  1. git обнаруживает, что данный репозиторий доступен через SSH и вызывает SSH транспорта
  2. SSH транспорт определяет, является ли проверка подлинности SSH агент работает на компьютере или нет.
  3. Если агент не обнаружен (ваш случай), то транспорт переключается на базовую аутентификацию на основе консоли. ssh ожидает «настоящую консоль», поэтому простого перенаправления stdin/stdout недостаточно.
  4. или если агент ssh запущен, вся проверка ключа передается агенту.
  5. Возможны различные варианты реализации альтернативных агентов. Некоторые просто спрашивают у пользователя пароль для разблокировки ключа ssh, другие сохраняют набор предварительно разблокированных ключей в памяти и т. Д. И в зависимости от характера агента он может отображать приглашение пароля в консоли или открывать новое отдельное окно с подсказкой. Проверьте this page, в частности, часть о шпаклевке/конкурсе, чтобы понять, как можно настроить аутентификацию SSH в Windows.

Вы можете взглянуть на pty4j, который использует JNA для реализации терминалов и обработки процесса низкого уровня. Или взгляните на JGit, который представляет собой чистую java-повторную реализацию git, и он вообще не вызывает командную строку git. JGit является базой, например, Eclipse Git plugin или Gerrit Code review system, поэтому он разработан и отполирован.

+0

Любая идея о том, как я могу решить все проблемы, связанные с обработкой git в java, без необходимости понимать такие вещи низкого уровня? Возможно, библиотека? –

+0

После вашего редактирования: JGit - это именно то, что я использую прямо сейчас: D, спасибо! –

+0

Хорошо :) Помните, что jgit использует [jsch] (http://www.jcraft.com/jsch/) для выполнения всех связанных с ssh операций, таких как 'git push' и' git fetch'. Это, в свою очередь, требует [JSch Agent proxy] (http://www.jcraft.com/jsch-agent-proxy/) использовать авторизационные агенты, такие как 'ssh-agent' или' pageant' для обработки аутентификации ключа SSH (хорошая функция так как это позволяет избежать необходимости вводить кодовую фразу каждый раз, когда вам нужно взаимодействовать с удаленным репозиторием) – user3159253