Ich habe ein Git-Repository, das mehrere Submodule enthält. Wie liste ich die Namen aller Submodule auf, nachdem git submodule init
sie ausgeführt wurden?
Der git submodule foreach
Befehl könnte die Namen des Submoduls wiedergeben, dies funktioniert jedoch nur, wenn sie ausgecheckt wurden, was nach dem Init-Schritt nicht geschehen ist. Es gibt weitere Schritte in der Kette, die ausgeführt werden müssen, bevor sie ausgecheckt werden können, und ich möchte nicht die Namen von Submodulen fest in das Skript einbinden müssen.
Gibt es also einen Git-Befehl, um die Namen aller aktuell registrierten, aber noch nicht ausgecheckten Submodule abzurufen?
git
git-submodules
tpg2114
quelle
quelle
git submodule
sich so verhält, wie ich es von einer Hypothese erwartet hattegit submodule list
- ich hätte einfach nie gedacht zu überprüfen, was ohne Argumente passiertgit submodule
. (Ich bin froh, dass ich diesen Link getestet habe, da ich anfangs den falschen 'Share'-Link gefunden habe!)git submodule list
es nicht existierte undgit submodule help
nicht geholfen hat (laut letzterer ist die Lösunggit submodule
keine gültige Verwendung).paths
nichtnames
, wenn sie Sonderzeichen enthalten. Ich habe versucht, eine Antwort für Namen und Pfade zu geben, die sicher sein sollten: stackoverflow.com/a/56912913/3215929Antworten:
Sie könnten den gleichen Mechanismus verwenden wie
git submodule init
sich selbst, nämlich betrachten.gitmodules
. Diese Datei listet jeden Submodulpfad und die URL auf, auf die er verweist.Beispielsweise werden vom Stammverzeichnis des Repositorys
cat .gitmodules
Inhalte auf dem Bildschirm gedruckt (vorausgesetzt, Sie haben dies getancat
).Da Gitmodule-Dateien das Git-Konfigurationsformat haben, können Sie diese Dateien mit git config analysieren:
Würde dir alle Submoduleinträge zeigen, und mit
Sie würden nur den Submodulpfad selbst erhalten.
quelle
cat .gitmodules
im Repository-Stamm tun ...awk
Teil schlägt fehl, wenn Sie Leerzeichen im Submodulpfad haben.awk
Fehler bei Submodulen mit Leerzeichen! Der Befehl sollte lautengit config -z --file .gitmodules --get-regexp '\.path$' | sed -nz 's/^[^\n]*\n//p' | tr '\0' '\n'
(Sie benötigen eine modernesed
mit-z
). Dies schlägt für Pfade mit Zeilenumbrüchen fehl (sie können mit erstellt werdengit mv
). Wenn Sie gegen diese sicher sein möchten, lassen Sie das weg| tr '\0' '\n'
und verwenden Sie so etwas... | while IFS='' read -d '' path; do ...
für die weitere Verarbeitung mit bash. Dies erfordert eine moderne Bash, die verstehtread -d ''
(vergessen Sie nicht den Raum zwischen-d
und''
).Sie können
git submodule status
oder optional verwenden,git submodule status --recursive
wenn Sie verschachtelte Submodule anzeigen möchten.Aus der Git-Dokumentation:
quelle
git submodule update --init --recursive
, um alle Submodule zu initialisieren.git
Befehls ohne Hilfe von bash markiert werden . Und diese Lösung ist insofern elegant, als sie an jedem Punkt der Arbeitskopie gut funktioniert (aber natürlich die Submodule selbst, für die das Ergebnis direkt auf sich selbst zutrifft).git submodule
ohne Argumente dasselbe wiegit submodule status
, also können Sie sich sparen, 7 Zeichen einzugeben ;-)git submodule status --recursive
funktioniert, abergit submodule --recursive
nicht. Diese 7 Charaktere kaufen dir etwas. Es hängt jedoch von Ihren Bedürfnissen ab.Mit diesem Befehl können Sie nur die Namen der registrierten Submodule zurückgeben:
Betrachten Sie es als das,
git submodule --list
was es nicht gibt.quelle
perl -ne '/^\s*path =\s*(.*)/ and push(@submods, $1); END { print(join("\n", sort(@submods)));}' "$(git rev-parse --show-toplevel)/.gitmodules"
was im Vergleich zu dieser Antwort (1) in einem beliebigen Unterverzeichnis funktioniert (jedoch nicht in einem Submodul). (2) sortiert die Submodule nach Namen; und (3) ignoriert kommentierte Zeilen in Gitmodulen.path
sie im Submodulnamen (git submodule add https://github.com/commercialhaskell/path.git
) enthalten sein kann. Aber das wussten Sie wahrscheinlich schon vorher. Wenn Sie.gitconfig
von einer beliebigen Stelle in einem Arbeitsbaum aus zugreifen möchten oder diese in einem--bare
Repository ausführen müssen , können Sie Folgendes verwendengit cat-file -p HEAD:.gitmodules | ...
. Wenn Sie auf die "bereitgestellte" Datei verweisen müssen, können Sie dies tungit cat-file -p :.gitmodules | ...
, jedoch muss ein Gitindex
vorhanden sein.Der folgende Befehl listet die Submodule auf:
Die Ausgabe ist ungefähr so:
Hinweis: Es erfordert Git 2.7.0 oder höher.
quelle
git ls-files --stage | grep ^160000
(von Answer stackoverflow.com/a/29325219 ) scheint das gleiche Ergebnis zu liefern. Vielleicht ist dies ein guter Ersatz, wenn Sie mit älteren Gits kompatibel sein müssen.--
submodule--helper
Verwenden:
Es werden alle Submodule im angegebenen Git-Repository aufgelistet.
quelle
git submodule [status]
(Hinweis, derstatus
impliziert wird, wenn er weggelassen wird, also ist dies der gleiche).fatal: no submodule mapping found in .gitmodules for path 'bla-bla/foo-bar'
. Zuerst müssen Sie alle inneren Repositorys löschen, die noch nicht submoduliert sind.--recursive
denstatus
Befehl explizit hinzufügen müssen , wenn Sie das Flag verwenden möchten :git submodule status --recursive
funktioniert, abergit submodule --recursive
nicht.Ich benutze das:
quelle
Ich bemerkte, dass der Befehl in einer Antwort auf diese Frage mir die Informationen gab, nach denen ich suchte:
In .gitmodule wurde keine Submodulzuordnung für einen Pfad gefunden, der kein Submodul ist
quelle
git ls-files --stage | grep 160000 | perl -ne 'chomp;split;print "$_[3]\n"'
.gimodules
oder nichts drin hatte.git/config
. (Ich bin nicht sicher, wie es passiert ist, ich habe das Repository in diesem Zustand. Es war ein Fehler, also war die Lösunggit rm
.)grep "^160000 "
wäre etwas robuster.Wenn es Ihnen nichts ausmacht, nur mit initialisierten Submodulen zu arbeiten, können Sie das
git submodule foreach
Parsen von Text vermeiden.quelle
Sie können verwenden:
quelle
test (master)
(Name mit einem Leerzeichen gefolgt von Klammern) fehlschlägt , bei dem es sich um einen gültigen Submodulnamen handelt . Der Befehl kann auch nicht behoben werden, da git entweder drucktmodule
odermodule (branch)
. Und es ist noch schlimmer, da dieser Befehl kein Porzellan ist und sich die Ausgabe des Befehls in Zukunft ohne vorherige Ankündigung ändern kann.Ich benutze dieses:
Ausgabe (Pfad + Version):
quelle
So listen Sie alle Submodule nach Namen auf:
git submodule --quiet foreach --recursive 'echo $name'
quelle
Das hat bei mir funktioniert:
Es basiert auf diesem großartigen Artikel: Git-Submodule verstehen
Es muss lesen
grep ^160000
.quelle
git ls-files --stage | grep ^160000
scheint die gleiche Ausgabe zu erzeugen wiegit submodule--helper list
von answer stackoverflow.com/a/40877379👍🏼
quelle
.url
Schlüssel beschränkt, daher werden möglicherweise auch andere Einträge angezeigt (normalerweise gibt es keine, aber es passiert Scheiße). Sie sollten--local
hier verwenden, da Sie--global
und--system
Einstellungen nicht sehen möchten . Und zuletzt, weil es übersehen werden könnte, funktioniert es nur für Submodule, die bereits in vorhanden sind.git/config
(wie danachgit submodule init
, siehe Frage).git config
ermöglicht die Angabe einer Konfigurationsdatei.Und
.gitmodules
ist eine Konfigurationsdatei.Also, mit Hilfe von " Leerzeichen als Trennzeichen mit Befehl cut verwenden ":
Dadurch werden nur die Pfade aufgelistet, einer pro deklariertem Submodul.
Wie Tino weist darauf hin , in den Kommentaren :
Als robustere Alternative schlägt Tino vor:
quelle
git submodule add https://github.com/hilbix/bashy.git "sub module"; git mv 'sub module' $'sub\nmodule'
) enthalten können . Siehe meinen Kommentar zu der akzeptierten Antwort, die Ihrer sehr ähnlich ist.In meiner Version von Git [1] hat jedes Git-Submodul ein
name
und einpath
. Sie müssen nicht unbedingt gleich sein [2] . Beides auf zuverlässige Weise zu erhalten, ohne zuerst die Submodule zu überprüfen (git update --init
), ist eine schwierige Aufgabe der Shell-Zauberei.Holen Sie sich eine Liste der Submodule
names
Ich habe keinen Weg gefunden, dies mit
git config
einem anderengit
Befehl zu erreichen. Deshalb sind wir wieder bei Regex.gitmodules
(super hässlich). Es scheint jedoch etwas sicher zu sein, dagit
der mögliche Codebereich für das Submodul begrenzt istnames
. Da Sie diese Liste wahrscheinlich für die weitere Shell-Verarbeitung verwenden möchten, werden in der folgenden Lösung Einträge mitNULL
-bytes (\0
) getrennt.Und in Ihrem Skript:
Hinweis :
read -rd ''
erfordertbash
und funktioniert nicht mitsh
.Holen Sie sich eine Liste der Submodule
paths
In meinem Ansatz versuche ich nicht die Ausgabe von zu verarbeiten
git config --get-regexp
mitawk
,tr
,sed
, ... , sondern gebe es einen Null - Byte wieder getrenntgit config --get
. Dies dient dazu, Probleme mit Zeilenumbrüchen, Leerzeichen und anderen Sonderzeichen (z. B. Unicode) im Submodul zu vermeidenpaths
. Da Sie diese Liste wahrscheinlich für die weitere Shell-Verarbeitung verwenden möchten, werden in der folgenden Lösung Einträge mitNULL
-bytes (\0
) getrennt.In einem Bash-Skript könnten Sie beispielsweise Folgendes tun:
Hinweis :
read -rd ''
erfordertbash
und funktioniert nicht mitsh
.Fußnoten
[1] Git-Version
[2] Submodul mit divergierenden
name
undpath
Test-Repository einrichten:
Verschieben Sie das Submodul, um Folgendes zu erstellen
name
und zupath
trennen:Testen
Test-Repository einrichten:
.gitmodules
::Liste der Submodule abrufen
names
Liste der Submodule abrufen
paths
quelle
Wenn keine
.gitmodules
Datei vorhanden ist, aber eine Submodulkonfiguration vorhanden ist in.git/modules/
:quelle
Hier ist eine andere Möglichkeit, Git-Submodulnamen aus .gitmodules zu analysieren, ohne dass sed oder ausgefallene IFS-Einstellungen erforderlich sind. :-)
quelle