Предполагая, что в репозитории подмодуля есть коммит, который вы хотите использовать (в отличие от коммита, на который ссылается текущее состояние суперпроекта), есть два способа сделать это.
Первый требует, чтобы вы уже знали коммит из подмодуля, который вы хотите использовать. Он работает «изнутри наружу», напрямую настраивая подмодуль, затем обновляя суперпроект. Второй работает извне, находя коммит супер-проекта, который изменил подмодуль, а затем сбрасывает индекс супер-проекта для ссылки на другой коммит суб-модуля.
Внутри, снаружи
Если вы уже знаете, какой коммит вы хотите использовать для подмодуля, cd
для субмодуля, проверьте нужный вам коммит, затем git add
и git commit
верните его в супер-проект.
Пример:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
Упс, кто-то сделал коммит суперпроекта, который ссылается на неопубликованный коммит в подмодуле sub
. Каким-то образом мы уже знаем, что хотим, чтобы субмодуль находился в коммите 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
. Отправляйся туда и посмотри прямо.
Оформить заказ в подмодуле
$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to '5d5a3ee314476701a20f2c6ec4a53f88d651df6c' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
git checkout -b <new_branch_name>
HEAD is now at 5d5a3ee... quux
$ cd ..
Так как мы проверяем коммит, это приводит к отсоединению HEAD в подмодуле. Если вы хотите убедиться, что в подмодуле используется ветвь, то используйте git checkout -b newbranch <commit>
, чтобы создать и извлечь ветку при фиксации или извлекать нужную ветку (например, одну с желаемой фиксацией на кончике).
Обновление Супер-проекта
Оформление заказа в подмодуле отражается в суперпроекте как изменение рабочего дерева. Таким образом, нам нужно поэтапно изменить индекс супер-проекта и проверить результаты.
$ git add sub
Проверить результаты
$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Обновление подмодуля было тихим, потому что подмодуль уже находится в указанной фиксации. Первый diff показывает, что индекс и рабочее дерево совпадают. Третья разница показывает, что единственное поэтапное изменение - это перемещение подмодуля sub
в другой коммит.
Commit
git commit
Это фиксирует фиксированную запись субмодуля.
Снаружи, в
Если вы не уверены, какой коммит вам следует использовать из подмодуля, вы можете посмотреть историю в суперпроекте, чтобы вам было легче. Вы также можете управлять сбросом напрямую из супер-проекта.
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
Это та же самая ситуация, что и выше. Но на этот раз мы сосредоточимся на том, чтобы починить его из суперпроекта, а не заглядывать в подмодуль.
Найти Странствующий коммит Супер-проекта
$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
ОК, похоже, что все пошло не так в ce5d37c
, поэтому мы восстановим подмодуль из его родителя (ce5d37c~
).
В качестве альтернативы, вы можете взять коммит субмодуля из текста патча (5d5a3ee314476701a20f2c6ec4a53f88d651df6c
) и использовать вместо этого описанный выше процесс «изнутри, снаружи».
Оформить заказ в Супер-проекте
$ git checkout ce5d37c~ -- sub
Это сбрасывает запись подмодуля для sub
к тому, что было при коммите ce5d37c~
в суперпроекте.
Обновление подмодуля
$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'
Обновление субмодуля прошло нормально (это указывает на отключенную головку).
Проверить результаты
$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Первый diff показывает, что sub
теперь то же самое в ce5d37c~
. Вторая разница показывает, что индекс и рабочее дерево совпадают. Третий отчет показывает, что единственное поэтапное изменение - это перемещение подмодуля sub
в другой коммит.
Commit
git commit
Это фиксирует фиксированную запись субмодуля.