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

310

J'ai un dépôt git ~/.janus/avec un tas de sous-modules. Je souhaite ajouter un sous-module ~/.janus/snipmate-snippets/snippets/, mais lorsque j'exécute git submodule add <[email protected]:...>dans le snipmate-snippetsrépertoire, 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 au snipmate-snippetsrépertoire?

Robert Audi
la source
Aller dans le répertoire racine d'un dépôt git pour les commandes de sous-module ne sera plus une exigence (bientôt). Voir ma réponse ci
VonC
3
git submodule add -b <branch> <url> <relative_path_4m_root>
parasrish

Réponses:

439

Vous entrez ~/.januset 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 assez utile.

BergmannF
la source
il semble une bonne idée d'ajouter une branche lors de l'ajout, sinon HEAD se détache facilement: git submodule add -b <branch> <repository> [<submodule-path>]
deann
1
Pour moi, cela causait 'subprojects' already exists in the index (j'utilisais des sous-projets comme nom de répertoire) . Au lieu de cela, ce qui a aidé, c'est la réponse du VonC ci-dessous, c'est-à-dire faire cd subprojects, puis git submodule add <get@github …>sans le chemin.
Hi-Angel
83

Notez qu'à partir de git1.8.4 (juillet 2013), vous n'aurez plus à retourner dans le répertoire racine.

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

( Bouke Versteegh commente que vous n'avez pas à utiliser /., comme dans snippets/.: snippetsc'est suffisant)

Voir commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

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

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

Étant donné que l'interprétation d'une URL de sous-module relative dépend de la remote.origin.urlconfiguration ou non de " ", bloquez explicitement les URL relatives dans " git submodule add" lorsqu'elles ne se trouvent pas au niveau supérieur de l'arborescence de travail.

Approuvé par: John Keeping

Dépend de la validation 12b9d32790b40bf3ea49134095619700191abf1f

Cela fait que ' git rev-parse' se comporte comme s'il était appelé depuis le sous-répertoire spécifié d'un référentiel, à la différence que tous les chemins de fichiers qu'il imprime sont préfixés avec le chemin complet depuis le haut de l'arborescence de travail .

Ceci est utile pour les scripts shell où nous souhaitons peut-être cden haut de l'arborescence de travail mais avons besoin de gérer les chemins relatifs donnés par l'utilisateur sur la ligne de commande.

VonC
la source
Grand merci! J'ai remarqué que le suivi /.n'est pas nécessaire, git créera les extraits de répertoire sans lui.
Bouke Versteegh
@BoukeVersteegh Intéressant. J'ai inclus votre commentaire dans la réponse pour plus de visibilité.
VonC
Je suis sur la version 2.7.4 de git mais je reçois toujours ce message d'erreur Relative path can only be used from the toplevel of the working tree. Je faisgit submodule add ../../../functest
FlyingAura
@ user3426358 oui, cela est attendu: la réponse ci-dessus concerne la capacité de faire un ajout de sous-module git à partir de n'importe quel sous-dossier du référentiel principal, pas seulement à partir de son dossier racine. Il ne s'agit pas de référencer le référentiel distant du sous-module avec un chemin relatif. Si vous le faites, vous obtiendrez le message d'erreur que vous voyez.
VonC
@ user3426358 Et au fait, ce message d'erreur (que vous voyez: " Relative path can only be used from the toplevel of the working tree") n'est pas celui de la question d'origine (" You need to run this command from the toplevel of the working tree")
VonC
17

J'ai eu un problème similaire, mais je me suis peint dans un coin avec des outils GUI.

J'avais un sous-projet avec quelques fichiers que je venais de copier jusqu'à présent au lieu de vérifier dans leur propre dépôt git. J'ai créé un dépôt dans le sous-dossier, j'ai pu valider, pousser, etc. très bien. 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érentiel parent - pas bon.

Pour sortir de ce bordel, j'ai dû 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 est actuellement suivi par git):

proj> git submodule add ./ui/jslib

Mettre à jour

La façon 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 clonera le dépôt git en tant que sous-module - ce qui implique les étapes de clonage standard, mais également plusieurs autres étapes de configuration plus obscures que git prend en votre nom pour faire fonctionner ce sous-module. La différence la plus importante est qu'il y place un simple fichier .git, au lieu d'un répertoire .git, qui contient une référence de chemin vers l'emplacement du 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 vous engagez et poussez le parent, et qu'un autre dev va tirer ce parent, vous venez de rendre leur vie beaucoup plus difficile. Il leur sera très difficile de répliquer 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, déplacer, pousser, ajouter un sous-module, c'est l'option la plus propre.

Chris Moschini
la source
16

Pour ceux d'entre vous qui partagent mon étrange envie de modifier manuellement les 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 validée )

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

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

yoniLavi
la source
2

script bash à une ligne pour aider la réponse de Chris à l'installation ci-dessus, car je m'étais moi-même peint dans un coin en utilisant les mises à jour Vundle de mes scripts .vim. DESTest le chemin d'accès au répertoire contenant vos sous-modules. Faites cela après avoir faitgit 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é

Rick R
la source