Git サブモジュール ヘッドの「参照はツリーではありません」エラー 質問する

Git サブモジュール ヘッドの「参照はツリーではありません」エラー 質問する

無効なコミットを指しているサブモジュールを含むプロジェクトがあります。サブモジュールのコミットはローカルのままで、別のリポジトリから取得しようとすると、次のエラーが発生します。

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

サブモジュール HEAD が何であるかはわかっていますが、コミットがあるリポジトリからプッシュせずに、これをローカルで変更する方法はありますか2d7cfbd09fc96c04c4c41148d44ed7778add6b43?

明確に説明できているか分かりませんが...似たような状況があります見つけた。

ベストアンサー1

サブモジュールのリポジトリに、使用したいコミットが含まれていると仮定すると (スーパープロジェクトの現在の状態から参照されるコミットとは異なります)、それを実行する方法は 2 つあります。

最初の方法では、使用するサブモジュールのコミットを既に知っている必要があります。これは、サブモジュールを直接調整してからスーパープロジェクトを更新することで、「内側から外側へ」機能します。2 番目の方法では、サブモジュールを変更したスーパープロジェクトのコミットを見つけ、スーパープロジェクトのインデックスをリセットして別のサブモジュールのコミットを参照することで、「外側から内側へ」機能します。

内側、外側

サブモジュールで使用するコミットが既にわかっている場合は、cdサブモジュールで必要なコミットをチェックアウトし、それgit addgit 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 は、インデックスと作業ツリーが同じであることを示しています。3 番目の diff は、ステージングされた変更のみがsubサブモジュールを別のコミットに移動していることを示しています。

専念

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

OK、 で問題が発生したようですce5d37cので、サブモジュールを親 ( ) から復元しますce5d37c~

あるいは、パッチテキスト ( 5d5a3ee314476701a20f2c6ec4a53f88d651df6c) からサブモジュールのコミットを取得し、代わりに上記の「inside, out」プロセスを使用することもできます。

スーパープロジェクトでチェックアウト

$ git checkout ce5d37c~ -- sub

これにより、サブモジュール エントリがスーパー プロジェクトでのsubコミット時の状態にリセットされます。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が で同じになったことを示しています。2 番目の diff は、インデックスと作業ツリーが同じになったことを示しています。3 番目の diff は、ステージングされた変更はサブモジュールを別のコミットにce5d37c~移動したことだけであることを示しています。sub

専念

git commit

これにより、修正されたサブモジュール エントリがコミットされます。

おすすめ記事