Введение
Git submodules (подмодули) – это мощная функция, позволяющая включать внешние репозитории в ваши собственные проекты. Эта возможность особенно полезна, когда ваш проект зависит от внешних библиотек или компонентов, которые поддерживаются отдельно. Используя подмодули, вы можете поддерживать эти зависимости в актуальном состоянии и эффективно управлять ими.
В этом руководстве вы узнаете, как проверить статус Git submodules (подмодулей) в вашем репозитории, понять, какие изменения были внесены в них, и убедиться, что они правильно синхронизированы с их исходными репозиториями.
Создание репозитория с подмодулями
Давайте начнем с создания примерного репозитория с подмодулем, чтобы иметь практическую среду для обучения.
Настройка основного репозитория
Сначала мы создадим новый основной репозиторий, в который добавим наш подмодуль. Откройте терминал и выполните следующие команды:
cd ~/project
mkdir main-repo
cd main-repo
git init
Вы должны увидеть вывод, аналогичный следующему:
Initialized empty Git repository in /home/labex/project/main-repo/.git/
Теперь давайте создадим простой файл в нашем основном репозитории:
echo "## Main Repository" > README.md
git add README.md
git commit -m "Initial commit"
Вывод должен указывать, что вы создали свой первый коммит:
[master (root-commit) xxxxxxx] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
Добавление подмодуля
Теперь давайте добавим подмодуль в наш основной репозиторий. Для этого руководства мы будем использовать небольшой публичный репозиторий в качестве нашего подмодуля:
git submodule add https://github.com/libgit2/libgit2-backends.git libs/libgit2-backends
Эта команда клонирует репозиторий и добавляет его в качестве подмодуля в каталог libs/libgit2-backends. Вы должны увидеть вывод, аналогичный следующему:
Cloning into '/home/labex/project/main-repo/libs/libgit2-backends'...
remote: Enumerating objects: xxx, done.
remote: Counting objects: 100% (xxx/xxx), done.
remote: Compressing objects: 100% (xxx/xxx), done.
remote: Total xxx (delta xx), reused xxx (delta xx), pack-reused xxx
Receiving objects: 100% (xxx/xxx), xxx KiB | xxx KiB/s, done.
Resolving deltas: 100% (xxx/xxx), done.
Понимание изменений
Когда вы добавляете подмодуль, Git создает файл .gitmodules в вашем репозитории, который отслеживает URL и путь подмодуля. Давайте посмотрим на этот файл:
cat .gitmodules
Вы должны увидеть содержимое, аналогичное следующему:
[submodule "libs/libgit2-backends"]
path = libs/libgit2-backends
url = https://github.com/libgit2/libgit2-backends.git
Давайте также проверим статус нашего репозитория:
git status
Вы должны увидеть вывод, указывающий, что были добавлены как новый файл .gitmodules, так и каталог подмодуля:
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: .gitmodules
new file: libs/libgit2-backends
Давайте закоммитим эти изменения, чтобы завершить настройку:
git commit -m "Add libgit2-backends submodule"
Теперь у вас должен быть репозиторий с успешно настроенным подмодулем.
Проверка статуса подмодулей
Теперь, когда у нас есть репозиторий с подмодулем, давайте узнаем, как проверить статус подмодуля и понять, что означает вывод.
Базовая проверка статуса подмодуля
Git предоставляет специальную команду для проверки статуса подмодулей. Выполните следующую команду:
cd ~/project/main-repo
git submodule status
Вы должны увидеть вывод, аналогичный следующему:
+abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (v1.0.0-123-gabcdef12)
Давайте разберемся, что означает этот вывод:
Первый символ может быть одним из следующих:
+: указывает, что зафиксированный коммит подмодуля отличается от того, что зарегистрирован в основном репозитории(пробел): указывает, что подмодуль синхронизирован с тем, что зарегистрировано-: указывает, что подмодуль не инициализированU: указывает на конфликты слияния в подмодуле
Буквенно-цифровая строка — это хэш коммита текущего коммита, зафиксированного в подмодуле.
Путь показывает, где находится подмодуль в вашем репозитории.
Текст в скобках показывает дополнительную информацию о зафиксированном коммите, например, теги или имена веток.
Подробная информация о подмодуле
Для получения более подробной информации о ваших подмодулях вы можете использовать следующую команду:
git submodule
Это покажет информацию, аналогичную команде status, но в другом формате.
Использование Git Status для просмотра изменений в подмодуле
Вы также можете использовать стандартную команду git status для просмотра изменений в подмодулях:
git status
Если в подмодуле нет изменений, вы не увидите упоминания о нем в выводе. Однако, если есть изменения в зафиксированном коммите подмодуля или в файлах внутри подмодуля, git status покажет эту информацию.
Изучение содержимого подмодуля
Давайте изучим содержимое нашего подмодуля:
cd ~/project/main-repo
ls -la libs/libgit2-backends/
Вы увидите файлы из репозитория libgit2-backends. Обратите внимание, что подмодуль по сути является полным репозиторием Git внутри вашего основного репозитория. Вы можете убедиться в этом, проверив наличие каталога .git:
ls -la libs/libgit2-backends/.git
Вы можете не увидеть каталог .git напрямую, а скорее файл, который указывает на фактические данные репозитория Git, хранящиеся в каталоге .git/modules вашего основного репозитория. Именно так Git управляет подмодулями.
Понимание ссылки на подмодуль
Основной репозиторий хранит ссылку на определенный коммит в репозитории подмодуля. Эта ссылка — то, что Git использует, чтобы знать, какую версию подмодуля следует зафиксировать при клонировании вашего репозитория или обновлении подмодуля.
Давайте посмотрим коммит, на который ссылается наш основной репозиторий:
cd ~/project/main-repo
git ls-files --stage libs/libgit2-backends
Вывод покажет хэш коммита, который является конкретным коммитом подмодуля, который отслеживает основной репозиторий.
Обновление подмодулей
Одна из распространенных задач при работе с подмодулями — это поддержание их в актуальном состоянии с их удаленными репозиториями. Давайте узнаем, как обновить наш подмодуль.
Инициализация и обновление подмодулей
Если вы только что клонировали репозиторий, который содержит подмодули, вам нужно будет инициализировать и обновить их. Для нашего существующего репозитория мы можем продемонстрировать этот процесс с помощью:
cd ~/project/main-repo
git submodule init
git submodule update
Команда init инициализирует конфигурацию ваших подмодулей, а команда update извлекает данные и фиксирует коммит, указанный в вашем основном репозитории.
Вы также можете объединить эти команды:
git submodule update --init
Обновление подмодулей до последней удаленной версии
Если вы хотите обновить подмодуль до последнего коммита в его удаленном репозитории, вы можете использовать:
cd ~/project/main-repo
git submodule update --remote libs/libgit2-backends
Эта команда извлекает последние изменения из удаленного репозитория и обновляет подмодуль. Вы должны увидеть вывод, указывающий, что Git извлекает изменения.
После выполнения этой команды давайте проверим статус подмодуля:
git submodule status
Вы заметите, что вывод теперь показывает знак плюс (+) в начале, указывающий на то, что зафиксированный коммит подмодуля отличается от того, что записано в основном репозитории:
+abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (origin/HEAD)
Чтобы подтвердить изменения в вашем основном репозитории, выполните:
git status
Вы должны увидеть вывод, указывающий на то, что подмодуль был изменен:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: libs/libgit2-backends (new commits)
Фиксация обновленной ссылки на подмодуль
Чтобы записать обновленное состояние подмодуля в вашем основном репозитории, вам нужно добавить и зафиксировать изменения:
git add libs/libgit2-backends
git commit -m "Update libgit2-backends submodule to latest version"
Вывод должен указывать, что вы успешно зафиксировали новую ссылку на подмодуль.
Проверка обновленного статуса
После фиксации обновленной ссылки на подмодуль давайте снова проверим статус:
git submodule status
Вывод больше не должен иметь знака плюс в начале, указывая на то, что подмодуль теперь синхронизирован с тем, что записано в основном репозитории:
abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (origin/HEAD)
Понимание опций обновления подмодуля
Команда git submodule update имеет несколько опций, которые управляют тем, как выполняются обновления:
--remote: Обновить до последнего коммита в удаленной ветке отслеживания--merge: Слить изменения, если текущая ветка отстает от удаленной--rebase: Перебазировать изменения, если текущая ветка отстает от удаленной--recursive: Обновить также вложенные подмодули
Для большинства базовых случаев использования достаточно git submodule update --remote.
Работа с изменениями в подмодулях
Иногда вам нужно работать с изменениями внутри подмодуля. На этом шаге мы узнаем, как вносить изменения в подмодули и управлять ими.
Переход в подмодуль
Чтобы работать с подмодулем, вам нужно перейти в его каталог:
cd ~/project/main-repo/libs/libgit2-backends
Отсюда вы можете использовать стандартные команды Git для просмотра информации о репозитории подмодуля:
git status
git log -3 --oneline
Команда git status показывает текущее состояние репозитория подмодуля, а git log показывает последние коммиты.
Внесение изменений в подмодуль
Давайте внесем простое изменение в файл в подмодуле. Сначала создадим новый файл:
echo "## My notes on libgit2-backends" > NOTES.md
Теперь давайте проверим статус нашего изменения:
git status
Вы должны увидеть вывод, указывающий на то, что у вас есть неотслеживаемый файл:
Untracked files:
(use "git add <file>..." to include in what will be committed)
NOTES.md
Давайте добавим и зафиксируем это изменение в подмодуле:
git add NOTES.md
git commit -m "Add notes file"
Вы должны увидеть вывод, подтверждающий ваш коммит в подмодуле.
Проверка статуса из основного репозитория
Теперь давайте вернемся в основной репозиторий и проверим статус:
cd ~/project/main-repo
git status
Вы должны увидеть вывод, указывающий на то, что подмодуль был изменен:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: libs/libgit2-backends (new commits)
Фиксация изменений подмодуля в основном репозитории
Чтобы записать новое состояние подмодуля в вашем основном репозитории, вам нужно добавить и зафиксировать изменения:
git add libs/libgit2-backends
git commit -m "Update libgit2-backends with notes file"
Вывод должен указывать, что вы успешно зафиксировали новую ссылку на подмодуль.
Просмотр подробных изменений подмодуля
Чтобы увидеть более подробную информацию об изменениях в подмодулях, вы можете использовать:
git diff --submodule
Эта команда показывает диапазон коммитов, которые были добавлены или удалены в каждом измененном подмодуле.
Резюме работы с изменениями в подмодулях
При работе с изменениями в подмодуле помните этот рабочий процесс:
- Перейдите в каталог подмодуля
- Внесите и зафиксируйте изменения в подмодуле
- Вернитесь в основной репозиторий
- Добавьте и зафиксируйте обновленную ссылку на подмодуль
Этот двухэтапный процесс фиксации (сначала в подмодуле, затем в основном репозитории) необходим для правильного отслеживания изменений в подмодулях.
Резюме
В этом руководстве вы узнали, как работать с подмодулями Git, уделяя основное внимание проверке их статуса и внесению обновлений. Вот что вы сделали:
- Создали основной репозиторий и добавили в него подмодуль
- Узнали, как проверять статус подмодулей с помощью различных команд Git
- Обновили подмодуль до последней версии из его удаленного репозитория
- Внесли изменения в подмодуль и правильно отследили эти изменения в основном репозитории
Подмодули Git предоставляют мощный способ включения внешних репозиториев в ваши проекты, позволяя эффективно управлять зависимостями. Понимая, как проверять их статус и управлять обновлениями, вы можете гарантировать, что ваш проект остается правильно синхронизированным со своими зависимостями.
Основные команды, которые следует запомнить:
git submodule status- Проверить текущий статус подмодулейgit submodule update --remote- Обновить подмодули до их последних версийgit add <submodule-path>- Зафиксировать изменения в ссылке на подмодульgit diff --submodule- Просмотреть подробные изменения в подмодулях
С этими навыками вы сможете эффективно управлять репозиториями Git, которые включают внешний код через подмодули.



