|
|
# Основы работы с подмодулями
|
|
|
# Работа с подмодулями
|
|
|
|
|
|
1. Добавление подмодуля
|
|
|
Наша система представляет собой набор модулей или плагинов, достаточно независимых, чтобы можно было вести разработку различных подсистем изолированно друг от друга и при этом сохранять целостность, подключая модули в конечный продукт, коим является интернет-банк.
|
|
|
|
|
|
2. Удаление подмодуля |
|
|
\ No newline at end of file |
|
|
Нам приходится отслеживать то какие именно модули включаются в интернет-банк, вносить изменения во взаимосвязанные модули подсистем синхронно, чтобы не нарушить целостность кода. Кроме того процесс осложняется наличием как минимум двух активных веток: **master** - основного ствола разработки и **текущей стабильной ветки**, в которую вносятся только исправления ошибок.
|
|
|
|
|
|
Типичная проблема, возникающая при использовании подобного сценария, это, как сделать так, чтобы иметь возможность рассматривать их как отдельные, всё же имея возможность использовать один модуль внутри другого.
|
|
|
|
|
|
Git решает эту задачу, используя **подмодули**. Подмодули позволяют содержать один Git-репозиторий как подкаталог другого Git-репозитория. Это даёт возможность клонировать ещё один репозиторий внутрь проекта, храня коммиты для вложенного репозитория отдельно.
|
|
|
|
|
|
## Начало использования подмодулей
|
|
|
|
|
|
Предположим, вы хотите добавить новую кастомизацию cust-ibank-fl-newbank в супер-проект. Первое, что требуется сделать, это клонировать внешний репозиторий cust-ibank-fl-newbank в подкаталог супер-репозитория ibank_root. Добавление внешних проектов в качестве подмодулей делается командой `git submodule add`:
|
|
|
```
|
|
|
>git submodule add git@source.isimplelab.com:ibank/cust-ibank-fl-newbank.git cust-ibank-fl-newbank
|
|
|
Initialized empty Git repository in ibank_root/cust-ibank-fl-newbank/.git/
|
|
|
remote: Counting objects: 3181, done.
|
|
|
remote: Compressing objects: 100% (1534/1534), done.
|
|
|
remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
|
|
|
Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done.
|
|
|
Resolving deltas: 100% (1951/1951), done.
|
|
|
```
|
|
|
После этого в суперрепозитории ibank_root будет изменён файл `.gitmodules`. Это конфигурационный файл, который содержит соответствие между URL проекта и локальным подкаталогом, в который был загружен подмодуль:
|
|
|
```
|
|
|
>type .gitmodules
|
|
|
[submodule "cust-ibank-fl-newbank"]
|
|
|
path = cust-ibank-fl-newbank
|
|
|
url = git@source.isimplelab.com:ibank/cust-ibank-fl-newbank.git
|
|
|
```
|
|
|
Теперь внутри проекта ibank_root в подкаталоге с именем cust-ibank-fl-newbank находится репозиторий cust-ibank-fl-newbank. Мы можем работать с ним как с обычным Git-репозиторием: вносить изменения и отправлять их в связанный удалённый репозиторий.
|
|
|
|
|
|
Если мы внесём изменения в этом подкаталоге и сделаем коммит, основной проект заметит, что HEAD в подмодуле был изменён, и зарегистрирует крайний хеш коммита в подмодуле.
|
|
|
Теперь нам нужно зафиксировать добавление подмодуля в суперрепозитории и протолкнуть изменения в удалённый репозиторий:
|
|
|
```
|
|
|
>cd ibank_root
|
|
|
|
|
|
>git commit -m 'Добавлена кастомизация NewBank'
|
|
|
[master 0550271] Добавлена кастомизация NewBank
|
|
|
2 files changed, 4 insertions(+), 0 deletions(-)
|
|
|
create mode 100644 .gitmodules
|
|
|
create mode 160000 cust-ibank-fl-newbank
|
|
|
|
|
|
>git push origin master
|
|
|
```
|
|
|
Таким образом, если теперь кто-то склонирует ibank_root, он сможет воссоздать окружение в точности.
|
|
|
|
|
|
## Клонирование проекта с подмодулями
|
|
|
|
|
|
Сейчас мы склонируем проект, содержащий подмодули. После получения такого проекта в вашей копии будут каталоги, содержащие подмодули, но без единого файла в них:
|
|
|
```
|
|
|
>git clone git@source.isimplelab.com:ibank/ibank_root.git
|
|
|
Initialized empty Git repository in ibank_root/.git/
|
|
|
remote: Counting objects: 6, done.
|
|
|
remote: Compressing objects: 100% (4/4), done.
|
|
|
remote: Total 6 (delta 0), reused 0 (delta 0)
|
|
|
Receiving objects: 100% (6/6), done.
|
|
|
```
|
|
|
Каталог cust-ibank-fl-newbank присутствует, но он пустой. Чтобы выкачать его содержимое необходимо выполнить команду:
|
|
|
```
|
|
|
>git submodule update --init --remote
|
|
|
Initialized empty Git repository in ibank_root/cust-ibank-fl-newbank/.git/
|
|
|
remote: Counting objects: 3181, done.
|
|
|
remote: Compressing objects: 100% (1534/1534), done.
|
|
|
remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
|
|
|
Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done.
|
|
|
Resolving deltas: 100% (1951/1951), done.
|
|
|
Submodule path 'cust-ibank-fl-newbank': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433'
|
|
|
```
|
|
|
Флаг `--init` используется для инициализации вашего локального файла конфигурации и получения изменений, до состояния, указанного в `.gitmodules`.
|
|
|
Флаг `--remote` автоматически обновляет вложенные репозитории до последей версии на указанной в `.gitmodules` ветке. В подавляющем большинстве случаев это именно то что вам нужно.
|
|
|
|
|
|
## Особенности работы с подмодулями
|
|
|
|
|
|
При использование подмодулей необходимо помнить, что команда
|
|
|
`git submodule update`, **возвращает определённую версию проекта, но не внутри ветви. Это называется состоянием с отделённым HEAD (detached HEAD) — это означает, что файл HEAD указывает на конкретный коммит, а не на символическую ссылку.**
|
|
|
|
|
|
Проблема в том, что теперь легко потерять изменения.
|
|
|
Если вы сделаете первоначальный submodule update, сделаете коммит в каталоге подмодуля, не создавая ветки для работы в ней, и затем вновь выполните git submodule update из основного проекта, Git затрёт ваши изменения в подмодуле без предупреждения.
|
|
|
Технически вы не потеряете проделанную работу, но у вас не будет ветки, указывающей на неё, так что восстановить её можно будет только зная хэш коммита.
|
|
|
Для предотвращения этой проблемы переключайтесь на ветку после клонирования суперпроекта командой:
|
|
|
```
|
|
|
>cd ibank_root
|
|
|
>git submodule foreach git checkout master
|
|
|
```
|
|
|
Либо создавайте ветвь, когда работаете в каталоге подмодуля с использованием команды `git checkout -b <имя ветки>`.
|
|
|
Когда вы сделаете обновление подмодуля командой submodule update в следующий раз, она откатит вашу работу, но у вас будет указатель для возврата назад. |