it-swarm.com.de

Git-Submodul-Kopfreferenz ist kein Baumfehler

Ich habe ein Projekt mit einem Submodul, das auf ein ungültiges Commit hinweist: Das Submodul Commit blieb lokal und wenn ich versuche, es von einem anderen Repo zu holen, bekomme ich:

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

Ich weiß, was das Submodul HEAD sein soll. Gibt es eine Möglichkeit, dies lokal zu ändern, ohne aus dem Repo herauszugehen, dass hat einen 2d7cfbd09fc96c04c4c41148d44ed7778add6b43-Befehl?

Ich bin mir nicht sicher, ob ich klar bin ... hier ist eine ähnliche Situation habe ich gefunden.

289

Angenommen, das Repository des Submoduls enthält ein Commit, das Sie verwenden möchten (im Gegensatz zum Commit, auf das vom aktuellen Status des Superprojekts verwiesen wird), gibt es zwei Möglichkeiten, dies zu tun.

Beim ersten müssen Sie das Commit bereits von dem Submodul kennen, das Sie verwenden möchten. Es funktioniert von innen nach außen, indem das Submodul direkt angepasst und das Superprojekt aktualisiert wird. Die zweite arbeitet von außen, indem sie das Commit des Superprojekts ermittelt, das das Submodul modifiziert hat, und dann den Index des Superprojekts zurücksetzen, um auf ein anderes Submodul-Commit zu verweisen.

Von innen nach außen

Wenn Sie bereits wissen, welches Commit das Submodul verwenden soll, cd für das Submodul, checken Sie das gewünschte Commit aus, dann git add und git commit im Superprojekt.

Beispiel:

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

Ups, jemand hat ein Superprojekt gemacht, das auf ein nicht veröffentlichtes Commit im Untermodul sub verweist. Irgendwie wissen wir bereits, dass das Submodul bei commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c sein soll. Geh dorthin und schau es dir direkt an.

Kasse im Submodul

$ 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 ..

Da wir ein Commit auschecken, wird ein getrenntes HEAD im Submodul erzeugt. Wenn Sie sicherstellen möchten, dass das Submodul eine Verzweigung verwendet, verwenden Sie git checkout -b newbranch <commit>, um eine Verzweigung beim Festschreiben zu erstellen und auszuchecken.

Aktualisieren Sie das Superprojekt

Ein Checkout im Submodul wird im Superprojekt als Änderung des Arbeitsbaums dargestellt. Daher müssen wir die Änderung im Index des Superprojekts in Szene setzen und die Ergebnisse überprüfen.

$ git add sub

Überprüfen Sie die Ergebnisse

$ 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

Das Submodul-Update wurde stummgeschaltet, da sich das Submodul bereits im angegebenen Commit befindet. Der erste Unterschied zeigt, dass Index und Arbeitsbaum identisch sind. Der dritte Unterschied zeigt, dass die einzige stufenweise Änderung das sub-Modul zu einem anderen Commit bewegt.

Verpflichten

git commit

Dadurch wird der festgelegte Submoduleintrag festgeschrieben.


Außenseite nach innen

Wenn Sie nicht sicher sind, welches Commit Sie von dem Submodul verwenden sollten, können Sie sich den Verlauf im Superprojekt ansehen, um Sie zu führen. Sie können den Reset auch direkt vom Superprojekt aus verwalten.

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

Dies ist die gleiche Situation wie oben. Dieses Mal werden wir uns jedoch darauf konzentrieren, es aus dem Superprojekt heraus zu beheben, anstatt in das Submodul einzutauchen.

Finden Sie das Errant Commit des Superprojekts

$ 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, es sieht so aus, als wäre es in ce5d37c schlecht gelaufen, also werden wir das Untermodul von seinem übergeordneten Element (ce5d37c~) wiederherstellen.

Alternativ können Sie die Festschreibung des Submoduls aus dem Patch-Text (5d5a3ee314476701a20f2c6ec4a53f88d651df6c) übernehmen und stattdessen den oben beschriebenen "inside, out" -Prozess verwenden.

