Git Submodules

6 min read

Иногда возникает потребность использовать в проекте готовый модуль или библиотеку. Причем это может быть как стороннее решение, так и ваша собственная разработка. Вы можете скопировать код библиотеки в проект, либо подключить его с помощью пакетного менеджера вроде npm, Rubygems или Composer.

Но что если стабильной версии модуля нет, и ему еще требуется отладка и доработка? Система контроля версий Git позволяет подключать один репозиторий, как поддиректорию другого. Эти вложенные репозитории называются подмодулями Git. Такая структура удобна для разработки и тестирования — у вас будет система контроля версий для каждого репозитория, а также вы сможете отлавливать и исправлять ошибки прямо в подмодуле. 

Помимо отладки, подмодули — способ абстрагировать какой-то компонент, чтобы его можно было использовать в нескольких проектах и дорабатывать независимо от основного приложения. Из этой статьи вы узнаете, как добавлять в проект git-подмодули и как работать с ними.

Добавление Git-подмодуля

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

Склонируем Git-репозиторий на компьютер. Для этого переместимся в директорию с проектами, выполнив в консоли команду:

cd path/to/your/projects_folder

 Затем создадим директорию project_dir и скопируем туда проект:

git clone https://github.com/your_user_name/project project_dir

Перейдем в только что созданную папку с проектом:

cd project_dir

Теперь добавим подмодуль. Вам потребуется адрес репозитория подмодуля и папка, в которой он должен оказаться:

git submodule add https://github.com/any_user_name/submodule_name submodules_folder/submodule_name

Если в проекте не было папки submodules_folder, она будет создана автоматически.

Копирование займет некоторое время. Когда оно завершится, вы увидите что-то подобное:

Cloning into '/path/to/your/project_dir/submodules_folder/submodule_name'... remote: Counting objects: 29875, done. remote: Compressing objects: 100% (51/51), done. remote: Total 29875 (delta 38), reused 65 (delta 33), pack-reused 29771 Receiving objects: 100% (29875/29875), 5.71 MiB | 85.00 KiB/s, done. Resolving deltas: 100% (18713/18713), done.

Если сейчас выполнить git status, вы заметите, что в проекте появились новые файлы:

git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitmodules new file: submodule_name

Это конфигурационный файл .gitmodules и папка подмодуля, который вы только что добавили.

Теперь нам нужно зафиксировать изменения в репозитории. Для начала выберем файлы git add file1 file2. 

В нашем случае:

git add .gitmodules submodule_name

Далее зафиксируем изменения локально. Не забываем про commit message после флага  -m

git commit -m 'Submodule submodule_name added'

И отправим изменения в репозиторий на GitHub:

git push

Вы великолепны! Теперь другие разработчики могут склонировать ваш репозиторий с подмодулями и начать работу.

Клонирование проекта с подмодулями

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

Так вы инициализируете локальный конфигурационный файл .gitmodules:

git submodule init

А затем загрузите подмодуль проекта в свою директорию командой:

git submodule update

Либо при клонировании проекта с подмодулями используйте флаг --recursive:

git clone --recursive https://github.com/your_user_name/project

После этого в папке подмодуля появятся его файлы.

Обновление подмодуля

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

git fetch

И затем для обновления локальной версии из ветки master репозитория подмодуля выполните:

git merge

Удаление подмодуля

Если вы хотите удалить подмодуль, избавиться от папки в проекте недостаточно — придется поправить ещё конфигурационные файлы. Итак, поехали.

1. Для начала необходимо удалить нужную секцию в файле .gitmodules. 

[submodule "submodule_name"] path = submodule_name url = git://github.com/any_user_name/submodule_name.git

2. Зафиксировать изменения, выполнив:

git add .gitmodules

3. Удалить соответствующие модулю строки из .git/config. Это можно сделать, открыв файл в текстовом редакторе nano: nano .git/config

[submodule "submodule_name"] url = git://github.com/any_user_name/submodule_name.git

4. Удалить пути, созданные для подмодулей, из области индексирования:

git rm --cached path/to/submodule_name

Где path/to/submodule_name — путь к директории подмодуля.

5. Удалить каталог подмодуля:

rm -rf .git/modules/submodule_name

Где submodule_name — имя подмодуля.

6. Сделать коммит изменений.

7. Удалить ненужные файлы подмодулей:

rm -rf path/to/submodule_name

Итого

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