Статьи

Как клонировать Git-репозитории с JGit

Что бы вы ни планировали делать с существующим хранилищем, сначала нужно создать клон. Планируете ли вы внести свой вклад или просто хотите посмотреть его историю, необходима локальная копия репозитория.

Хотя клонирование репозитория с помощью JGit не представляет особой сложности, есть несколько деталей, которые стоит отметить. И поскольку по этой теме имеется мало онлайн-ресурсов, в этой статье описывается, как использовать JGit API для клонирования из существующего репозитория Git.

Основы клонирования

Чтобы сделать локальную копию удаленного репозитория, CloneCommand необходимо, по крайней мере, указать, где находится удаленный репозиторий:

1
2
3
Git git = Git.cloneRepository()
  .call();

У класса фабрики Git есть статический метод cloneRepository (), который возвращает новый экземпляр CloneCommand. setURI () указывает, откуда клонировать и как во всех командах JGit, метод call () фактически выполняет команду.

Хотя удаленные репозитории — как следует из названия — обычно хранятся на удаленном хосте, местоположение, указанное в setURI (), также может быть путем к локальному ресурсу.

Если больше информации не предоставлено, JGit выберет каталог, в котором будет храниться клонированный репозиторий. На основе текущего каталога и имени репозитория, полученного из его URL, создается имя каталога. В приведенном выше примере это будет / path / to / current / jgit.

Но обычно вы хотели бы иметь больший контроль над каталогом назначения и явно указывать, где хранить локальный клон.

Метод setDirectory () указывает, где должен находиться рабочий каталог, и с помощью setGitDir () можно указать местоположение каталога метаданных (.git). Если setGitDir () опущен, каталог .git создается непосредственно под рабочим каталогом.

Пример ниже

1
2
3
4
Git git = Git.cloneRepository()
  .setDirectory( "/path/to/repo" )
  .call();

создаст локальный репозиторий, рабочий каталог которого находится в «/ path / to / repo», а каталог метаданных которого расположен в «/path/to/repo/.git».

Однако место назначения выбирается явно через ваш код или с помощью JGit, указанный каталог должен быть либо пустым, либо не должен существовать. В противном случае будет выдано исключение.

Настройки для setDirectory (), setGitDir () и setBare () (см. Ниже) перенаправляются в InitCommand, который используется внутри CloneCommand. Поэтому более подробно об этом рассказывается в разделе « Инициализация репозиториев Git с помощью JGit» .

Экземпляр Git, возвращаемый CloneCommand.call (), обеспечивает доступ к самому хранилищу (git.getRepository ()) и может использоваться для выполнения дальнейших команд, нацеленных на это хранилище. Когда использование репозитория закончено, оно должно быть закрыто (git.close ()), иначе в приложении могут возникнуть утечки файловых дескрипторов.

Чтобы позднее восстановить экземпляр Repository (или Git), достаточно указать путь к рабочему каталогу или каталогу .git. Статья Как получить доступ к Git-репозиторию с помощью JGit содержит подробную информацию по этому вопросу.

Конфигурация восходящего потока

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

При просмотре файла конфигурации (.git / config) удаленный раздел выглядит так:

