347 votes

Comment ajouter un sous-module à un sous-répertoire ?

J'ai un dépôt git dans ~/.janus/ avec un tas de sous-modules dedans. Je veux ajouter un sous-module dans ~/.janus/snipmate-snippets/snippets/ mais quand je lance git submodule add <git@github.com:...> dans le snipmate-snippets j'obtiens le message d'erreur suivant :

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

La question est donc la suivante : comment ajouter un sous-module à l'ensemble de l'architecture de l'entreprise ? snipmate-snippets répertoire ?

508voto

BergmannF Points 2977

Vous allez dans ~/.janus et courir :

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

Si vous avez besoin de plus d'informations sur les submodules (ou sur git en général) ProGit est très utile.

88voto

VonC Points 414372

Notez que le démarrage git1.8.4 (juillet 2013), vous n'auriez plus besoin de retourner au répertoire Root.

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

( Bouke Versteegh commentaires que vous n'avez pas besoin d'utiliser /. , comme dans snippets/. : snippets est suffisant)

Voir commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

submodule : abandon de l'exigence de niveau supérieur

Utilisez le nouveau rev-parse --prefix pour traiter tous les chemins donnés à la commande submodule, sans exiger qu'elle soit exécutée depuis le niveau supérieur du référentiel.

Puisque l'interprétation d'un URL de sous-module relatif dépend de la présence ou non de " remote.origin.url "est configuré, bloquer explicitement les URLs relatives dans " git submodule add "lorsqu'il ne se trouve pas au niveau supérieur de l'arbre de travail.

Signé par : John Keeping

Dépend de commit 12b9d32790b40bf3ea49134095619700191abf1f

Ce qui fait que ' git rev-parse ' se comporte comme s'il était invoqué à partir du sous-répertoire spécifié d'un dépôt, à la différence que tous les chemins d'accès aux fichiers qu'il imprime sont préfixés par le chemin d'accès complet depuis le sommet de l'arbre de travail. .

Ceci est utile pour les scripts shell où nous pouvons vouloir cd au sommet de l'arbre de travail mais doivent gérer les chemins relatifs donnés par l'utilisateur sur la ligne de commande.

19voto

Chris Moschini Points 7278

J'avais un problème similaire, mais je m'étais mis dans une impasse avec les outils GUI.

J'avais un sous-projet avec quelques fichiers dedans que j'avais jusqu'à présent simplement copié autour au lieu de vérifier dans leur propre repo git. J'ai créé un repo dans le sous-dossier, j'ai été capable de commiter, pousser, etc. Mais dans le repo parent, le sous-dossier n'était pas traité comme un sous-module, et ses fichiers étaient toujours suivis par le repo parent - pas bon.

Pour me sortir de ce pétrin, je devais dire à Git d'arrêter de suivre le sous-dossier (sans supprimer les fichiers) :

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

Ensuite, j'ai dû lui dire qu'il y avait un sous-module à cet endroit (ce que vous ne pouvez pas faire si quelque chose à cet endroit est actuellement suivi par git) :

proj> git submodule add ./ui/jslib

Mise à jour

La manière idéale de gérer cette situation implique quelques étapes supplémentaires. Idéalement, le dépôt existant est déplacé dans son propre répertoire, sans modules git parents, validé et poussé, puis ajouté en tant que sous-module comme suit :

proj> git submodule add git@bitbucket.org:user/jslib.git ui/jslib

Cela clonera le dépôt git en tant que sous-module - ce qui implique les étapes de clonage standard, mais aussi plusieurs autres étapes de configuration plus obscures que git effectue en votre nom pour que ce sous-module fonctionne. La différence la plus importante est qu'il place un simple fichier .git à cet endroit, au lieu d'un répertoire .git, qui contient une référence de chemin vers l'endroit où se trouve le vrai répertoire git - généralement à la racine du projet parent .git/modules/jslib.

Si vous ne faites pas les choses de cette manière, elles fonctionneront bien pour vous, mais dès que vous commettez et poussez le parent, et qu'un autre développeur va tirer ce parent, vous venez de leur rendre la vie beaucoup plus difficile. Il sera très difficile pour eux de reproduire la structure que vous avez sur votre machine tant que vous avez un répertoire .git complet dans un sous-dossier d'un répertoire qui contient son propre répertoire .git.

Donc, move, push, git add submodule, est l'option la plus propre.

19voto

yoniLavi Points 372

Pour ceux d'entre vous qui partagent mon étrange penchant pour l'édition manuelle des fichiers de configuration, l'ajout (ou la modification) des éléments suivants ferait également l'affaire.

.git/config (configuration personnelle)

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

.gitmodules (configuration partagée engagée)

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

Voir aussi ceci - différence entre .gitmodules et la spécification des submodules dans .git/config ?

2voto

Rick R Points 1

Une ligne de bash script pour faciliter la réponse de Chris ci-dessus, car je m'étais mis dans le pétrin en utilisant des mises à jour de Vundle pour mes scripts .vim. DEST est le chemin d'accès au répertoire contenant vos submodules. Faites ceci après avoir fait git 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

salutations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X