Wie füge ich einem Unterverzeichnis ein Submodul hinzu?

310

Ich habe ein Git-Repo ~/.janus/mit ein paar Submodulen. Ich möchte ein Submodul hinzufügen ~/.janus/snipmate-snippets/snippets/, aber wenn ich git submodule add <[email protected]:...>im snipmate-snippetsVerzeichnis ausgeführt werde, wird die folgende Fehlermeldung angezeigt:

You need to run this command from the toplevel of the working tree.

Die Frage ist also: Wie füge ich dem snipmate-snippetsVerzeichnis ein Submodul hinzu ?

Robert Audi
quelle
Das Wechseln in das Stammverzeichnis eines Git-Repos für Submodul-Befehle ist (bald) nicht mehr erforderlich. Siehe meine Antwort unten
VonC
3
git submodule add -b <branch> <url> <relative_path_4m_root>
Parasrish

Antworten:

439

Du gehst hinein ~/.janusund rennst:

git submodule add <git@github ...> snipmate-snippets/snippets/

Wenn Sie weitere Informationen zu Submodulen (oder Git im Allgemeinen) benötigen, ist ProGit sehr nützlich.

BergmannF
quelle
Es scheint eine gute Idee zu sein, beim Hinzufügen einen Zweig hinzuzufügen, da sich HEAD sonst leicht trennen lässt: Git-Submodul add -b <branch> <Repository> [<Submodul-Pfad>]
Deann
1
Für mich war dies eine Ursache 'subprojects' already exists in the index (ich habe Teilprojekte als Verzeichnisnamen verwendet) . Stattdessen hat die Antwort des VonC unten geholfen, dh zu tun cd subprojects, und dann git submodule add <get@github …>ohne den Pfad.
Hi-Angel
83

Beachten Sie, dass Sie ab git1.8.4 (Juli 2013) nicht mehr zum Stammverzeichnis zurückkehren müssen.

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets

( Bouke Versteegh kommentiert, dass Sie nicht verwenden müssen /., wie in snippets/.: snippetsist genug)

Siehe Commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

Submodul: Löschen Sie die Anforderung der obersten Ebene

Verwenden Sie die neue rev-parse --prefixOption, um alle Pfade zu verarbeiten, die dem Befehl submodule zugewiesen wurden, und löschen Sie die Anforderung, dass er von der obersten Ebene des Repositorys ausgeführt werden soll.

Da die Interpretation einer relativen Submodul-URL davon abhängt, ob " remote.origin.url" konfiguriert ist oder nicht , blockieren Sie relative URLs explizit in " git submodule add", wenn Sie sich nicht auf der obersten Ebene des Arbeitsbaums befinden.

Abgemeldet von: John Keeping

Kommt drauf an Commit 12b9d32790b40bf3ea49134095619700191abf1f

Das macht 'git rev-parse verhält sich ' so, als würde es aus dem angegebenen Unterverzeichnis eines Repositorys aufgerufen, mit dem Unterschied, dass allen gedruckten Dateipfaden der vollständige Pfad vom oberen Rand des Arbeitsbaums vorangestellt wird .

Dies ist nützlich für Shell-Skripte, bei denen wir möglicherweise cdan die Spitze des Arbeitsbaums möchten, aber die vom Benutzer in der Befehlszeile angegebenen relativen Pfade verarbeiten müssen.

VonC
quelle
Vielen Dank! Ich habe festgestellt, dass das Trailing /.nicht erforderlich ist. Git erstellt die Verzeichnis-Snippets ohne dieses.
Bouke Versteegh
@BoukeVersteegh Interessant. Ich habe Ihren Kommentar zur besseren Sichtbarkeit in die Antwort aufgenommen.
VonC
Ich bin auf Git Version 2.7.4, aber ich erhalte immer noch diese Fehlermeldung Relative path can only be used from the toplevel of the working tree. Ich machegit submodule add ../../../functest
FlyingAura
@ user3426358 Ja, das wird erwartet: Die obige Antwort über die Fähigkeit, ein Git-Submodell hinzuzufügen, wird aus einem beliebigen Unterordner des Haupt-Repos hinzugefügt, nicht nur aus seinem Stammordner. Es geht nicht darum, das Remote-Repo des Submoduls mit einem relativen Pfad zu referenzieren. In diesem Fall wird die angezeigte Fehlermeldung angezeigt.
VonC
@ user3426358 Übrigens, diese Fehlermeldung (die Sie sehen: " Relative path can only be used from the toplevel of the working tree") ist nicht die aus der ursprünglichen Frage (" You need to run this command from the toplevel of the working tree")
VonC
17

