Grundsätzlich besteht mein Problem darin, dass ich git nicht verstehen kann, dass ~/main-project/submodule
ein Submodul ist.
Ich habe gute Erfahrungen mit Git-Submodulen:
in meinem dotfiles-Repository Ich habe die .gitmodules-Datei in ~/dotfiles-repo
erstellt und dort Pfade und URLs hinzugefügt. Wenn ich dann Änderungen an den Dateien innerhalb der Submodule vornehme und git status
ausführte, würde ich Folgendes erhalten: .vim/bundle/auto-complete (new commits) # in red
Ich habe die .gitmodules
-Datei in ~/main-project
erstellt, aber:
~/main-project/submodule
und sogar Push-Änderungen ändere, erhalte ich keine ähnliche Antwort wie <submodule> (new commits) # in red
, wenn git status
in ~/main-project
ausgeführt wird. Ich bekomme nur die Änderungen, die in diesen Verzeichnissen vorgenommen wurdenWenn ich für diese Verzeichnisse auf die Ordner-Links auf github
klicke, leite ich nicht zu den Repositorys selbst, aber ich bleibe im selben Repository.
~/main-project/submodule
zum Index hinzuzufügen?Ich habe diese Frage die mich zu diese Antwort geführt hat/gelesen Aber ich bin mir nicht sicher, ob ich git-subtree
brauche. Ich möchte keine Dinge tun, bei denen sich Änderungen möglicherweise schwer ändern lassen.
Edit: Diese vorgeschlagene Duplikat-Lösung hat auch nicht funktioniert, ich habe einen Fehler mit dem
Updates were rejected because the remote contains work that you do not have locally
erhalten. Es scheint, dass @GabLeRoux mir praktisch gesagt hat,<repo-A>
an die URL von<repo-B>
zu drücken.
Die Lösung ist ganz einfach. Es wurde aus hier extrahiert.
git rm submodule-dir
submodule-dir
verfolgt wurde.rm -rf submoduledir
submodule-dir
verbleiben, da git sie ignoriert hat.git commit
submodul-dir
..__ folgte. Jetzt ist es Zeit zu tun:git submodule add <remote-path-to-submodule>
.gitmodules
zu überprüfen und zu prüfen, ob die Submodule erfolgreich hinzugefügt wurden. In meinem Fall hatte ich bereits eine .gitmodules
-Datei, so dass ich sie ändern musste.Seit v2.12.0-rc0 und nach dieses Commit , erhielten wir git submodule absorbgitdirs
und es war genau das, was ich zum Zeitpunkt der Veröffentlichung dieser Frage brauchte.
Dies ist, was der Befehl docs state dieses Befehls ausführt:
Wenn sich ein Git-Verzeichnis eines Submoduls im Submodul befindet, Verschieben Sie das Git-Verzeichnis des Submoduls in seine Superprojekte
$GIT_DIR/modules
Pfad und verbinden Sie dann das Git-Verzeichnis und sein Arbeitsverzeichnis durch Setzen voncore.worktree
und Hinzufügen von Eine .git-Datei, die auf das in .__ eingebettete git-Verzeichnis verweist. SuperProjekte Git-Verzeichnis.
Anstatt wie in den vorherigen Antworten von @DomQ und mir selbst alles von vorn zu beginnen, kann man einfach Folgendes hinzufügen:
.gitmodules
und zu .git/config
mit hinzugit submodule add <url> <path>
$GIT_DIR
-Verzeichnis des Submoduls (.git
in regulären Repositorys) mit .git/modules/<path>
git submodule absorbgitdirs <path>
Es gibt grundsätzlich keinen besseren Weg, als von vorne zu beginnen:
git submodule add
von der Remote des Sub-Repositoryscd mysubmodule
git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
git merge FETCH_HEAD
Um zu erklären, warum dies so ist, scheint mir ein tieferes Verständnis darüber, welche Submodule sind erforderlich sind, als das, was man der git-submodule(1)
/ manuellen Seite (oder sogar dem relevanten Kapitel der Git Buch ). Ich habe einige ausführlichere Erklärungen zu diesem Blogbeitrag gefunden, aber da dieser Beitrag etwas langwierig ist, erlaube ich mir, sie hier zusammenzufassen.
Auf einem niedrigen Niveau besteht ein Git-Submodul aus den folgenden Elementen:
.git/modules
zum Hosten der Git-Objekte für das Submodul..gitmodules
.Das Commit-Objekt ist (oder genauer von SHA1 referenziert) im übergeordneten Baumobjekt enthalten. Dies ist ungewöhnlich, da Dinge normalerweise - umgekehrt laufen, aber dies erklärt, warum ein Verzeichnis im git status
des Haupt-Repositorys angezeigt wird, nachdem Sie im Submodul ein Commit ausgeführt haben. Sie können auch einige Experimente mit git ls-tree
machen, um dieses Commit-Objekt genauer zu betrachten.
Das Unterverzeichnis in .git/modules
steht für ein .git
-Unterverzeichnis im Untermodul; Tatsächlich gibt es im Submodul eine .git
file, die mit einer gitdir:
-Zeile auf das erste Modul verweist. Dies ist das Standardverhalten seit Version 1.7.8 von Git . Nicht sicher, warum alles nicht funktionieren würde, wenn Sie einfach nur ein separates .git
-Verzeichnis hätten, außer wie in den Versionshinweisen angegeben, würden Sie wahrscheinlich in Schwierigkeiten geraten, wenn Sie zwischen einem Zweig mit Submodul und einem anderen wechseln.
Die .gitmodules
-Datei enthält die URL, von der git submodule update --remote
und Freunde abgerufen werden sollen. was sich offensichtlich von den Fernbedienungen des Haupt-Repository unterscheidet. Beachten Sie auch, dass .gitmodules
durch den .git/config
-Befehl und andere Befehle, die ihn im Hintergrund aufrufen, teilweise in git submodule sync
kopiert wird.
Während es relativ einfach ist, die notwendigen Änderungen von Hand für .gitmodules
+ .git/config
und auch für .git/modules
+ mysubmodule/.git
vorzunehmen (und in der Tat gibt es sogar git submodule absorbgitdirs
für Letzteres), es ist nicht wirklich nur ein Porzellan, das nur erstellt werden kann das In-Tree-Commit-Objekt. Daher die vorgeschlagene Lösung durch Verschieben + Wiederherstellen der oben dargestellten Änderungen.
Um Ihre Fragen in der richtigen Reihenfolge zu beantworten:
git rm --cached submodule-name/
. Erstellen Sie anschließend ein Intermediate-Commit und fügen Sie anschließend den Ordner als Repository hinzu: git add submodule-name
(beachten Sie, dass bei Submodulen kein nachstehender Schrägstrich hinter dem Submodulnamen steht).Die Antwort , die Sie erwähnt haben, kann auch die Historie Ihrer Commits korrigieren:
Dieser Ordner wird in Ihrem gesamten Commit-Verlauf als Submodul behandelt, nicht nur in allen zukünftigen Commits. Dadurch werden Komplikationen vermieden, wenn Sie sich zu einer früheren Version auschecken, in der sie als Ordner behandelt wurde. Dies ist eine Komplikation, denn wenn Sie zum Tipp Ihres Zweigs zurückkehren, müssen Sie möglicherweise auch Ihr Submodul eingeben und den neuesten Befehl auschecken, um alle Dateien wiederherzustellen (die möglicherweise aus Ihrem Arbeitsverzeichnis gelöscht werden). Dies könnte vermieden werden, indem Sie bei Ihrem letzten Commit eine Art rekursives Checkout durchführen.
Wenn die Festschreibungshistorie geändert wird, müssten auch alle anderen Mitwirkenden das Projekt erneut klonen, da Konflikte mit der Zusammenführung auftreten oder schlimmer werden. Das Problem wird wieder in das Projekt eingefügt.