Kasse im Super-Projekt

$ git checkout ce5d37c~ -- sub

Dadurch wurde der Submoduleintrag für sub auf das zurückgesetzt, was er beim Commit ce5d37c~ im Superprojekt war.

Aktualisieren Sie das Submodul

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

Das Submodul-Update wurde erfolgreich ausgeführt (es zeigt einen abgelösten HEAD an).

Überprüfen Sie die Ergebnisse

$ 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

Der erste Unterschied zeigt, dass sub jetzt in ce5d37c~ gleich ist. Der zweite Unterschied zeigt, dass Index und Arbeitsbaum identisch sind. Der dritte Unterschied zeigt, dass die einzige stufenweise Änderung das Submodul sub in ein anderes Commit versetzt.

Verpflichten

git commit

Dadurch wird der festgelegte Submoduleintrag festgeschrieben.

368
Chris Johnsen

versuche dies:

git submodule sync
git submodule update
183
Lonre Wang

Dieser Fehler kann bedeuten, dass im Submodul ein Commit fehlt. Das Repository (A) hat also ein Submodul (B). A möchte B laden, damit es auf ein bestimmtes Commit (in B) zeigt. Wenn dieses Commit fehlt, wird dieser Fehler angezeigt. Einmal möglicher Grund: Der Verweis auf das Commit wurde in A verschoben, aber das eigentliche Commit wurde nicht von B gedrängt. Ich würde also dort beginnen.

Weniger wahrscheinlich ist ein Berechtigungsproblem, und das Festschreiben kann nicht ausgeführt werden (möglich, wenn Sie git + ssh verwenden).

Stellen Sie sicher, dass die Submodulpfade in .git/config und .gitmodules in Ordnung sind.

Eine letzte Sache, die Sie ausprobieren können - im Submodul-Verzeichnis: git reset HEAD --hard

15
Daniel Tsadok

Mögliche Ursache

Dies kann passieren, wenn: 

  1. Submodule wurden an Ort und Stelle bearbeitet
  2. Festgeschriebene Submodule, die den Hash des Submoduls aktualisieren, auf das zeigt.
  3. Submodul (e) nicht gedrückt .

z.B. so etwas ist passiert:

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

Sollte Submodul an dieser Stelle geschoben haben.

$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git Push Origin master

Daher konnten die fehlenden Commits vom Remote-Benutzer möglicherweise nicht gefunden werden, da sie sich noch auf der lokalen Festplatte befinden.

Lösung

Informieren Sie die Person, die das Submodul in Push geändert hat, d. H.

$ cd submodule
$ git Push
9
chriskelly

Ich habe diesen Fehler erhalten, als ich es tat:

$ git submodule update --init --depth 1

das Commit im übergeordneten Projekt wies jedoch auf ein früheres Commit hin.
Submodule-Ordner löschen und ausführen

$ git submodule update --init

hat das Problem NICHT gelöst. Ich löschte das Repo und versuchte es erneut ohne Tiefenmarkierung und es funktionierte.

4
Plato

Dies kann auch passieren, wenn Sie ein Submodul haben, das auf ein Repository verweist, das umbasiert wurde und der angegebene Commit "gegangen" ist. Das Commit befindet sich zwar möglicherweise noch im fernen Repository, aber nicht in einer Verzweigung. Wenn Sie keinen neuen Zweig erstellen können (z. B. nicht Ihr Repository), müssen Sie das Superprojekt aktualisieren, um auf ein neues Commit zu verweisen. Alternativ können Sie eine Kopie Ihrer Submodule an eine andere Stelle verschieben und dann das Superprojekt aktualisieren, um stattdessen auf dieses Repository zu verweisen.

4
pasamio

Diese Antwort ist für Benutzer von SourceTree mit eingeschränkter Terminalerfahrung gedacht. 

Öffnen Sie das problematische Submodul aus dem Git-Projekt (Superprojekt).

Rufen Sie ab und stellen Sie sicher, dass "Alle Tags abrufen" aktiviert ist.

Erstelle dein Git-Projekt neu.

