Git submodule head' reference is not a tree ' ошибка

у меня есть проект с подмодулем, который указывает на недопустимую фиксацию: фиксация подмодуля осталась локальной, и когда я пытаюсь получить ее из другого РЕПО, я получаю:

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

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

Я не уверен, что я ясно выражаюсь... вот аналогичная ситуация я нашел.

12 ответов


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

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

Внутри, Из

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

пример:

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

Oops, кто-то сделал супер-проект commit, который ссылается на неопубликованный commit в подмодуле 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 ..

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

это фиксирует запись фиксированного подмодуля.


Снаружи, В

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

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

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

найти странствующий 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

это сброс записи подмодуля для 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

первая разница показывает, что sub сейчас же ce5d37c~. Второе различие показывает, что индекс и рабочее дерево одинаковы. Третий diff показывает только поэтапное изменение перемещает sub подмодуль для другой фиксации.

фиксация

git commit

это фиксирует запись фиксированного подмодуля.


попробуйте это:

git submodule sync
git submodule update

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

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

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

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


возможные причины

Это может произойти, когда:

  1. подмодуль(ы) были отредактированы на месте
  2. подмодуль(Ы) зафиксирован, который обновляет хэш подмодуля, на который указывает
  3. подмодуля(с) не толкнул.

например, что-то вроде этого получилось:

$ 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

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

решение

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

$ cd submodule
$ git push

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


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

$ git submodule update --init --depth 1

но фиксация в Родительском проекте указывала на более раннюю фиксацию.
Удаление папки подмодуля и запуск

$ git submodule update --init

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


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

откройте проблемный подмодуль из проекта Git (super-project).

Fetch и убедитесь, что "Fetch all tags" проверено.

Rebase потяните свой проект Git.

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


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

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

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


просто чтобы быть уверенным, попробуйте обновить git бинарники.

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


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

  1. перейти к dir подмодуля:

    cd sub
    
  2. оформить заказ на master:

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

  4. вернитесь к родительскому директору:

  5. обязуются мастер!--5-->

  6. изменение на другой клиент, do rebase снова.

  7. наконец-то он работает нормально! Может быть, потерять пару коммитов, но это работает.

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


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

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

  1. запустить git rm --cached
  2. удалить соответствующие строки из .файл gitmodules.
  3. удалить соответствующий раздел .git / config.
  4. Удалить сейчас неотслеживаемые файлы субмодуль.
  5. удалить каталог .git / modules/

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

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


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