Как «git добавить» модифицированный подмодуль в основной модуль? - PullRequest
1 голос
/ 18 марта 2020

Я изменил, добавил, зафиксировал и передал изменения в подмодуль, затем поднялся в каталог основного модуля и запустил:

# git status
...
Changes not staged for commit:
...
modified:   deps/gr-d13 (modified content, untracked content)
...

# git add deps/gr-d13
(no errors)
# git status
...
Changes not staged for commit:
...
modified:   deps/gr-d13 (modified content, untracked content)
...

Точно так же, как и раньше. Мой субмодуль не был поставлен. Почему нет?

И основной, и подмодуль находятся в одной ветви.

1 Ответ

2 голосов
/ 18 марта 2020

Давайте начнем с погружения в глубокий конец бассейна. Это:

modified:   deps/gr-d13 (modified content, untracked content)

означает, что ваш суперпроект Git выполнил:

(cd deps/gr-d13; git status)

, чтобы узнать состояние хранилища субмодулей и когда это произошло В его рабочем дереве (подмодуле) есть файлы, которые были изменены, и файлы, которые не были отслежены.

Если вы хотите, чтобы эти файлы были зафиксированы, вам нужно самостоятельно войти в хранилище подмодуля и работать с ним. как и в случае с любым хранилищем Git. Просто помните, что в данный момент он находится в режиме detached HEAD , с определенной фиксацией c. Этот коммит может иметь или не иметь имя ветки, ассоциированное с ним. Если нет, запомните, что вам нужно сделать.

После того, как вы получите новый коммит в подмодуле, вы можете сделать так, чтобы суперпроект ссылался на этот новый коммит. Для этого вернитесь в суперпроект и запустите git add deps/gr-d13. Это скажет суперпроекту Git сделать (cd deps/gr-d13; git rev-parse HEAD), чтобы найти правильный коммит ha sh ID, а затем записать этот ha sh ID в индексе суперпроекта.

Background

Помните, что подмодуль - это не что иное, как второй Git репозиторий. Ваш (верхний уровень) Git репозиторий теперь является суперпроектом . В вашем суперпроекте каждый коммит, который вы делаете, перечисляет две вещи:

  • путь к имени хранилища субмодулей, в данном случае, deps/gr-d13
  • ха sh Идентификатор, который ваш суперпроект Git должен использовать, когда он:

    (cd $submodule; git checkout $hash)
    

    , чтобы заставить подмодуль Git находиться в режиме detached HEAD при именованном коммите.

(Суперпроект должен также иметь файл .gitmodules, который содержит информацию, необходимую новому клону суперпроекта для запуска команды git clone Это создает репозиторий подмодулей. Этот файл также должен быть в каждом коммите. Как только существует репозиторий подмодулей, Git больше не нуждается в файле .gitmodules для этой информации.)

Файлы, которые вы в вашем рабочем дереве отображаются , а не зафиксированные файлы. (Принятые файлы хранятся в специальном сжатом, доступном только для чтения формате Git, как часть снимка фиксации.) Как и в любом репозитории Git, когда вы извлекаете коммит, его файлы go в индекс для этого хранилища, и оттуда они копируются и расширяются в полезную форму, в рабочее дерево, чтобы вы могли просматривать и работать с ними.

В вашем суперпроекте нет коммитов подмодулей, он имеет га sh идентификаторов коммитов подмодулей. Однако у вашего рабочего дерева для репозитория суперпроектов есть каталог (или папка, если вы предпочитаете этот термин), который содержит .git 1 и рабочее дерево подмодуля. Это означает, что рабочее дерево подмодуля является подкаталогом рабочего дерева суперпроекта.

Вы можете в любое время использовать:

cd deps/gr-d13

, чтобы самостоятельно войти в хранилище подмодуля. Если вы сделаете это, вы можете работать с ним так же, как вы работаете с любым хранилищем. Он имеет коммиты, HEAD, индекс и рабочее дерево, как и любой репозиторий. Единственное, что особенного в этом репозитории подмодулей, - это то, что есть внешний репозиторий, который иногда (когда ему сообщают) делает cd в подмодуле и запускает git checkout <hash>, чтобы снова принудительно перевести его в режим отсоединенного HEAD при указанной фиксации.


1 В старых версиях Git этот .git будет действительным каталогом, содержащим базу данных хранилища подмодуля (т. Е. Все, что не является рабочим деревом) , В современном Git этот .git будет простым файлом. Git теперь «поглощает» базу данных хранилища субмодулей в суперпроект, в каталоге под .git, содержащим данные суперпроекта.


Работа с субмодулями и push / fetch

Работа с обычным репозиторием Git часто немного сложна, потому что Git является распределенной системой контроля версий. Это означает, что вам нужно не только управлять вашим репозиторием, вы должны беспокоиться о каком-то другом репозитории, например, в GitHub, который в основном содержит те же коммиты, но имеет собственные имена веток.

Другими словами, для работы с одним репозиторием Git вы на самом деле работаете с двумя Git репозиториями: вашим и еще одним в origin. Ваша рабочая нагрузка удваивается (или хуже, поскольку они только слабо скоординированы).

Когда вы добавляете подмодуль в микс, ваша рабочая нагрузка снова удваивается (или хуже), потому что подмодуль равен a Git хранилище, и, как таковое, оно также имеет origin. Итак, теперь вы работаете с четырьмя Git репозиториями. Ваш и тот, кто в происхождении, согласованы между собой; и вы должны согласовать свои с вашим хранилищем подмодулей. Но ваш подмодульный репозиторий также согласован с его origin.

Поскольку ваш суперпроектный репозиторий продолжает отсоединять HEAD в подмодуле, фактически выполняя любую работу в подмодуле требуется ввести его, повторно присоединить HEAD к одному из его имен ветвей (или создать новое имя ветки, если необходимо), и только затем выполнять работу и делать новые коммиты. После того, как вы сделали эти новые коммиты, вы можете протестировать их с вашим суперпроектом, возможно, делая коммиты в суперпроекте. Если они не сработают, вам может потребоваться отменить все эти коммиты.

(Вы можете, если хотите, работать с незафиксированными изменениями как в репроектах суперпроекта, так и в субмодуле. В зависимости от ваших задач и требований , это может быть проще.)

В любом случае, если коммиты подмодуля существуют и являются правильными, вы можете использовать git push из субмодуля для отправки этих коммитов в origin. Вы можете сделать это до или после обновления вашего суперпроекта до , используя эти коммиты. Просто помните, что если вы сначала обновите свой суперпроект, вы должны быть уверены, что git push из субмодуля, прежде чем git push из суперпроекта. Причина в том, что любому, кто хочет получить ваш новый коммит суперпроекта, понадобится и ваш новый коммит субмодуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...