Ich hatte ein ähnliches Problem, hatte mich aber mit GUI-Tools in eine Ecke gemalt.

Ich hatte ein Teilprojekt mit ein paar Dateien, die ich bisher nur kopiert hatte, anstatt in ihr eigenes Git-Repo einzuchecken. Ich habe ein Repo im Unterordner erstellt, konnte mich gut verpflichten, pushen usw. Aber im übergeordneten Repo wurde der Unterordner nicht als Submodul behandelt, und seine Dateien wurden immer noch vom übergeordneten Repo verfolgt - nicht gut.

Um aus diesem Chaos herauszukommen, musste ich Git anweisen, den Unterordner nicht mehr zu verfolgen (ohne die Dateien zu löschen):

proj> git rm -r --cached ./ui/jslib

Dann musste ich sagen, dass es dort ein Submodul gibt (was Sie nicht tun können, wenn irgendetwas dort gerade von git verfolgt wird):

proj> git submodule add ./ui/jslib

Aktualisieren

Der ideale Weg, dies zu handhaben, umfasst ein paar weitere Schritte. Im Idealfall wird das vorhandene Repo in ein eigenes Verzeichnis verschoben, das frei von übergeordneten Git-Modulen ist, festgeschrieben und gepusht und dann als Submodul wie folgt hinzugefügt:

proj> git submodule add [email protected]:user/jslib.git ui/jslib

Dadurch wird das Git-Repo als Submodul geklont. Dies umfasst die Standardschritte zum Klonen, aber auch einige andere undurchsichtigere Konfigurationsschritte, die Git in Ihrem Namen ausführt, damit dieses Submodul funktioniert. Der wichtigste Unterschied besteht darin, dass dort anstelle eines .git-Verzeichnisses eine einfache .git-Datei abgelegt wird, die einen Pfadverweis darauf enthält, wo sich das echte git-Verzeichnis befindet - im Allgemeinen im Stammverzeichnis des übergeordneten Projekts .git / modules / jslib.

Wenn Sie die Dinge nicht so machen, funktionieren sie gut für Sie, aber sobald Sie die Eltern verpflichten und pushen und ein anderer Entwickler diese Eltern zieht, haben Sie ihnen das Leben viel schwerer gemacht. Es wird für sie sehr schwierig sein, die Struktur auf Ihrem Computer zu replizieren, solange Sie ein vollständiges .git-Verzeichnis in einem Unterordner eines Verzeichnisses haben, das sein eigenes .git-Verzeichnis enthält.

Also, verschieben, drücken, Submodul hinzufügen, ist die sauberste Option.

Chris Moschini
quelle
16

Für diejenigen unter Ihnen, die meine seltsame Vorliebe für das manuelle Bearbeiten von Konfigurationsdateien teilen, würde das Hinzufügen (oder Ändern) des Folgenden ebenfalls den Trick tun.

.git / config (persönliche Konfiguration)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules (festgeschriebene gemeinsam genutzte Konfiguration)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

Sehen Sie dies auch - Unterschied zwischen .gitmodules und der Angabe von Submodulen in .git / config?

yoniLavi
quelle
2

Einzeiliges Bash-Skript, um Chris 'Antwort oben zu erleichtern, da ich mich auch in einer Ecke mit Vundle-Updates für meine .vim-Skripte gemalt hatte. DESTist der Pfad zu dem Verzeichnis, das Ihre Submodule enthält. Tun Sie dies nach dem Tungit rm -r $DEST

DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

Prost

Rick R.
quelle