web-dev-qa-db-fra.com

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

J'ai un repo git dans ~/.janus/ avec un tas de sous-modules dedans. Je souhaite ajouter un sous-module dans ~/.janus/snipmate-snippets/snippets/, mais lorsque j'exécute git submodule add <[email protected]:...> dans le répertoire snipmate-snippets, le message d'erreur suivant s'affiche:

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

La question est donc la suivante: comment ajouter un sous-module au répertoire snipmate-snippets?

269
Robert Audi

Vous allez dans ~/.janus et exécutez:

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

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

381
BergmannF

Notez qu'à partir de git1.8.4 (juillet 2013), vous ne devriez plus avoir à revenir au répertoire racine.

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

( Bouke Versteeghcommentaires vous n'êtes pas obligé d'utiliser /., comme dans snippets/.: snippets est suffisant)

Voir commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

sous-module: supprime l'exigence de niveau supérieur

Utilisez la nouvelle option rev-parse --prefix pour traiter tous les chemins donnés à la commande de sous-module, en supprimant la nécessité de l'exécuter à partir du niveau supérieur du référentiel.

Puisque l'interprétation d'une URL de sous-module relative dépend de la configuration de "remote.Origin.url", bloquez explicitement les URL relatives dans "git submodule add" lorsque vous n'êtes pas au niveau supérieur de l'arbre de travail.

Signé-par-: John Keeping

Dépend de commit 12b9d32790b40bf3ea49134095619700191abf1f

Ceci fait que _ git rev-parse 'se comporte comme s’il était appelé à partir du sous-répertoire spécifié d’un référentiel, à la différence que les chemins de fichiers qu’il affiche sont préfixés du chemin complet du répertoire. sommet de l’arbre de travail .

Ceci est utile pour les scripts Shell dans lesquels nous pouvons vouloir cd tout en haut de l’arbre de travail, mais devons gérer les chemins relatifs donnés par l’utilisateur sur la ligne de commande.

75
VonC

J'avais un problème similaire, mais je m'étais dissimulé dans un coin avec des outils d'interface graphique.

J'avais un sous-projet contenant quelques fichiers que je venais de copier au lieu de vérifier dans leur propre dépôt Git. J'ai créé un repo dans le sous-dossier, j'ai pu valider, Push, etc. Mais dans le référentiel parent, le sous-dossier n’était pas traité comme un sous-module et ses fichiers étaient toujours suivis par le référent parent - rien de bon.

Pour 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 (ce que vous ne pouvez pas faire si quelque chose là-bas est actuellement suivi par git):

proj> git submodule add ./ui/jslib

Mise à jour

La manière idéale de gérer cela implique quelques étapes supplémentaires. Idéalement, le référentiel existant est déplacé vers son propre répertoire, exempt de tout module git parent, validé et poussé, puis ajouté en tant que sous-module comme:

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

Cela va cloner le dépôt git en tant que sous-module - ce qui implique les étapes standard de clonage, mais également plusieurs autres étapes de configuration plus obscures que git prend en votre nom pour que ce sous-module fonctionne. La différence la plus importante est qu’il place un simple fichier .git à la place d’un répertoire .git, qui contient une référence de chemin vers le répertoire où réside 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 façon, cela fonctionnera bien pour vous, mais dès que vous aurez validé et poussé le parent, et qu'un autre développeur le tirera, vous leur aurez rendu la vie beaucoup plus difficile. Il leur sera très difficile 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.

17
Chris Moschini

Pour ceux d'entre vous qui partagent mon goût étrange pour l'édition manuelle de fichiers de configuration, ajouter (ou modifier) ​​les é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 validée)

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

Voir cela aussi - différence entre .gitmodules et spécification de sous-modules dans .git/config?

15
yoniLavi

one-liner bash script pour aider la réponse de Chris ci-dessus, car je m'étais peint aussi dans un coin en utilisant les mises à jour Vundle de mes scripts .vim. DEST est le chemin du répertoire contenant vos sous-modules. 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

à votre santé

2
Rick R