1
2
3
[remote "origin"]
  url = https://github.com/eclipse/jgit.git
  fetch = +refs/heads/*:refs/remotes/origin/*

Если удаленное имя не указано, используется значение по умолчанию «origin». Чтобы CloneCommand использовал определенное имя, под которым зарегистрирован удаленный репозиторий, используйте setRemote ().

Refspec, заданный ‘fetch’, определяет, какие ветви следует заменить при извлечении или удалении из удаленного репозитория по умолчанию.

Клонирование ветвей

По умолчанию команда clone создает одну локальную ветвь. Он просматривает ссылку на HEAD удаленного репозитория и создает локальную ветвь с тем же именем, что и удаленная ветка, на которую он ссылается.

Но команде clone также может быть приказано клонировать и оформить определенные ветви. Предполагая, что удаленный репозиторий имеет ветку с именем «extra», следующие строки будут клонировать эту ветку.

1
2
3
4
5
6
Git git = Git.cloneRepository()
  .setDirectory( "/path/to/repo" )
  .setBranchesToClone( singleton( "refs/heads/extra" ) );
  .setBranch( "refs/heads/extra" )
  .call();

С помощью setBranchesToClone () команда клонирует только указанные ветви. Обратите внимание, что директива setBranch () необходима также для извлечения желаемой ветви. В противном случае JGit попытается извлечь ветку ‘master’. Хотя это не проблема с технической точки зрения, обычно это не то, что вам нужно.

Если все ветви удаленного репозитория должны быть клонированы, вы можете посоветовать команду следующим образом:

1
2
3
4
5
Git git = Git.cloneRepository()
  .setDirectory( "/path/to/repo" )
  .setCloneAllBranches( true )
  .call();

Чтобы вообще не извлекать текущую ветвь, можно использовать метод setNoCheckout ().

Список удаленных веток

Если вы хотите узнать, какие ветви может предложить удаленный репозиторий, LsRemoteCommand придет на помощь. Чтобы вывести список всех ветвей репозитория JGit, используйте lsRemoteRepository () из Git, как показано ниже.

1
2
3
4
Collection<Ref> remoteRefs = Git.lsRemoteRepository()
  .setHeads( true )
  .call();

Если вы также хотите перечислить теги, советуйте команде с setTags (true) включать теги.

По причинам, которые я не хочу знать, JGit требует локального репозитория для определенных протоколов , чтобы иметь возможность перечислять удаленные ссылки. В этом случае Git.lsRemoteRepository () сгенерирует исключение NotSupportedException. Обходной путь — создать временный локальный репозиторий и использовать git.lsRemote () вместо Git.lsRemoteRepository (), где git оборачивает временный репозиторий.

Клонирование голых репозиториев

Если локальный репозиторий не нуждается в рабочем каталоге, команда clone может быть инструктирована для создания чистого репозитория.

По умолчанию создаются не пустые репозитории, но с помощью setBare (true) создается пустой репозиторий, как показано ниже:

1
2
3
4
5
Git git = Git.cloneRepository()
  .setBare( true )
  .setGitDir( "/path/to/repo" )
  .call();

Здесь каталог назначения указывается через setGitDir () вместо использования setDirectory ().
IsBare () результирующего репозитория вернет true, getGitDir () вернет / path / to / repo, и поскольку рабочего каталога нет, getWorkTree () сгенерирует исключение NoWorkTreeException.

Обратите внимание, что «голые» здесь применимы только к хранилищу назначения. Независимо от того, является ли исходный репозиторий пустым, не имеет значения при клонировании.

Подмодули клонирования

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

1
2
3
4
5
Git git = Git.cloneRepository()
  .setCloneSubmodules( true )
  .setDirectory( "/path/to/repo" )
  .call();

Приведенный выше пример советует команде clone также клонировать любой найденный субмодуль.

Если setCloneSubmodules (true) не был указан при клонировании репозитория, вы можете позже найти недостающие подмодули. Для получения более подробной информации смотрите статью Как управлять подмодулями Git с помощью JGit .

Клонирование с аутентификацией

Конечно, JGit также позволяет получить доступ к репозиториям, которые требуют аутентификации. Поддерживаются общие протоколы, такие как SSH и HTTP (S) и методы их аутентификации. Подробное объяснение того, как использовать поддержку аутентификации, можно найти в статье « Объяснение аутентификации JGit» .

Как клонировать Git-репозитории с помощью JGit

Почти для всех функций родной команды Git clone в JGit есть эквивалент. Существует даже монитор прогресса, который может быть полезен, когда JGit встроен в интерактивные приложения. И для отсутствующего варианта зеркала, по- видимому, существует обходной путь . JGit пока не поддерживает только часто запрашиваемые мелкие клоны (например, git clone --depth 2 ).

Фрагменты, показанные в этой статье, являются выдержками из обучающего теста, который иллюстрирует общие случаи использования CloneCommand.

Если у вас все еще есть трудности или вопросы, не стесняйтесь оставлять комментарии или обращаться за помощью к дружелюбному и полезному сообществу JGit .