Проблемы JGit checkout и `git checkout`

tl;dr JGit checkout выдает исключения, в то время как командная строка git checkout работает нормально

В настоящее время я пытаюсь использовать JGit для проверки определенных версий из онлайн-репозитория Git на Java (для работы). Мой текущий подход (и я очень новичок в Git, исходя из фона SVN, так что это может быть неправильно):

  • клонировать репозиторий во временное место на моем жестком диске
  • выяснить, какую ревизию я хочу (я пытался использовать хэш SHA-1, а также имя ветки)
  • проверить эту версию
  • оттуда я буду использовать проверенные файлы в качестве входных данных для более поздней части программы.
  • проверить другую ревизию
  • использовать эти файлы в качестве входных данных для другой части программы

По сути, я хочу иметь возможность менять содержимое моей временной папки на любую версию. С интерфейсом командной строки я смог сделать это с помощью git checkout master и git checkout dylanbranch (где dylanbranch — это ветвь, которую я сделал на своем собственном клоне с произвольно выбранной ревизией), но мой Java-код, пытающийся сделать то же самое, терпит неудачу:

Git git = Git.open(new File("checkout")); //checkout is the folder with .git
git.checkout().setName("master").call(); //succeeds
git.checkout().setName("dylanbranch").call(); //fails

И исключения, напечатанные на консоли:

Exception in thread "main" org.eclipse.jgit.api.errors.JGitInternalException: Checkout conflict with files: 
src/sizzle
test/qunit
    at org.eclipse.jgit.api.CheckoutCommand.call(CheckoutCommand.java:211)
    at com.avi.scm.git.BranchCheckout.main(BranchCheckout.java:30)
Caused by: org.eclipse.jgit.errors.CheckoutConflictException: Checkout conflict with files: 
src/sizzle
test/qunit
    at org.eclipse.jgit.dircache.DirCacheCheckout.checkout(DirCacheCheckout.java:387)
    at org.eclipse.jgit.api.CheckoutCommand.call(CheckoutCommand.java:162)
    ... 1 more

Я могу убедиться, что рассматриваемые файлы помечены как удаленные и не подготовлены для фиксации с помощью git status, хотя я не уверен, почему эти изменения существуют, и они возвращаются каждый раз, когда я переключаюсь обратно на ветку master. Несмотря на это, я все еще могу успешно изменить рабочее дерево с помощью командной строки Git.

Итак, мой вопрос: Почему JGit не работает для этого приложения, когда git работает из командной строки? Любая другая полезная информация приветствуется - просветите меня :)

Обновление Я тестировал репозиторий jQuery и заметил еще несколько проблем с JGit: когда я работаю с веткой "master", git status сообщает мне, что я #On branch master и что там равно nothing to commit (working directory clean), но с помощью команды состояния JGit я вижу, что test/qunit и src/sizzle помечены как Missing. Сброс JGit, похоже, ничего не делает.


person Dylan    schedule 16.09.2011    source источник


Ответы (3)


Два каталога, упомянутые в трассировке стека, — это подмодули Git (test/qunit и src/sizzle), что наиболее вероятно, причина проблемы, поскольку JGit еще не имеет полной поддержки подмодулей.

Это может работать по-другому в версии 1.1 JGit, которая должна выйти в этом месяце, в зависимости от этого фиксации.

Подробнее о текущем состоянии поддержки подмодулей JGit можно прочитать здесь.

person Kevin Sawicki    schedule 20.09.2011
comment
Спасибо за ссылки, +1 Для всех, кто пытается сделать то же самое, мой текущий план атаки состоит в том, чтобы зафиксировать изменения, которые видит JGit, чтобы я мог проверить другие вещи. (По существу игнорируя подмодули, как JGit) - person Dylan; 21.09.2011
comment
Можете ли вы попробовать версию JGit здесь и посмотрите, получаете ли вы такие же конфликтные исключения? - person Kevin Sawicki; 21.09.2011
comment
Эта более новая версия действительно решает мою проблему (хотя команда клонирования теперь прерывается, когда вы пытаетесь переопределить/обновить существующий клон). - person Dylan; 21.09.2011
comment
На самом деле, я нашел это: stackoverflow .com/questions/1685228/how-to-cat-a-file-in-jgit, где показано, как получить содержимое файла без проверки - person Dylan; 22.09.2011

Я знаю, что это не напрямую отвечает на ваш вопрос, но у меня также были проблемы с реализациями Git на Java. Для меня лучше всего было просто отказаться от реализации Java и выполнять вызовы git из командной строки из приложения. Это может быть не идеально, но оно будет делать именно то, что вы хотите, поскольку вы будете полностью контролировать команду.

Просто позвоните Runtime.getRuntime().exec(...)

Ссылка на Javadoc для класса Runtime

person Ken Mason    schedule 16.09.2011
comment
Я согласен с тем, что Runtime будет работать в моей собственной системе, но у нас нет гарантии, что пользователи будут иметь git в своих системах, и я надеюсь, что мне не придется распространять бинарные файлы для конкретной ОС. - person Dylan; 16.09.2011

У меня была аналогичная проблема с Checkout. Я думаю, что тот факт, что вы можете переключать ветки с неустановленным контентом в Git, на самом деле является допуском, а не функцией. JGit в глобальном масштабе не так толерантен, как Git, поэтому обычно следует тестировать множество случаев.

Кажется, это не ваша проблема (которая связана с подмодулями), но в более общих случаях вы хотели бы зафиксировать свои изменения, прежде чем использовать проверку для переключения на другую ветку.

Обратите внимание, что CheckoutCommand отлично работает для меня, чтобы запустить новую ветку из старой ревизии (вы должны установить имя ветки и начальную ревизию).

person Vince    schedule 17.11.2011