A
Etienne Deneuve
Mar 10, 2024 · 4 min read

Monorepo avec Git - Centraliser sans compromis

Side view worker wearing gloves

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
Terminal window
git init
Terminal window
node init -y

et 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:

Terminal window
git clone https://github.com/meriouliabdallah/monorepo-guide-repo1

Normalement, 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:

Terminal window
git remote add repo1 ../monorepo-guide-repo1

qui 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:

Terminal window
git fetch

4. 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:

Terminal window
git checkout -b feat/repo1

Cette 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

Terminal window
git merge <nom du remote/nom de la branche> --allow-unrelated-histories

Le 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:

Terminal window
mkdir repo1

Puis déplacer les fichiers vers ce dossier tout en préservant l’historique , on utilisera la commande suivante:

Terminal window
git mv README.md app.js package,json repo1

6. 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

Terminal window
goji -i

puis

Terminal window
goji

et 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:

Terminal window
git push

Comme la branche n’est pas présente dans le monorepo, il nous sera demandé d’utiliser la commande suivante:

Terminal window
git push --set-upstream repo1 feat/repo1

Une 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.

Monorepo Git

Articles relatifs