Статьи

Упрощенная работа с подмодулями Git с push-доступом на месте — Git Tricks # 2

Узнайте, как решить проблему, отправив субмодули непосредственно из основного репо, сохранив при этом возможность простого клонирования проекта внешними участниками.

Вступление

Механизм субмодулей Git довольно удобен, чтобы хранить исходный код вредоносного программного обеспечения вместе в одном репозитории Git, оставляя их разработку отдельной. Это что-то вроде символических ссылок в мире Unix, но с возможностью ссылаться и на предыдущую версию. Он довольно популярен в проектах, использующих интеграцию исходного кода (вместо общих библиотек) или для ускорения разработки за счет упрощения связанных изменений в нескольких репозиториях. Это не единственное возможное решение — например, Gradle предоставляет механизм составной сборки. Monorepo — это другой подход, но у него есть свои ограничения, и его очень проблематично использовать в проектах FOSS, разработанных разными людьми / командами.

Как обычно, я столкнулся с такой ситуацией в одном из моих проектов. Будучи большим энтузиастом автоматического тестирования кода и непрерывной доставки, некоторое время назад я работал над повышением надежности моего (автоматически выпускаемого) плагина gradle-nexus-staging-plugin . После каждого коммита (так же как и перед выпуском) я хотел выполнить сквозные тесты, чтобы убедиться, что плагин способен передавать простой (но реальный) проект через процесс выпуска в Maven Central (он же Центральный репозиторий). ).

Я мог бы перенести этот тестовый проект в репозиторий плагинов, но — ну, это отдельный проект, который можно было бы также выпустить отдельно или заменить другим проектом. Кроме того, при тестировании двух вариантов освобождения было удобно использовать его в двух ветках, «смонтированных» дважды в моем корневом хранилище.

01
02
03
04
05
06
07
08
09
10
11
12
13
gradle-nexus-staging-plugin
├── src
│   ├── funcTest
│   │   ├── groovy
│   │   │   └── ...
│   │   └── resources
│   │       └── sampleProjects
│   │           ├── nexus-at-minimal (submodule - master branch)
│   │           │   └── ...
│   │           ├── nexus-at-minimal-publish (submodule - publish branch)
│   │           │   └── ...
│   │           └── ...
│   ├── ...

Проблема (иначе вызов)

gradle-nexus-staging-plugin содержит субмодуль nexus-at-minimal из отдельного репозитория. Работая над новой необычной функцией в GNSP, необходимо настроить проект приемочного тестирования. Чтобы сделать разработку более плавной, очень полезно иметь возможность вносить изменения в зависимый проект непосредственно из рабочей копии основного проекта. Работает из коробки. Тем не менее, в дальнейшем мы также должны напрямую отправить их обратно в отдельное репо этого зависимого проекта (путем входа в подмодуль и вызова git push или — все в одном — используя git push --recurse-submodules=on-deamand параметр git push --recurse-submodules=on-deamand при нажатии из основного репозитория). И затем — в долгосрочной перспективе — мы сталкиваемся с некоторыми неудобствами.

Давайте начнем с определения пути субмодуля для подключения через SSH:

1
2
3
[submodule "src/funcTest/resources/sampleProjects/nexus-at-minimal"]
        path = src/funcTest/resources/sampleProjects/nexus-at-minimal
        url = [email protected]:nexus-at/nexus-at-minimal.git

В общем, работает нормально и толкание разрешено. Однако любой не разработчик, пытающийся клонировать это репо (и инициализировать подмодули), получает:

1
2
3
4
5
6
...
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.
 
Please make sure you have the correct access rights
and the repository exists.

Это довольно плохо в разработке с открытым исходным кодом (FOSS), когда проекты общедоступны, другим людям предлагается загрузить (клонировать) их, создать и внести свой вклад.

Очевидное исправление предыдущей ошибки — переключение на HTTPS:

1
2
3
[submodule "src/funcTest/resources/sampleProjects/nexus-at-minimal"]
        path = src/funcTest/resources/sampleProjects/nexus-at-minimal
        url = https://gitlab.com/nexus-at/nexus-at-minimal.git

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

Прозрачное решение

Чтобы внешние участники были довольны, разработчики могли вручную изменять URL-адрес в .gitmodules с HTTPS на SSH для каждого клонированного проекта. Тем не менее, это довольно утомительно. Лучшее решение — использование pushInsteadOf . Для вышеупомянутого примера разработчикам нужно только добавить в глобальный ~/.gitconfig конфигурации ~/.gitconfig :

1
2
[url "[email protected]:nexus-at/"]
    pushInsteadOf = https://gitlab.com/nexus-at/

Он эффективно переопределяет push-URL для использования SSH вместо HTTPS для всей группы в GitLab / GitHub, охватывая также подмодули (где HTTPS — схема, удобная для внешних участников — оставлена ​​по умолчанию).

Резюме

Перезапись URL-адреса и условная конфигурация (описанная в первой части ) — это лишь часть вариантов, доступных в Git, чтобы сделать разработку более гибкой и простой. Все просто, если мы уже нашли нужные функции и научились ими пользоваться ;-).

Главная фотография, основанная на работе Мохамеда Хасана , опубликованной в Pixabay , Pixabay License.

Смотрите оригинальную статью здесь: Упрощенная работа с подмодулями Git с push-доступом на месте — Git Tricks # 2

Мнения, высказанные участниками Java Code Geeks, являются их собственными.