J'ai un référentiel Git qui contient plusieurs sous-modules. Comment répertorier les noms de tous les sous-modules après leur git submodule init
exécution?
La git submodule foreach
commande pourrait faire écho aux noms du sous-module, mais cela ne fonctionne qu'une fois qu'ils ont été extraits, ce qui ne s'est pas produit après l'étape d'initialisation. Il y a plus d'étapes dans la chaîne qui doivent se produire avant de pouvoir les extraire, et je ne veux pas avoir à câbler les noms des sous-modules dans le script.
Existe-t-il une commande Git pour obtenir les noms de tous les sous-modules actuellement enregistrés, mais pas encore extraits?
git
git-submodules
tpg2114
la source
la source
git submodule
se comporte comme je m'attendais à ce qu'un hypothétiquegit submodule list
se comporte - je n'ai jamais pensé à vérifier ce qui se passait sans argumentgit submodule
. (Heureux d'avoir testé ce lien, car j'ai pris le mauvais lien 'Partager' au départ!)git submodule list
n'existait pas etgit submodule help
n'a pas aidé (selon ce dernier, la solutiongit submodule
, n'est pas une utilisation valide).paths
- modules , pasnames
et se cassent lorsqu'ils contiennent des caractères spéciaux. J'ai essayé de donner une réponse pour les noms et les chemins qui devraient être sûrs: stackoverflow.com/a/56912913/3215929Réponses:
Vous pouvez utiliser le même mécanisme que
git submodule init
lui-même, à savoir regarder.gitmodules
. Ce fichier énumère chaque chemin de sous-module et l'URL à laquelle il se réfère.Par exemple, à partir de la racine du référentiel,
cat .gitmodules
imprimera le contenu à l'écran (en supposant que vous l'ayezcat
).Les fichiers .gitmodule ayant le format de configuration Git, vous pouvez utiliser git config pour analyser ces fichiers:
Vous montrerait toutes les entrées de sous-module, et avec
vous obtiendrez uniquement le chemin du sous-module lui-même.
la source
cat .gitmodules
à la racine du référentiel ...awk
pièce échoue si vous avez des espaces sur le chemin du sous-module.awk
échoue pour les sous-modules avec des espaces! La commande devrait liregit config -z --file .gitmodules --get-regexp '\.path$' | sed -nz 's/^[^\n]*\n//p' | tr '\0' '\n'
(vous avez besoin d'une version modernesed
avec-z
). Cela échoue pour les chemins contenant des retours à la ligne (ils peuvent être créés avecgit mv
). Si vous voulez vous protéger contre ces derniers, laissez de côté le| tr '\0' '\n'
et utilisez quelque chose comme... | while IFS='' read -d '' path; do ...
pour un traitement ultérieur avec bash. Cela nécessite un bash moderne qui comprendread -d ''
(n'oubliez pas l'espace entre-d
et''
).Vous pouvez utiliser
git submodule status
ou facultativementgit submodule status --recursive
si vous souhaitez afficher les sous-modules imbriqués.Depuis la documentation de Git:
la source
git submodule update --init --recursive
pour initialiser tous les sous-modules.git
sans aucune aide de bash. Et cette solution est élégante dans la mesure où elle fonctionne bien à tout moment de la copie de travail (mais les sous-modules eux-mêmes bien sûr, pour lesquels le résultat s'applique directement à eux-mêmes).git submodule
sans argument est le même quegit submodule status
, donc vous pouvez vous épargner en tapant 7 caractères ;-)git submodule status --recursive
fonctionnent, mais cegit submodule --recursive
n'est pas le cas. Ces 7 personnages t'achètent quelque chose. Cela dépend de vos besoins.Pour renvoyer uniquement les noms des sous-modules enregistrés, vous pouvez utiliser cette commande:
Pensez-y comme
git submodule --list
qui n'existe pas.la source
perl -ne '/^\s*path =\s*(.*)/ and push(@submods, $1); END { print(join("\n", sort(@submods)));}' "$(git rev-parse --show-toplevel)/.gitmodules"
ce qui, comparé à cette réponse (1), fonctionne à partir de n'importe quel sous-répertoire (mais pas à l'intérieur d'un sous-module); (2) trie les sous-modules par nom; et (3) ignore les lignes commentées dans .gitmodules.path
peut être présent dans le nom du sous-module (git submodule add https://github.com/commercialhaskell/path.git
). Mais vous le saviez probablement déjà auparavant. Si vous souhaitez accéder.gitconfig
à n'importe où dans un arbre de travail ou devez l'exécuter dans un--bare
référentiel, vous pouvez utiliser quelque chose commegit cat-file -p HEAD:.gitmodules | ...
. Si vous devez vous référer au fichier "intermédiaire", vous pouvez le fairegit cat-file -p :.gitmodules | ...
, mais cela nécessite laindex
présence d' un git .La commande suivante répertorie les sous-modules:
La sortie est quelque chose comme ceci:
Remarque: il nécessite Git 2.7.0 ou supérieur.
la source
git ls-files --stage | grep ^160000
(de Answer stackoverflow.com/a/29325219 ) semble produire le même résultat, donc c'est peut-être un bon remplacement si vous devez être compatible avec des gits plus anciens.--
doubles tirets danssubmodule--helper
Utilisation:
Il répertoriera tous les sous-modules dans le référentiel Git spécifié.
la source
git submodule [status]
(notez que celastatus
est implicite si omis, c'est donc la même chose).fatal: no submodule mapping found in .gitmodules for path 'bla-bla/foo-bar'
. Vous devez d'abord supprimer tous les référentiels internes qui ne sont pas encore sous-modulés.--recursive
indicateur, vous devez ajouter explicitement lastatus
commande:git submodule status --recursive
fonctionne, maisgit submodule --recursive
ne fonctionne pas.J'utilise ceci:
la source
J'ai remarqué que la commande fournie dans une réponse à cette question m'a donné les informations que je cherchais:
Aucun mappage de sous-module trouvé dans .gitmodule pour un chemin qui n'est pas un sous-module
la source
git ls-files --stage | grep 160000 | perl -ne 'chomp;split;print "$_[3]\n"'
.gimodules
ou rien.git/config
. (Je ne sais pas comment cela s'est produit, j'ai obtenu le référentiel dans cet état. C'était une erreur, alors la solution étaitgit rm
.)grep "^160000 "
serait légèrement plus robuste.Si cela ne vous dérange pas d'opérer uniquement sur des sous-modules initialisés, vous pouvez utiliser
git submodule foreach
pour éviter l'analyse de texte.la source
Vous pouvez utiliser:
la source
test (master)
(nom avec un espace suivi de parenthèses), qui est un nom de sous-module valide . La commande ne peut pas non plus être corrigée, car git imprimemodule
oumodule (branch)
. Et c'est encore pire, car cette commande n'est pas porcellaine, donc la sortie de la commande peut changer à l'avenir sans préavis.J'utilise celui-ci:
Sortie (chemin + version):
la source
Pour répertorier tous les sous-modules par nom:
git submodule --quiet foreach --recursive 'echo $name'
la source
Cela a fonctionné pour moi:
Il est basé sur cet excellent article: Comprendre les sous-modules Git
Il faut lire
grep ^160000
.la source
git ls-files --stage | grep ^160000
semble produire la même sortie que cellegit submodule--helper list
de answer stackoverflow.com/a/40877379👍🏼
la source
.url
clés, donc d'autres entrées peuvent également apparaître (généralement il n'y en a pas, mais la merde se produit). Vous devez utiliser--local
ici, car vous ne voulez pas voir--global
et les--system
paramètres. Enfin, car il peut être ignoré, il ne fonctionne que pour les sous-modules qui sont déjà présents dans.git/config
(comme aprèsgit submodule init
, voir question).git config
permet de spécifier un fichier de configuration.Et
.gitmodules
est un fichier de configuration.Ainsi, à l'aide de " utiliser l'espace comme délimiteur avec la commande cut ":
Cela ne listera que les chemins, un par sous-module déclaré.
Comme le souligne Tino dans les commentaires :
Comme alternative plus robuste, Tino propose:
la source
git submodule add https://github.com/hilbix/bashy.git "sub module"; git mv 'sub module' $'sub\nmodule'
). Voir mon commentaire sur la réponse acceptée qui est très similaire à la vôtre.Dans ma version de Git [1] , chaque sous-module Git a un
name
et unpath
. Ils ne doivent pas nécessairement être les mêmes [2] . Obtenir les deux de manière fiable, sans vérifier d'abord les sous-modules (git update --init
), est un peu délicat de la magie du shell.Obtenez une liste des sous-modules
names
Je n'ai pas trouvé de moyen pour y parvenir en utilisant
git config
ou toute autregit
commande. Par conséquent, nous sommes de retour à regex.gitmodules
(super laid). Mais il semble être quelque peu sûr cargit
limite l'espace de code possible autorisé pour le sous-modulenames
. De plus, comme vous souhaitez probablement utiliser cette liste pour un traitement ultérieur du shell, la solution ci-dessous sépare les entrées avecNULL
-bytes (\0
).Et dans votre script:
Remarque :
read -rd ''
nécessitebash
et ne fonctionnera pas avecsh
.Obtenez une liste des sous-modules
paths
Dans mon approche , j'essaie pas de traiter la sortie
git config --get-regexp
avecawk
,tr
,sed
, ... mais passe plutôt un zéro octet séparé retour àgit config --get
. C'est pour éviter les problèmes avec les nouvelles lignes, les espaces et autres caractères spéciaux (par exemple Unicode) dans le sous-modulepaths
. De plus, comme vous souhaitez probablement utiliser cette liste pour un traitement ultérieur du shell, la solution ci-dessous sépare les entrées avecNULL
-bytes (\0
).Par exemple, dans un script Bash, vous pouvez alors:
Remarque :
read -rd ''
nécessitebash
et ne fonctionnera pas avecsh
.Notes de bas de page
[1] Version Git
[2] Sous-module avec divergence
name
etpath
Configurer le référentiel de test:
Déplacer le sous-module pour faire
name
etpath
diverger:Essai
Configurer le référentiel de test:
.gitmodules
:Obtenir la liste des sous-modules
names
Obtenir la liste des sous-modules
paths
la source
S'il n'y a pas de
.gitmodules
fichier, mais une configuration de sous-modules existe dans.git/modules/
:la source
Voici une autre façon d'analyser les noms de sous-modules Git à partir de .gitmodules sans avoir besoin de paramètres IFS sed ou fantaisie. :-)
la source