Подмодули Git можно назвать репозиториями внутри репозиториев, которые позволяют добавлять в проект внешние библиотеки кода или зависимости без привязки системы контроля версий модуля к самому проекту. Это делает модули обособленными, что упрощает их обновление, а каталог также легко можно преобразовать в новый подмодуль.
Что такое подмодуль в Git?
Подмодуль – это репозиторий Git, который встроен в другой репозиторий Git. Таким образом, вы можете добавлять код из других проектов в качестве зависимостей и поддерживать при этом его собственное управление версиями.
Когда вы клонируете родительский репозиторий, репозиторий подмодуля клонируется автоматически. Это значит, что код подмодуля и история Git хранятся отдельно от основного управления версиями, и их можно обновлять для разных репозиториев, использующих библиотеку.
Альтернатива подмодуля – публикация ваших библиотек в виде пакетов в диспетчерах пакетов, например, NPM, Maven или NuGet. Но такой вариант подходит не для всех типов проектов. Если вы работаете с личным кодом, то вам придется настроить частный реестр пакетов, а это может оказаться куда более сложным, чем простое встраивание исходного кода библиотеки в качестве подмодуля.
Одна из основных проблем, которая возникает при преобразовании существующего каталога в подмодуль заключается в том, что управление подмодулем должно производиться извне. Git ждет, что вы создадите для него новый пустой каталог и клонируете подмодуль в проект. Вы можете скопировать код в новую папку, но тогда вы потеряете всю историю Git, связанную с ним, что будет иметь негативные последствия для крупных проектов. Вместо этого мы клонируем репозиторий, удалим ненужный код и отправим новую историю в новый подмодуль.
Как превратить каталог в подмодуль
Первый шаг – создание нового репозитория для подмодуля. Как правило, это делается на хостинге Git, например, GitHub, но вы можете создать локальный репозиторий на своем компьютере.
Далее вам понадобиться свежая копия вашего основного репозитория. Из нее будет создаваться репозиторий подмодуля.
git clone git@github.com:username/repository.git submodule-repo
cd submodule-repo
Затем вы должны удалить все, что не имеет отношение к вашему подмодулю. То есть будут удалены вся история коммитов, никак не связанных с кодом, который содержится в подмодуле. Эта операция подразумевает разрушение данных, так что убедитесь, что вы выполняете ее именно с копией вашего репозитория, а не с основным репозиторием.
git filter-branch --subdirectory-filter submoduledirectory -- --all
У вас должен остаться только тот код, который был в каталоге, и соответствующие коммиты. Таким образом, вы сможете перенести всю историю Git, относящуюся к этому подмодулю.
Также вам нужно будет изменить удаленный URL-адрес этого каталога на URL нового репозитория подмодуля, который, как правило, называется «origin».
git remote set-url origin https://github.com/new-repository.git
После чего вы можете передать историю в репозиторий так, как делали это всегда.
git push -u origin main
Добавление нового подмодуля
Когда вы вернетесь к основному проекту, вы, возможно, захотите добавить новый подмодуль.
Для начала вы должны перестать отслеживать каталог родительского репозитория, который вы хотите превратить в подмодуль. Он все также будет присутствовать в истории версий Git, и вы в любом случае только что добавили его в новый репозиторий модуля.
rm -rf directory_name
Далее вы можете добавить для репозитория подмодуля, который вы создали в GitHub, удаленный URL-адрес. Для этого вам понадобиться команда git submodule add:
git submodule add git@github.com:username/repository.git directory_name
После того, как вы запустите эту команду, Git создаст в родительском репозитории новый каталог подмодуля и клонирует репозиторий подмодуля в этот каталог. Плюс ко всему, он снова начнет отслеживать папку модуля.
А для того, чтобы обновить подмодуль, вам понадобиться команда git submodule update:
git submodule update --remote submodule_name