#Что означает проблема
Подмодуль Git — это отдельный репозиторий внутри проекта. Родитель хранит не все его файлы, а ссылку на конкретный коммит (gitlink). Поэтому после переключения ветки или обновления подмодуля родитель может показать modified: libs/example (new commits), даже если обычные git diff внутри подмодуля не видят незакоммиченных строк.
#Как отличить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Подмодуль находится на другом коммитеВнешний инструмент или ручной checkout передвинул HEAD подмодуля. | git submodule status выводит + перед SHA; --cached показывает другой. | Сравнить два SHA, затем решить, какой нужен. |
| Родительский проект ожидает конкретную версиюПроверенный коммит подмодуля уже записан в текущем коммите основного проекта. | git submodule status --cached показывает эталон, а HEAD — другую версию. | После копии изменений выполнить штатное submodule update. |
| Рабочая директория подмодуля измененаПомимо нового SHA есть незакоммиченные или неотслеживаемые файлы внутри подмодуля. | git -C libs/example status --short выводит M или ??. | Сохранить работу отдельно, не скрывать её настройкой ignore. |
#Пошаговая диагностика и решение
- Проверьте состояние родительского проектаОткройте корень проекта в VS Code → «Терминал» → «Создать терминал». Запустите
git status -sbиgit submodule status. Найдите путь проблемного подмодуля, напримерlibs/example. Символ+перед коммитом означает, что проверенный сейчас коммит подмодуля не совпадает с записанным в индексе родительского проекта;-означает неинициализированный подмодуль,U— конфликт. Перед остальными командами выполнитеgit --version: в ответ должна появиться установленная версия Git. Если терминал сообщает, чтоgitне найден, проверьте установку Git и доступность команды в этом терминале; не продолжайте операции наугад. - Сравните ожидаемую и текущую версииЗапустите
git submodule status --cachedиgit submodule status. В первой команде показывается зафиксированный в индексе SHA, во второй — фактически проверенный. Сравните путь и хеши посимвольно. Никакие файлы эти команды не меняют. Если SHA одинаковы, ищите незакоммиченные файлы, другую вложенную папку или изменения только в рабочем дереве. - Узнайте, нет ли локальной работы внутри подмодуляОткройте папку подмодуля в проводнике VS Code или выполните
git -C libs/example status -sb, заменивlibs/exampleна фактический относительный путь. Если показаныmodified,untrackedили собственные локальные коммиты, сохраните их в отдельной ветке этого подмодуля и копии; не выполняйтеgit submodule update --forceи не очищайте папку. Если статус чистый, переходите к сравнению версий. - Посмотрите различия коммитов вместо различий файловВ родительском репозитории выполните
git diff --submodule=log -- libs/exampleиgit submodule summary -- libs/example. Вы увидите диапазон коммитов либо краткую сводку. Если diff пуст, но статус сообщает о новом коммите, проверьте, не было ли изменение уже добавлено в индекс:git diff --cached --submodule=log -- libs/example. - Если другой коммит подмодуля оказался случайным, верните ожидаемыйТОЛЬКО после проверки, что внутри подмодуля нет несохранённых файлов или уникальных незакреплённых коммитов, выполните в корне родительского проекта
git submodule update --init -- libs/example. Команда получает или выбирает коммит, записанный в родительском проекте, и может изменить файлы внутри подмодуля. Если нужный коммит отсутствует на сервере, не выбирайте другой случайный — попросите автора предоставить его. - Если новая версия подмодуля нужна проекту, сохраните изменение указателяВначале подтвердите с командой, что новый коммит подмодуля действительно опубликован в доступном удалённом хранилище и проходит тесты. После этого в корне родительского проекта выполните
git add -- libs/example, посмотритеgit diff --cached --submodule=logи создайте коммит изменения указателя. Обычныйgit addподмодуля НЕ отправляет его локальный коммит на сервер подмодуля; его нужно публиковать в собственном репозитории отдельно. - Проверяйте и собирайте проект с закреплённым SHAПосле решения выполните
git status -sb,git submodule status --cachedиgit submodule status. Хеши должны совпадать, если вы вернули зафиксированную версию. Если новая версия была целенаправленно записана в индекс, после коммита и повторной проверки её хеш должен быть закреплён в основном проекте. Затем запустите штатные тесты приложения.
#Команды для проверки и исправления
--cached показывает записанный в индексе коммит подмодуля, а не проверенный в файловой системе.git status -sbgit submodule statusgit submodule status --cachedlibs/example нужно заменить своим в обеих командах. -C запускает Git внутри указанной папки, не меняя ваш текущий каталог.git -C libs/example status -sbgit diff --submodule=log -- libs/examplegit submodule update --init -- libs/exampleКоманда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
git add -- libs/examplegit diff --cached --submodule=log -- libs/exampleКоманда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
#Как проверить результат и что делать, если не помогло
Нормальное состояние: git submodule status не содержит + для непреднамеренно изменённых подмодулей, а нужный SHA закреплён коммитом родительского проекта. Если восстановление невозможно из-за отсутствующего коммита на сервере, запросите у автора подмодуля публикацию нужного SHA — не подменяйте его автоматически.