Comment utiliser un référentiel git dans un autre référentiel?

284

J'ai un référentiel multimédia Git où je conserve tous mes fichiers maîtres et scripts JavaScript et CSS que j'utiliserai sur divers projets.

Si je crée un nouveau projet dans son propre référentiel Git, comment utiliser les fichiers JavaScript de mon référentiel multimédia dans mon nouveau projet de manière à ce que je n'aie pas à mettre à jour les deux copies du script lorsque j'apporte des modifications ?

Brent O'Connor
la source
Veuillez consulter la réponse du sous - arbre ci-dessous de @ ruslan-kabalin. Remarque: les hooks pré-commit (ou overcommit ) sont un moyen de traiter l'objection soulevée par Robert Dundon
Hedgehog

Réponses:

348

La clé est les sous-modules git .

Commencez à lire le chapitre Sous-modules du Git Community Book ou du mode d' emploi

Supposons que vous ayez le référentiel PROJECT1, PROJECT2 et MEDIA ...

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

Répétez sur l'autre dépôt ...

Maintenant, ce qui est cool, c'est que chaque fois que vous validez des modifications dans MEDIA, vous pouvez le faire:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

Cela vient d'enregistrer le fait que le sous-module MEDIA WITHIN PROJECT2 est maintenant à la version XYZ.

Il vous donne un contrôle à 100% sur la version de MEDIA que chaque projet utilise. Les sous - modules git sont excellents, mais vous devez les expérimenter et les découvrir.

Avec une grande puissance vient la grande chance de se faire mordre dans la croupe.

gahooa
la source
Ce flux de travail me rappelle d'utiliser un module NPM privé stackoverflow.com/questions/7575627/…
cyrf
Si vous préférez que la valeur par défaut soit la dernière version, vous pouvez ajouter un script pour propager la validation MEDIA à tous les projets dépendants.
jiggunjer
3
Comment cela s'intègre-t-il avec github?
theonlygusti
27

Envisagez d'utiliser des sous-arbres au lieu de sous-modules, cela facilitera la vie de vos utilisateurs de référentiel. Vous pouvez trouver un guide plus détaillé dans le livre Pro Git .

Ruslan Kabalin
la source
6
Voici un autre article informatif sur le sous-arbre contre le sous-module: blogs.atlassian.com/2013/05/…
Benny Neugebauer
3
Selon cet article, l'un des inconvénients est:> La responsabilité de ne pas mélanger le code de super et de sous-projet dans les commits vous incombe. Personne n'a eu le temps pour ça (OMI)
Robert Dundon
20

Si je comprends bien votre problème, vous voulez les choses suivantes:

  1. Ayez vos fichiers multimédias stockés dans un seul référentiel git, qui est utilisé par de nombreux projets
  2. Si vous modifiez un fichier multimédia dans l'un des projets de votre machine locale, il devrait apparaître immédiatement dans tous les autres projets (donc vous ne voulez pas valider + pousser + tirer tout le temps)

Malheureusement, il n'y a pas de solution ultime pour ce que vous voulez, mais il y a certaines choses qui peuvent vous faciliter la vie.

Vous devez d'abord décider d'une chose importante: voulez-vous stocker pour chaque version dans votre référentiel de projet une référence à la version des fichiers multimédias? Ainsi, par exemple, si vous avez un projet appelé example.com, avez-vous besoin de savoir quel style.css il a utilisé il y a 2 semaines, ou la dernière est toujours (ou surtout) la meilleure?

Si vous n'avez pas besoin de le savoir, la solution est simple:

  1. créer un référentiel pour les fichiers multimédias et un pour chaque projet
  2. créez un lien symbolique dans vos projets qui pointe vers le référentiel multimédia cloné localement. Vous pouvez soit créer un lien symbolique relatif (par exemple ../media) et supposer que tout le monde va extraire le projet afin que le répertoire multimédia soit au même endroit, ou écrire le nom du lien symbolique dans .gitignore, et tout le monde peut décider où il place les fichiers multimédias.

Dans la plupart des cas, cependant, vous souhaitez connaître ces informations de version. Dans ce cas, vous avez deux choix:

  1. Stockez chaque projet dans un grand référentiel. L'avantage de cette solution est que vous n'aurez qu'une seule copie du référentiel multimédia. Le gros inconvénient est qu'il est beaucoup plus difficile de basculer entre les versions de projet (si vous passez à une version différente, vous modifierez toujours TOUS les projets)

  2. Utilisez des sous-modules (comme expliqué dans la réponse 1). De cette façon, vous stockerez les fichiers multimédias dans un référentiel et les projets ne contiendront qu'une référence à une version spécifique du référentiel multimédia. Mais de cette façon, vous aurez normalement de nombreuses copies locales du référentiel multimédia et vous ne pourrez pas facilement modifier un fichier multimédia dans tous les projets.

Si j'étais vous, je choisirais probablement la première ou la troisième solution (liens symboliques ou sous-modules). Si vous choisissez d'utiliser des sous-modules, vous pouvez toujours faire beaucoup de choses pour vous faciliter la vie:

  1. Avant de vous engager, vous pouvez renommer le répertoire du sous-module et mettre un lien symbolique vers un répertoire multimédia commun. Lorsque vous êtes prêt à valider, vous pouvez supprimer le lien symbolique et supprimer le sous-module, puis valider.

  2. Vous pouvez ajouter une de vos copies du référentiel multimédia en tant que référentiel distant à tous vos projets.

Vous pouvez ajouter des répertoires locaux en tant que télécommande de cette façon:

cd /my/project2/media
git remote add project1 /my/project1/media

Si vous modifiez un fichier dans / my / project1 / media, vous pouvez le valider et le retirer de / my / project2 / media sans le pousser vers un serveur distant:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

Vous êtes libre de supprimer ces commits plus tard (avec git reset) car vous ne les avez pas partagés avec d'autres utilisateurs.

gyim
la source
1
pour les projets liés au Web dans lesquels vous travaillez dans le wwwdossier d'Apache , vous devez placer un .htaccessfichier à la racine du wwwdossier ou de votre projet, avec Options +FollowSymLinks, ou mieux encore <IfModule mod_rewrite.c>{new line}Options +FollowSymLinks{new line}RewriteEngine on{new line}</IfModule> (remplacer {new line}par une nouvelle ligne réelle)
3

J'ai eu des problèmes avec les sous-arbres et les sous-modules que les autres réponses suggèrent ... principalement parce que j'utilise SourceTree et cela semble assez bogué.

Au lieu de cela, j'ai fini par utiliser SymLinks et cela semble bien fonctionner, donc je le poste ici comme une alternative possible.

Il y a un guide complet ici: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

Mais en gros, il vous suffit de mklink les deux chemins dans une invite de commande élevée. Assurez-vous d'utiliser le préfixe de lien dur / J. Quelque chose dans ce sens: mklink / JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

Vous pouvez également utiliser des chemins d'accès de dossier relatifs et le mettre dans une chauve-souris à exécuter par chaque personne lors de la première vérification de votre projet.

Exemple: mklink / J. \ Assets \ TaqtileTools .. \ TaqtileHoloTools

Une fois le dossier lié, vous devrez peut-être ignorer le dossier de votre référentiel principal qui le référence. Sinon, vous êtes prêt à partir.

Remarque : J'ai supprimé ma réponse en double d'un autre message, car ce message a été marqué comme question en double pour celui-ci.

ickydime
la source