Ich habe ein Projekt mit einem Submodul, das auf ein ungültiges Commit verweist: Das Submodul-Commit blieb lokal und wenn ich versuche, es von einem anderen Repo abzurufen, erhalte 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 sollte. Gibt es eine Möglichkeit, dies lokal zu ändern, ohne von dem Repo zu drücken, das Commit hat 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
?
Ich bin mir nicht sicher, ob ich klar bin ... hier ist eine ähnliche Situation, die ich gefunden habe.
git
git-submodules
Mauricio Scheffer
quelle
quelle
Antworten:
Angenommen, das Repository des Submoduls enthält ein Commit, das Sie verwenden möchten (im Gegensatz zu dem Commit, auf das aus dem aktuellen Status des Superprojekts verwiesen wird), gibt es zwei Möglichkeiten.
Das erste erfordert, dass 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. Der zweite Vorgang erfolgt von außen nach innen, indem das Commit des Superprojekts ermittelt wird, mit dem das Submodul geändert wurde, und anschließend der Index des Superprojekts zurückgesetzt wird, um auf ein anderes Commit des Submoduls zu verweisen.
Von innen nach außen
Wenn Sie bereits wissen, welches Commit das Submodul verwenden soll
cd
, überprüfen Sie das gewünschte Commit für das Submodulgit add
undgit commit
dann wieder im Superprojekt.Beispiel:
Hoppla, jemand hat ein Superprojekt-Commit durchgeführt, das sich auf ein unveröffentlichtes Commit im Submodul bezieht
sub
. Irgendwie wissen wir bereits, dass das Submodul festgeschrieben werden soll5d5a3ee314476701a20f2c6ec4a53f88d651df6c
. Gehen Sie dorthin und sehen Sie es sich direkt an.Kasse im Submodul
Da wir ein Commit auschecken, erzeugt dies einen getrennten HEAD im Submodul. Wenn Sie sicherstellen möchten, dass das Submodul einen Zweig verwendet
git checkout -b newbranch <commit>
, erstellen und checken Sie einen Zweig beim Festschreiben aus oder checken den gewünschten Zweig aus (z. B. einen mit dem gewünschten Festschreiben an der Spitze).Aktualisieren Sie das Super-Projekt
Ein Checkout im Submodul spiegelt sich im Superprojekt als Änderung des Arbeitsbaums wider. Wir müssen also die Änderung im Index des Superprojekts inszenieren und die Ergebnisse überprüfen.
Überprüfen Sie die Ergebnisse
Die Aktualisierung des Submoduls war stumm, da sich das Submodul bereits im angegebenen Commit befindet. Der erste Unterschied zeigt, dass Index und Arbeitsbaum identisch sind. Der dritte
sub
Unterschied zeigt, dass die einzige schrittweise Änderung darin besteht, das Submodul in ein anderes Commit zu verschieben.Verpflichten
Dies schreibt den festen Submoduleintrag fest.
Außenseite nach innen
Wenn Sie nicht sicher sind, welches Commit Sie aus dem Submodul verwenden sollen, können Sie sich den Verlauf im Superprojekt ansehen, um sich zu orientieren. Sie können den Reset auch direkt vom Superprojekt aus verwalten.
Dies ist die gleiche Situation wie oben. Aber dieses Mal werden wir uns darauf konzentrieren, es aus dem Superprojekt heraus zu reparieren, anstatt in das Submodul einzutauchen.
Finden Sie das Errant Commit des Superprojekts
OK, es sieht so aus, als wäre es schlecht
ce5d37c
gelaufen, also werden wir das Submodul von seinem übergeordneten (ce5d37c~
) wiederherstellen .Alternativ können Sie das Commit des Submoduls aus dem Patch-Text (
5d5a3ee314476701a20f2c6ec4a53f88d651df6c
) übernehmen und stattdessen den obigen Prozess "Inside, Out" verwenden.Kasse im Super-Projekt
Dadurch wurde der Submoduleintrag
sub
auf das zurückgesetzt , was erce5d37c~
im Superprojekt festgeschrieben hatte.Aktualisieren Sie das Submodul
Das Submodul-Update ging in Ordnung (es zeigt einen abgetrennten HEAD an).
Überprüfen Sie die Ergebnisse
Der erste Unterschied zeigt, dass dies
sub
jetzt der gleiche istce5d37c~
. Der zweite Unterschied zeigt, dass Index und Arbeitsbaum identisch sind. Der drittesub
Unterschied zeigt, dass die einzige schrittweise Änderung darin besteht, das Submodul in ein anderes Commit zu verschieben.Verpflichten
Dies schreibt den festen Submoduleintrag fest.
quelle
e47c0a
ein Commit, das im lokalen Repository für nicht vorhanden istsub
, aber das Superprojektsub
verweist auf dieses Commit. Dies kann geschehen sein, weil jemand anderes, dere47c0a
in seiner Kopie von erstellt wurdesub
, sein Superprojekt aktualisiert hat, um auf dieses Commit zu verweisen, und das Superprojekt verschoben hat, ohnee47c0a
auf das zentrale / gemeinsam genutzte Repository für zu pushensub
. Wenn wir von dem zentralen / shared super-Projekt ziehen bekommen wir eine Festschreibung , dass die Punktesub
aufe47c0a
, aber wir können nicht „sehen“ , die zu begehen.ce5d37c
ist verdächtig, weil es aufgrund des Diff eingeführt wurdee47c0a
.sub
im übergeordneten Repo aufbewahrten Repos befindet, der es als Submodul enthält, und ob es direkt auf den aktuellen HEAD vonsub
direkt manipuliert werden kann oder nicht , ohne sich auf einen älteren Status des Elternteils zu verlassen Repo, was vielleicht nicht immer hilft.Versuche dies:
quelle
git submodule sync
in Szenarien erforderlich ist, in denen sich die URL der Fernbedienung für ein bestimmtes Submodul geändert hat. In unserem Fall hatten wir unser Submodul aus einem öffentlichen Repo hinzugefügt und dann die URL in eine private Abzweigung geändert - und uns in diese spezielle Essiggurke hineinversetzt.Dieser Fehler kann bedeuten, dass ein Commit im Submodul fehlt. Das heißt, das Repository (A) hat ein Submodul (B). A möchte B so laden, dass es auf ein bestimmtes Commit zeigt (in B). Wenn dieses Commit irgendwie fehlt, wird dieser Fehler angezeigt. Einmal mögliche Ursache: Der Verweis auf das Commit wurde in A verschoben, aber das tatsächliche Commit wurde nicht von B übertragen. Also würde ich dort beginnen.
Weniger wahrscheinlich liegt ein Berechtigungsproblem vor und das Commit kann nicht gezogen 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 versuchen sollten - im Submodul-Verzeichnis: git reset HEAD --hard
quelle
Mögliche Ursache
Dies kann passieren, wenn:
zB ist so etwas passiert:
Sollte das Submodul an dieser Stelle gedrückt haben.
Infolgedessen konnten die fehlenden Festschreibungen vom Remotebenutzer möglicherweise nicht gefunden werden, da sie sich noch auf der lokalen Festplatte befinden.
Lösung
Informieren Sie die Person, die das Submodul geändert hat, um zu pushen, dh
quelle
Ich habe diesen Fehler bekommen, als ich tat:
Das Commit im übergeordneten Projekt zeigte jedoch auf ein früheres Commit.
Löschen des Submodul-Ordners und Ausführen von:
hat das Problem NICHT gelöst. Ich habe das Repo gelöscht und es erneut ohne die Tiefenflagge versucht und es hat funktioniert.
Dieser Fehler tritt in Ubuntu 16.04 Git 2.7.4 auf, aber nicht in Ubuntu 18.04 Git 2.17. TODO findet das genaue Fixing Commit oder die Version.
quelle
username/repo#sha
zu package.json hinzugefügt , eine viel flexiblere Option ist es, Ihr System mit einer Reihe von Docker-Containern zu organisieren--depth=1
spart so viel Bandbreite, wenn ich den Repo-Verlauf nicht benötige. Wenn jemand jemals findet oder weiß, warum dies geschieht, würde ich es gerne wissen.deinit
Ansatz verwendet, der das Problem die meiste Zeit behebt. In Verbindung mit einem Build-System kann der Endbenutzer das Build-System einfach die Submodule abrufen lassen und den fehlerhaftenrecursive
Befehl ganz fallen lassen. Es gibt immer noch Szenarien, in denen dies unterbrochen wird, z. B. dass das Submodul einen Force-Push ausgeführt und das Commit vollständig gelöscht hat.Dies kann auch passieren, wenn ein Submodul auf ein Repository verweist, das neu basiert wurde, und das angegebene Commit "weg" ist. Während sich das Commit möglicherweise noch im Remote-Repository befindet, befindet es sich nicht in einem Zweig. Wenn Sie keinen neuen Zweig erstellen können (z. B. nicht Ihr Repository), müssen Sie das Superprojekt nicht mehr aktualisieren, um auf ein neues Commit zu verweisen. Alternativ können Sie eine Ihrer Kopien der Submodule an eine andere Stelle verschieben und dann das Superprojekt aktualisieren, um stattdessen auf dieses Repository zu verweisen.
quelle
Ihre Niederlassung ist möglicherweise nicht auf dem neuesten Stand, eine einfache Lösung, aber versuchen Sie es
git fetch
quelle
Diese Antwort richtet sich an Benutzer von SourceTree mit eingeschränkter Erfahrung mit Terminal-Git.
Öffnen Sie das problematische Submodul aus dem Git-Projekt (Superprojekt).
Abrufen und sicherstellen, dass "Alle Tags abrufen" aktiviert ist.
Rebase ziehen Sie Ihr Git-Projekt.
Dies löst das Problem "Referenz ist kein Baum" 9 von zehn Fällen. Das 1 Mal, wenn dies nicht der Fall ist, ist ein Terminal-Fix, wie in der oberen Antwort beschrieben.
quelle
Ihr Submodulverlauf wird ohnehin sicher im Submodul-Git gespeichert.
Warum also nicht einfach das Submodul löschen und erneut hinzufügen?
Andernfalls haben Sie versucht, das
HEAD
oderrefs/master/head
das Submodul manuell zu bearbeiten.git
quelle
Versuchen Sie zur Sicherheit, Ihre
git
Binärdateien zu aktualisieren .GitHub für Windows hat die Version,
git version 1.8.4.msysgit.0
die in meinem Fall das Problem war. Aktualisierung gelöst.quelle
In meinem Fall löst keine der oben genannten Antworten das Problem, auch wenn es sich um gute Antworten handelt. Also poste ich meine Lösung (in meinem Fall gibt es zwei Git-Clients, Client A und B):
Gehe zum Verzeichnis des Submoduls:
Kasse zum Master:
Rebase auf einen Commit-Code, den beide Clients sehen können
gehe zurück zum Verzeichnis der Eltern:
verpflichten sich zu meistern
zum anderen Client wechseln
rebase
again erneut ausführen.endlich funktioniert es jetzt gut! Vielleicht ein paar Commits verlieren, aber es funktioniert.
Zu Ihrer Information, versuchen Sie nicht, Ihr Submodul zu entfernen, es bleibt
.git/modules
dort und kann dieses Submodul nicht erneut lesen, es sei denn, es ist ein reaktives lokales Modul.quelle
Um das Git-Repo mit dem Kopf des Submoduls zu synchronisieren, habe ich festgestellt, dass das Entfernen und anschließende Lesen des Submoduls das Basteln mit dem Verlauf vermeidet, falls dies wirklich gewünscht wird. Leider erfordert das Entfernen eines Submoduls das Hacken, anstatt ein einzelner Git-Befehl zu sein, aber machbar.
Schritte zum Entfernen des Submoduls, inspiriert von https://gist.github.com/kyleturner/1563153 :
Dies kann wiederum nützlich sein, wenn Sie nur erneut auf den Kopf des Submoduls zeigen möchten und Sie die Dinge nicht kompliziert haben, indem Sie die lokale Kopie des Submoduls intakt halten müssen. Es wird davon ausgegangen, dass Sie das Submodul "richtig" als eigenes Repo haben, wo immer es seinen Ursprung hat, und Sie möchten es einfach wieder richtig als Submodul einbinden.
Hinweis: Erstellen Sie immer eine vollständige Kopie Ihres Projekts, bevor Sie diese Art von Manipulation oder einen Git-Befehl ausführen, der über das einfache Festschreiben oder Drücken hinausgeht. Ich würde das auch bei allen anderen Antworten und als allgemeine Git-Richtlinie empfehlen.
quelle
Ich bin gerade auf dieses Problem gestoßen, und keine dieser Lösungen hat bei mir funktioniert. Was sich als Lösung für mein Problem herausstellte, ist tatsächlich viel einfacher: Git aktualisieren. Meins war 1.7.1 und nachdem ich es auf 2.16.1 (aktuell) aktualisiert hatte, verschwand das Problem spurlos! Ich schätze, ich lasse es hier, hoffe es hilft jemandem.
quelle