Close

Подмодули Git

Подмодули Git позволяют сохранить репозиторий git в качестве подкаталога другого репозитория git. Подмодуль Git — это просто ссылка на другой репозиторий в определенный момент времени. Благодаря подмодулям в репозиторий Git можно включить историю версий внешнего кода и отслеживать ее.


Что такое подмодуль git?


Часто репозиторий кода зависит от внешнего кода, который можно включить в репозиторий различными способами. Вы можете напрямую скопировать и вставить внешний код в главный репозиторий, но при этом потеряете доступ ко всем вышестоящим изменениям во внешнем репозитории. Можно пойти другим путем и воспользоваться системой управления пакетами для конкретного языка, такой как Ruby Gems или NPM, однако в этом случае придется заниматься установкой и управлением версиями во всех местах развертывания исходного кода. Оба предложенных метода не позволяют отслеживать правки и изменения во внешнем репозитории.

Подмодуль git — это запись в хост-репозитории git, которая указывает на конкретный коммит в другом внешнем репозитории. Подмодули очень статичны: с их помощью можно отслеживать определенные коммиты, но не ветки или ссылки git. Кроме того, они не обновляются автоматически при обновлении хост-репозитория. Когда вы добавляете подмодуль в репозиторий, создается новый файл .gitmodules, в котором содержатся метаданные о сопоставлении URL-адреса проекта подмодуля с локальным каталогом. Если хост-репозиторий содержит несколько подмодулей, в файл .gitmodules будет включена отдельная запись для каждого подмодуля.

Когда следует использовать подмодуль git?


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

  • Внешний компонент или подпроект изменяются слишком быстро, или предстоящие изменения могут нарушить работу API. В этом случае можно заблокировать код для конкретного коммита в целях безопасности.
  • У вас есть компонент, который обновляется довольно редко, и вы хотите отслеживать его в качестве зависимости поставщика.
  • Вы делегируете выполнение части проекта другим лицам и хотите интегрировать их работу в определенное время или в конкретном релизе. Это полезно только в том случае, когда обновления происходят не слишком часто.
базы данных
Связанные материалы

Перемещение полного репозитория Git

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите Git с помощью Bitbucket Cloud

Основные команды для работы с подмодулями git


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

С помощью команды git submodule add можно добавить новый подмодуль в существующий репозиторий. Ниже приводится пример, в котором создается пустой репозиторий и изучаются подмодули git.

mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/

Эта последовательность команд создает новый каталог git-submodule-demo, выполняет переход в этот каталог и инициализирует его в качестве нового репозитория. Теперь добавим подмодуль в этот новый репозиторий.

$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.

Команда git submodule add принимает в качестве параметра URL-адрес, который указывает на репозиторий git. Мы добавили подмодуль awesomelibrary, который система Git сразу же клонирует. Теперь проверим текущее состояние репозитория с помощью команды git status

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

 new file:   .gitmodules
 new file:   awesomelibrary

В репозитории появилось два новых элемента: файл .gitmodules и каталог awesomelibrary. Если изучить содержимое файла .gitmodules, можно увидеть информацию о сопоставлении для нового подмодуля.

[submodule "awesomelibrary"]
 path = awesomelibrary
 url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 awesomelibrary

Клонирование подмодулей Git

git clone /url/to/repo/with/submodules
git submodule init
git submodule update

Команда git submodule init

По умолчанию команда git submodule init копирует информацию о сопоставлении из файла .gitmodules в локальный файл ./.git/config. Это может показаться избыточным и вызвать сомнения в полезности команды git submodule init. Однако команда git submodule init имеет расширенные функциональные возможности. В частности, она принимает заданный в явном виде список имен модулей. В этом случае рабочий процесс активирует только определенные подмодули, необходимые для работы с репозиторием. Это может быть полезно, если в репозитории много подмодулей, но для текущей работы не требуется извлекать их все.

Рабочие процессы подмодулей

После надлежащей инициализации и обновления подмодулей в родительском репозитории их можно использовать точно так же, как автономные репозитории. Это означает, что у подмодулей есть собственные ветки и история. После того как вы внесли изменения в подмодуль, важно опубликовать их и обновить ссылку на подмодуль в родительском репозитории. Продолжим работу с подмодулем awesomelibrary и внесем некоторые изменения:

cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
  (use "git add <file>..." to include in what will be committed)

 new_awesome.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
 1 file changed, 1 insertion(+)
 create mode 100644 new_awesome.txt
$ git branch
  main
* new_awesome

Мы перешли в каталог подмодуля awesomelibrary, затем создали новый текстовый файл new_awesome.txt с некоторым содержимым, добавили этот файл в подмодуль и выполнили коммит. Теперь переключим каталог, чтобы вернуться в родительский репозиторий, и проверим текущее состояние родительского репозитория.

cd ..
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

 modified:   awesomelibrary (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

Выполнив команду git status, мы увидим, что родительскому репозиторию известно о новых коммитах в подмодуле awesomelibrary. При этом речь не идет о деталях обновлений, поскольку за них отвечают репозитории подмодулей. Родительский репозиторий занимается только связью подмодуля с коммитом. Теперь можно снова обновить родительский репозиторий, выполнив команды git add и git commit для подмодуля, чтобы подытожить работу с локальным содержимым. Если вы работаете в командной среде, важно после этого выполнить команду git push для отправки обновлений подмодуля и родительского репозитория.

При работе с подмодулями часто возникают ошибки и путаница из-за того, что разработчики забывают отправить обновления для удаленных пользователей. Если взглянуть на работу с подмодулем awesomelibrary, которую мы только что проделали, можно увидеть, что мы отправили обновления только в родительский репозиторий. Если другой разработчик захочет получить последнюю версию родительского репозитория, в котором будет указатель на коммит awesomelibrary, он не сможет получить изменения, потому что мы забыли отправить подмодуль. Это приведет к сбою в работе локального репозитория удаленного разработчика. Чтобы избежать такого сценария, всегда отправляйте подмодуль и родительский репозиторий командой push после выполнения коммитов.

Заключение


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


Поделитесь этой статьей

Рекомендуемые статьи

Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up