Monorepo avec Git - Centraliser sans compromis
Historique
- Google a été l’un des premiers (années 2000) à adopter ce modèle en raison de la taille considérable de sa code base.
- L’adoption généralisée de Git ( années 2005) en tant que système de contrôle de version distribué a joué un rôle significatif dans la popularité des Monorepos.
- Le passage de Facebook à une structure Monorepo en 2010, a attiré l’attention d’autres organisations à explorer cette approche. Depuis, les outils tels que Bazel (créé par Google), et Buck (créé par Facebook) ont émergé pour répondre spécifiquement aux défis posés par les Monorepos. Dans cet article, nous allons se focalisé sur l’approche directe , en utilisant seulement Git afin de fusionner plusieurs repos en une seule Monorepo tout en sauvegardant l’historique passé de chacune.
Example Pratique
Dans cet exemple, nous allons utiliser 2 repos:
- Un repo vide qui va nous servir comme Monorepo sous le nom de ‘monorepo’, initié avec la commande
git init- Un repo1 ( vous pouvez le cloner avec le lien suivant => https://github.com/meriouliabdallah/monorepo-guide-repo1) avec un projet node.js, initié avec la commande :
node init -yet un fichier app.js avec le contenu suivant: qui affiche un message avec l’heure et date courante dans la console. Le but c est de merger le repo1 dans le Monorepo tout en conservant l’historique des commits.
1. Cloner le repo
Pour commencer , on crée un dossier ( dans notre cas il va s’appeler monorepo-guide-repo1) dans lequel nous aurons le Monorepo vide et le repo1 cloner avec la commande suivante:
git clone https://github.com/meriouliabdallah/monorepo-guide-repo1Normalement, vous devriez avoir la structure suivante :
2.Ajouter une référence
Il est nécessaire d’ajouter le repo1 comme référence depuis le monorepo (vous devriez vous positionner dans le dossier) avec la commande suivante:
git remote add repo1 ../monorepo-guide-repo1qui permets d’ajouter une référence sous le nom de repo1 depuis un repo local. Il est possible d’ajouter une référence depuis un repo distant en spécifiant l’URL apres le nom.
3.Récupérer le contenu de repo1
Pour récupérer le contenu de repo sans fusionner ses modifications avec la branche actuelle on utilise la commande suivante:
git fetch4. Créer une branche
Avant de faire la fusion (merge), il est conseillé de créer une branche qui va s’appeler dans notre cas feat/repo1 avec la commande suivante:
git checkout -b feat/repo1Cette pratique est recommandée pour plusieurs raisons:
- Isolation des changements
- Possibilité de révisions et test avant d’accepter la pull request.
- Collaboration facilitée.
- Rollback facilitée.
- Historique clair.
4.Fusionner le contenu
Afin de merger le contenu de repo1 dans notre monorepo nous allons utilisé la commande
git merge <nom du remote/nom de la branche> --allow-unrelated-historiesLe flag —allow-unrelated-histories autorise la fusion des deux branches qui ont des historiques de développement différents. On se retrouve avec le contenu suivant: Remarque:S’il ya des conflits, vous devriez les résoudre avant de pouvoir fusionner.
5.Déplacer le contenu tout en préservant l’historique
Pour ne pas avoir les fichiers de plusieurs repos dans la racine du monorepo , il est conseillé de créer un dossier pour chaque repo. Dans notre cas nous allons le faire avec la commande suivante:
mkdir repo1Puis déplacer les fichiers vers ce dossier tout en préservant l’historique , on utilisera la commande suivante:
git mv README.md app.js package,json repo16. Commiter les changements
Nous allons utiliser l’outil Goji (développement interne Omnivya sous l’impulsion de Zine) qui permets de commiter des jolies commits avec rapidité tout en suivant les bonnes pratiques. Pour le lancer apres l’avoir installé, rien de plus simple
goji -ipuis
gojiet on aura l’interface suivante:
on spécifie que c est une feat , on ajoute le scope et le message de la commit
7.Pousser les changements
Une fois terminé , on pousse les changements avec la commande:
git pushComme la branche n’est pas présente dans le monorepo, il nous sera demandé d’utiliser la commande suivante:
git push --set-upstream repo1 feat/repo1Une PR(pull request) va t être créer et apres être revu et accepter le contenu va t être fusionner tout en préservant l’historique de chaque repo.
Conclusion
À travers notre example pratique, nous avons exploré une approche directe en utilisant uniquement Git pour fusionner plusieurs repos en un seul Monorepo tout en préservant l’historique des commits de chacun.