Как использовать JGit для эквивалента git push --mirror?

Я пытаюсь создать простое приложение, которое выполняет операцию «git push --mirror» из домена Java.

Библиотека JGit, в частности PushCommand, похоже, не поддерживает параметр «--mirror», хотя он поддерживает «--all» и «--tags».

Я что-то упускаю? Как мы используем JGit для выполнения «git push --mirror…»?


person DavidCastagna    schedule 13.08.2014    source источник


Ответы (2)


Попробуйте вручную, используя следующую спецификацию ref:

git.push().setRefSpecs(new RefSpec("+refs/*:refs/*")).call();
person robinst    schedule 14.08.2014
comment
Спасибо за этого робинста. - person DavidCastagna; 18.08.2014

Точного эквивалента --mirror в JGit пока нет, но вы должны уметь подражать этому поведению. Чтобы принудительно отправить все локальные ссылки, вы можете настроить PushCommand с помощью

PushCommand pushCommand = git.push();
pushCommand.setForce(true);
pushCommand.add("refs/*:refs/*");

Это оставило бы ссылки, которые были удалены локально. Поэтому вы можете получить список удаленных ссылок, чтобы определить, что было удалено локально, и опубликовать эти удаления на удаленном компьютере:

Collection<Ref> remoteRefs = git.lsRemote().setRemote("origin").setHeads(true).setTags(true).call();
Collection<String> deletedRefs = new ArrayList<String>();
for (Ref remoteRef : remoteRefs) {
  if (git.getRepository().getRef(remoteRef.getName()) == null) {
    deletedRefs.add(remoteRef.getName());
  }
}
for (String deletedRef : deletedRefs) {
  pushCommand.add(":" + deletedRef);
}

Переменная git ссылается на репозиторий, из которого вы хотите выполнить отправку, т. е. тот, который находится в первом блоке. LsRemoteCommand возвращает все заголовки и теги из удаленного репозитория, настроенного как origin в конфигурации локального репозитория. В обычном случае тот, с которого вы клонировали.

Обратите внимание, что существует небольшой пробел в подходе к распространению удаленных локальных ссылок. LsRemoteCommand возвращает только ссылки под heads и tags (например, никаких пользовательских ссылок, таких как pulls), поэтому вы не обнаружите локальное удаление, например. refs/foo/bar.

Это работает для вас?

person Rüdiger Herrmann    schedule 14.08.2014
comment
Первая часть работает нормально (спасибо за это). Но это обнаружение удаленных ссылок кажется более сложным. Похоже, мне сначала нужно будет клонировать копию репо, а затем выполнить LsRemoteCommand в клоне (иначе пульта нет). Итак, должен ли объект git во втором блоке кода быть git на дальнем конце push-соединения или дополнительным клоном репо, который я должен сделать, прежде чем отправить его на зеркало? (Примечание: я ожидаю запустить это приложение из папки основного хранилища для git, а не из клона.) - person DavidCastagna; 18.08.2014
comment
Я должен сделать это правильно?: Git gRemote = new Git(new FileRepository(‹‹удаленный путь››)) ; Collection‹Ref› remoteRefs = ››gRemote‹‹.lsRemote().setHeads(true).setTags(true).call() ; Потом остальное, что ты дал... - person DavidCastagna; 18.08.2014
comment
Боюсь, я не понимаю, что означает «главная папка хранения для git». Насколько я понимаю ваш первоначальный вопрос, у вас есть клонированный репозиторий, из которого вы хотите выпустить файл push --mirror. Я аннотировал второй блок кода в надежде прояснить ситуацию. - person Rüdiger Herrmann; 19.08.2014
comment
Нет, я не клонировал... и не хочу. У нас есть главный сервер с Gits и зеркальные серверы с копиями (созданными с помощью git push --mirror). Если я хочу скомпилировать список удаленных элементов, как в вашем примере кода, как я могу рассчитать список элементов в копии Git на зеркальном сервере без предварительного его клонирования? В основном все сводится к следующему: вызов git›.lsRemote() работает только на клоне. Есть ли способ получить список всех ссылок на заголовки и теги без предварительного клонирования git? - person DavidCastagna; 19.08.2014
comment
Существует метод satic Git.lsRemoteRepository(), он вернет LsRemoteCommand, который работает без (локального) репозитория. Должна быть возможность заменить git.lsRemote() во втором блоке кода на Git.lsRemoteRepository() и использовать setRemote для указания URL-адреса удаленного репозитория. Но имейте в виду, что статически созданный LsRemoteCommand имеет свои ограничения - person Rüdiger Herrmann; 20.08.2014
comment
@RüdigerHerrmann, я знаю, что опаздываю на вечеринку. Уже более 3 лет кто-то задавал этот вопрос. Я хотел бы сделать ``` git clone --depth 1 git-url ```, возможно ли теперь сделать поверхностную копию? - person supritshah1289; 12.06.2018
comment
На данный момент мелкие клоны по-прежнему не поддерживаются JGit, см. комментарии к stackoverflow.com/questions/11475263/shallow-clone-with-jgit - person Rüdiger Herrmann; 12.06.2018