Підмодуль - інший Git-репозиторій, вкладений у каталог вашого репозиторію. Головний репозиторій зберігає не файли підмодуля, а посилання на конкретний коміт.
git submodule add https://github.com/acme/docs.git docs
З'являються файл .gitmodules (адреса й шлях) і запис-вказівник у дереві:
[submodule "docs"]
path = docs
url = https://github.com/acme/docs.git
Клонування з підмодулями:
git clone --recurse-submodules https://github.com/acme/app.git
# або в уже існуючому клоні
git submodule update --init --recursive
Типові проблеми:
- порожній каталог після клону - клонували без
--recurse-submodules; - detached HEAD у підмодулі:
submodule updateпереключає підмодуль на записаний коміт, а не на гілку. Коміти, зроблені там без перемикання на гілку, легко загубити; - оновлення - два кроки: зробити коміт і push у репозиторії підмодуля, а потім закомітити новий вказівник у головному репозиторії. Якщо забути другий крок, колеги отримають стару версію; якщо забути push - вказівник посилатиметься на коміт, якого немає на сервері;
git pullне оновлює підмодулі автоматично - потрібенgit submodule update(чиgit config submodule.recurse true);- конфлікти вказівників при злитті гілок, що оновили підмодуль по-різному;
- CI і доступи: приватний підмодуль вимагає окремих прав на клонування.
Коли підмодулі доречні:
- спільний код, що розвивається окремо, з власним циклом випусків, і потрібна точна версія;
- документація чи контент в окремому репозиторії, яким керує інша команда.
Альтернативи для PHP-проєкту:
- Composer-пакет (зокрема з
path- чиvcs-репозиторієм) - для спільного PHP-коду майже завжди краще: версії, залежності, автозавантаження; - subtree - код копіюється в репозиторій з історією, без окремого клонування;
- монорепозиторій - якщо код насправді тісно пов'язаний.
Корисні налаштування: git config --global submodule.recurse true і git config --global status.submoduleSummary true - Git сам оновлює підмодулі й показує їхні зміни в git status.