# git submodule ou subtree pour partager une bibliothèque PHP entre projets

> Deux façons d'inclure un code commun versionné séparément, avec des compromis différents sur la mise à jour et la visibilité pour l'équipe.

- Auteur : WordPress Développement
- Publié le : 2021-08-17
- Mis à jour le : 2021-08-17
- Catégorie : Outils &amp; workflow
- URL : https://www.wpmoderne.fr/outils/git-submodule-ou-subtree-bibliotheque-php/

## L’essentiel

- submodule garde une référence claire mais demande une manipulation supplémentaire
- subtree fusionne le code dans l'historique, plus transparent mais plus lourd
- Le bon choix dépend de la fréquence de mise à jour de la bibliothèque partagée

`git submodule add git@depot:agence/bibliotheque-commune.git lib/commune` : cette commande ajoute une référence vers un dépôt externe dans un projet, sans jamais copier son contenu dans l'historique du projet principal. Une alternative existe, `git subtree`, qui suit une logique inverse. Ce billet compare les deux approches pour partager une bibliothèque PHP entre plusieurs projets d'agence, sans traiter la publication de cette bibliothèque sur Packagist.

Le choix entre ces deux mécanismes n'est pas anodin : il détermine comment l'équipe perçoit le code partagé au quotidien, et combien d'efforts une mise à jour demande ensuite.

## git submodule : une référence, pas une copie

Un sous-module Git conserve le dépôt de la bibliothèque partagée entièrement séparé, en ne stockant dans le projet principal qu'une référence à un commit précis de ce dépôt externe. Cloner le projet principal ne récupère pas automatiquement le contenu du sous-module : une commande supplémentaire est nécessaire.

```
git submodule add git@depot:agence/bibliotheque-commune.git lib/commune
git clone --recurse-submodules git@depot:agence/projet-client.git
git submodule update --remote lib/commune
```

Cette séparation stricte a un avantage : chaque projet référence une version précise et figée de la bibliothèque, et rien ne change dans le projet principal tant que quelqu'un ne met pas explicitement à jour cette référence. Elle a aussi un inconvénient bien connu des équipes qui l'utilisent : oublier l'option `--recurse-submodules` au clonage laisse un dossier vide, source d'incompréhension pour un nouveau membre de l'équipe.

## git subtree : le code fusionné dans l'historique du projet

> L'essentiel à retenir : submodule garde une référence claire mais demande une manipulation supplémentaire ; subtree fusionne le code dans l'historique, plus transparent mais plus lourd ; Le bon choix dépend de la fréquence de mise à jour de la bibliothèque partagée

L'approche subtree fonctionne différemment : le code de la bibliothèque partagée est directement fusionné dans l'historique du projet principal, comme s'il avait toujours fait partie du même dépôt. Aucune commande supplémentaire n'est nécessaire au clonage, puisque le code est physiquement présent dans le dépôt principal.

```
git subtree add --prefix=lib/commune git@depot:agence/bibliotheque-commune.git main --squash
git subtree pull --prefix=lib/commune git@depot:agence/bibliotheque-commune.git main --squash
```

Cette transparence a un coût : l'historique du projet principal s'alourdit du contenu de la bibliothèque partagée, et distinguer une modification du code métier d'une mise à jour de la bibliothèque commune demande davantage d'attention en lisant les journaux de commits.

## Comparatif des deux approches

| Critère | git submodule | git subtree |
| --- | --- | --- |
| Clonage du projet principal | Nécessite une option ou une commande supplémentaire | Récupère tout automatiquement |
| Visibilité du code partagé | Référence distincte, dépôt séparé visible | Fusionné, moins visible comme code externe |
| Historique du projet principal | Reste léger, seule la référence change | S'alourdit du contenu de la bibliothèque |
| Mise à jour de la bibliothèque | Une commande dédiée, ciblée sur la référence | Une commande dédiée, fusion possible avec conflits |

## Ce qui a orienté notre choix selon les projets

Sur une bibliothèque interne mise à jour rarement, et pour une équipe habituée aux mécanismes de Git, le sous-module a été préféré : la séparation nette entre le code métier et la bibliothèque partagée facilite la relecture. Sur un projet impliquant des développeurs moins familiers avec les subtilités des sous-modules, l'approche subtree a évité des erreurs récurrentes au clonage, au prix d'un historique plus difficile à lire.

- Une équipe restreinte et expérimentée tire pleinement parti de la clarté du sous-module.
- Une équipe plus large, avec un renouvellement fréquent, gagne en fiabilité avec l'approche subtree.
- Une bibliothèque mise à jour très fréquemment complique les deux approches ; la gestion via un gestionnaire de dépendances devient alors préférable.

> Ni le sous-module ni le subtree ne sont supérieurs dans l'absolu ; ils répondent à deux besoins différents de visibilité du code partagé.

## En résumé

Le sous-module Git garde une séparation nette entre le projet principal et la bibliothèque partagée, au prix d'une commande supplémentaire facilement oubliée. Le subtree fusionne tout dans un historique unique, plus transparent au clonage mais plus lourd à relire. Le choix dépend surtout de l'expérience de l'équipe avec Git et de la fréquence de mise à jour de la bibliothèque concernée.
