Git ошибка заголовка субмодуля "не является деревом"

У меня есть проект с подмодулем, который указывает на недопустимый коммит: компиляция субмодуля оставалась локальной, и когда я пытаюсь извлечь ее из другого репо, я получаю:

$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'

Я знаю, что должно быть HEAD подмодуля, есть ли способ изменить это локально, не отталкиваясь от репо, у которого есть commit 2d7cfbd09fc96c04c4c41148d44ed7778add6b43?

Я не уверен, если я буду ясно... здесь похожая ситуация Я нашел.

Ответ 1

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

Первое требует, чтобы вы уже знали фиксацию из подмодуля, который вы хотите использовать. Он работает от "внутри, вне", напрямую регулируя подмодуль, а затем обновляя суперпроект. Второй работает из "снаружи, в", обнаруживая суперпроектную фиксацию, которая модифицировала подмодуль, а затем перезаписывала индекс суперпроекта, чтобы ссылаться на другой компромисс подмодуля.

Внутри, выход

Если вы уже знаете, какой фиксатор вы хотите использовать подмодуль, cd для подмодуля, проверьте комманду, которую хотите, а затем git add и git commit обратно в суперпроекте.

Пример:

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

К сожалению, кто-то сделал суперпроектный коммит, который ссылается на неопубликованное коммитирование в подмодуле sub. Так или иначе, мы уже знаем, что мы хотим, чтобы подмодуль был в commit 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 показывает, что индекс и рабочая точка одинаковы. Третий diff показывает, что единственное поэтапное изменение перемещает подмодуль sub к другому фиксации.

Зафиксировать

git commit

Это фиксирует запись с фиксированным подмодулем.


Снаружи, In

Если вы не уверены, какую фиксацию вы должны использовать из подмодуля, вы можете посмотреть историю в суперпроекте, чтобы вести вас. Вы также можете управлять reset непосредственно из суперпроекта.

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

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

Найти Супер-проект Errant Commit

$ 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

Этот reset элемент подмодуля для sub соответствует тому, что он был в commit ce5d37c~ в суперпроекте.

Обновить подмодуль

$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'

Обновление подмодуля прошло нормально (это указывает на отсоединенную HEAD).

Проверить результаты

$ 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 к другому фиксации.

Зафиксировать

git commit

Это фиксирует запись с фиксированным подмодулем.

Ответ 2

попробуйте следующее:

git submodule sync
git submodule update

Ответ 3

Эта ошибка может означать, что в подмодуле отсутствует коммит. То есть в репозитории (A) имеется подмодуль (B). A хочет загрузить B так, чтобы он указывал на определенную фиксацию (в B). Если эта фиксация каким-то образом отсутствует, вы получите эту ошибку. Одна из возможных причин: ссылка на фиксацию была нажата в A, но фактическая фиксация не была нажата из B. Поэтому я начал там.

Меньше вероятность, есть проблема с разрешениями, и фиксация не может быть вытащена (возможно, если вы используете git + ssh).

Убедитесь, что пути подмодулей выглядят нормально в .git/config и .gitmodules.

Последнее, что нужно попробовать - внутри каталога подмодулей: git reset HEAD --hard

Ответ 4

Возможная причина

Это может произойти, если:

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

например. произошло нечто подобное:

$ cd submodule
$ emacs my_source_file  # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"

Должен иметь подмодуль, нажатый в этот момент.

$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master

В результате недостающие коммиты не могут быть найдены удаленным пользователем, поскольку они все еще находятся на локальном диске.

Решение

Сообщите человеку, который модифицировал подмодуль, чтобы нажать, т.е.

$ cd submodule
$ git push

Ответ 5

Я получил эту ошибку, когда я сделал:

$ git submodule update --init --depth 1

но коммит в родительском проекте указывал на более ранний коммит.

Удаление папки submodule и запуск:

$ git submodule update --init

НЕ решил проблему. Я удалил репо и попробовал снова без флага глубины, и это сработало.

Эта ошибка происходит в Ubuntu 16.04 git 2.7.4, но не в Ubuntu 18.04 git 2.17, TODO находит точную фиксацию фиксации или версию.

Ответ 6

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

Ответ 7

Этот ответ предназначен для пользователей SourceTree с ограниченным интерфейсом git.

Откройте проблемный подмодуль из проекта git (суперпроект).

Выбрано и убедитесь, что флажок "Получить все теги" отмечен.

Rebase вытащите ваш проект git.

Это позволит решить проблему "ссылка не на дерево" 9 из десяти раз. Это 1 раз, когда это не будет, это терминальное исправление, как описано в верхнем ответе.

Ответ 8

В любом случае ваша субмодульная история благополучно сохраняется в подмодуле git.

Итак, почему бы просто не удалить подмодуль и не добавить его снова?

В противном случае вы попытались вручную отредактировать HEAD или refs/master/head в рамках подмодуля .git

Ответ 9

Чтобы убедиться, попробуйте обновить двоичные файлы git.

GitHub для Windows имеет версию git version 1.8.4.msysgit.0, которая в моем случае была проблемой. Обновление было решено.

Ответ 10

В моем случае ни один из ответов выше не решает проблему, даже если они хорошие ответы. Поэтому я отправляю свое решение (в моем случае есть два клиента git, клиент A и B):

  • перейти к подмодулю dir:

    cd sub
    
  • проверка:

    git checkout master
    
  • rebase к коду фиксации, который оба клиента могут видеть

  • вернитесь к родительскому директорию:

  • передать мастеру

  • измените на другой клиент, повторите rebase.

  • наконец, он отлично работает! Возможно, потеряйте пару коммитов, но он работает.

  • FYI, не пытайтесь удалить ваш подмодуль, он останется там .git/modules и не сможет прочитать этот подмодуль еще раз, если не будет реактивный локальный.

Ответ 11

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

Шаги, которые я выполнил, чтобы удалить подмодуль, вдохновленный https://gist.github.com/kyleturner/1563153:

  • Запустить git rm --cached
  • Удалите соответствующие строки из файла .gitmodules.
  • Удалить соответствующий раздел из .git/config.
  • Удалите теперь необработанные файлы подмодулей.
  • Удалить каталог .git/modules/

Опять же, это может быть полезно, если все, что вам нужно, это снова указать на голову подмодуля, и вы не усложнили ситуацию, если не нужно сохранять локальную копию подмодуля. Предполагается, что у вас есть подмодуль "право" как свое собственное репо, где бы оно ни происходило, и вы просто хотите вернуться к правильному включению его в качестве подмодуля.

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

Ответ 12

Просто наткнулся на эту проблему, и ни одно из этих решений не помогло мне. То, что оказалось решением моей проблемы, на самом деле намного проще: обновить Git. Мой был 1.7.1, и после того, как я обновил его до 2.16.1 (последний), проблема ушла без следа! Думаю, я оставляю это здесь, надеюсь, это кому-нибудь поможет.

Ответ 13

Ваша ветка может быть не в курсе, простое решение, но попробуйте git fetch