Dadurch wird das Problem "Referenz ist kein Baum" 9 von zehn Mal gelöst. Wenn dies nicht der Fall ist, handelt es sich um ein Terminalfix, wie es in der Top-Antwort beschrieben wird.

1
ericTbear

Um das Git-Repo mit dem Kopf des Submoduls zu synchronisieren, falls Sie es wirklich wollen, habe ich herausgefunden, dass das Entfernen des Submoduls und das Lesen des Submoduls das Basteln mit der Historie vermeiden. Leider erfordert das Entfernen eines Submoduls eher ein Hacken als ein einzelner git-Befehl, aber machbar.

Schritte, die ich zum Entfernen des Submoduls befolgt habe, inspiriert von https://Gist.github.com/kyleturner/1563153 :

  1. Führen Sie git rm --cached aus 
  2. Löschen Sie die relevanten Zeilen aus der .gitmodules-Datei.
  3. Löschen Sie den relevanten Abschnitt aus .git/config.
  4. Löschen Sie die jetzt nicht protokollierten Submodul-Dateien.
  5. Entferne das Verzeichnis .git/modules /

Dies kann wiederum nützlich sein, wenn Sie nur noch einmal auf den Kopf des Submoduls zeigen möchten und die Dinge nicht kompliziert sind, indem Sie die lokale Kopie des Submoduls intakt halten müssen. Es wird davon ausgegangen, dass Sie das Submodul "rechts" als eigenes Repo haben, wo auch immer der Ursprung des Submoduls liegt, und Sie möchten nur, dass es richtig als Submodul eingefügt wird. 

Hinweis: Machen Sie immer eine vollständige Kopie Ihres Projekts, bevor Sie diese Manipulationen oder einen beliebigen git-Befehl über das einfache Festschreiben oder Push hinaus ausführen. Ich würde das auch bei allen anderen Antworten und als allgemeine Git-Richtlinie empfehlen.

0
matanster

Ihre Submodul-Historie bleibt trotzdem im Submodul git sicher erhalten.

Warum also nicht einfach das Submodul löschen und erneut hinzufügen?

Haben Sie andernfalls versucht, die HEAD oder den refs/master/head innerhalb des Submoduls .git manuell zu bearbeiten?

0
Lakshman Prasad

In meinem Fall löst keine der obigen Antworten das Problem, auch wenn sie gute Antworten sind. Also poste ich meine Lösung (in meinem Fall gibt es zwei git-Kunden, Kunden A und B):

  1. gehe zum Verzeichnis der Untermodule:

    cd sub
    
  2. kasse zum Master:

    git checkout master
    
  3. rebase auf einen Commit-Code, den beide Clients sehen können

  4. zurück zum Elternverzeichnis:

  5. verpflichten sich zum Meister

  6. wechseln Sie zum anderen Client erneut rebase.

  7. endlich funktioniert es jetzt gut! Vielleicht ein paar Commits verlieren, aber es funktioniert.

  8. Zu Ihrer Information, versuchen Sie nicht, Ihr Submodul zu entfernen. Es bleibt dort .git/modules und kann dieses Submodul nicht erneut lesen, es sei denn, es handelt sich um ein reaktives lokales Modul.

0
kimimaro

Ich bin einfach über dieses Problem gestolpert und keine dieser Lösungen hat für mich funktioniert. Was sich als Lösung für mein Problem herausstellte, ist in der Tat viel einfacher: Aktualisieren Sie Git. Meines war 1.7.1, und nachdem ich es auf 2.16.1 (zuletzt) ​​aktualisiert habe, ist das Problem spurlos verschwunden! Ich denke, ich lasse es hier, hoffe es hilft jemandem.

0
An Phan

Ihre Filiale ist möglicherweise nicht auf dem neuesten Stand, eine einfache Lösung, aber versuchen Sie es mit git fetch

0
kittycatbytes

Um sicherzugehen, aktualisieren Sie Ihre git-Binärdateien.

GitHub für Windows hat die Version git version 1.8.4.msysgit.0, was in meinem Fall das Problem war. Update wurde behoben.

0
Gman