Git et les sous-modules
Lorsque vous développez un programme / système / logiciel, il n’est pas rare d’utiliser des bibliothèques / frameworks extérieurs au projet, aussi appelés des dépendances. Saviez vous que Git vous permettait de gérer ces dépendances en les intégrant comme sous-projet / sous-module de votre projet ? Nous verrons dans cet article comme cela se passe.
Ajout d’un sous-projet à votre dépôt Git
Comme dit dans l’intro, vous avez besoin d’intégrer une dépendance dans un de vos projets, pour cela rien de plus simple. Vous allez tout d’abord récupérer votre projet via la commande git clone
puis ajouter un sous-module via la commande git submodule add
.
$ git clone git://github.com/apapillon/projet.git $ cd projet ~/projet $ git submodule add git://github.com/apapillon/submodule.git submodule
En faisant une git status
au niveau de votre projet, vous verrez apparaître un nouveau fichier .gitmodules
~/projet $ git status Sur la branche master Votre branche est à jour avec 'origin/master'. Modifications qui seront validées : nouveau fichier : .gitmodules nouveau fichier : submodule
Le fichier .gitmodules
contient les références de votre sous-module.
[submodule "submodule"] path = submodule url = git://github.com/apapillon/submodule.git
Pour enregistrer ce lien, il faut ajouter le fichier .gitmodules
et le répertoire submodule
~/projet $ git add .gitmodules submodule ~/projet $ git commit -m "Ajout du lien avec le sous-module"
Travailler avec votre sous-module
Votre sous-module se comporte comme un projet à part entière, cela signifie qui vous pouvez concevoir des branches, faire des commits ainsi que des merges dans ce projet sans impacter votre projet mère.
~/projet $ git branch * master ~/projet $ cd submodule ~/projet/submodule $ git branch * master brsubmod ~/projet/submodule $ git branch brsubmod Basculement sur la branche 'brsubmod' ~/projet/submodule $ cd .. ~/projet $ git branch * master
Comme vous pouvez le voir dans l’exemple ci-dessus, notre projet mère est sur la branche master. Lorsque nous changeons de branche dans le répertoire du sous-module cela n’impacte pas le projet mère qui lui reste sur le master.
Pour moi, le gros avantage de la gestion des sous-modules est la possibilité de faire travailler des équipes différentes sur des parties différentes avec un système de releases entre les équipes. Imaginez un projet ou vous auriez une équipe dédiée au développement de drivers (équipe A) et une autre devant utiliser ces drivers (équipe B). Dans ce cas, votre équipe A pourrait développer son driver en créant des releases lors de chaque phase finale de développement. Votre équipe B n’aurait alors plus qu’à récupérer la release stable pour développer pendant que votre équipe A continue le développement normal de son driver.
~/projet $ cd submodule ~projet/submodule $ git checkout v1 La position précédente de HEAD était 680b237... Second commit - V2 HEAD est maintenant sur a6a38de... Premier commit - V1 ~projet/submodule $ cd .. ~projet $ git add submodule ~projet $ git commit -m "lien au tag v1 de submodule"
Ce mode de fonctionnement permet un meilleur rendu du code en améliorant sa maintenabilité et sa réusabilité. En effet, le code de votre équipe A peut être réutilisé dans un autre projet sans modification car non dépendant de votre projet initial.
Récupérer un projet utilisant les sous-modules
Si vous avez lu l’article jusqu’à cette ligne, vous avez sûrement voulu faire les tests / exemples. Si vous avez cloné mon github, vous avez pu remarquer que le clone ne charge pas le sous-module.
$ git clone https://github.com/apapillon/projet.git ~/projet $ ls -l total 8,0K -rw-r--r-- 1 perhonen perhonen 183 févr. 24 05:08 README.md drwxr-xr-x 2 perhonen perhonen 4,0K févr. 24 05:08 submodule ~/projet $ cd submodule ~/projet/submodule $ ls -l total 0
En effet, le répertoire de sous-module est vide. Il vous faut faire 2 commandes pour récupérer les sous-modules (je dis les car vous pouvez en avoir plusieurs). La commande git submodule init
récupère les liens vers les sous-modules inclus dans votre projet. La commande git submodule update
importe les fichiers des sous-modules dans leurs répertoires effectifs et dans la version annotée dans votre projet mère.
~/projet $ git submodule init Sous-module 'submodule' (git@github.com:apapillon/submodule.git) enregistré pour le chemin 'submodule' ~/projet $ git submodule update Clonage dans 'submodule'... remote: Counting objects: 8, done. remote: Compressing objects: 100% (4/4), done. remote: Total 8 (delta 0), reused 8 (delta 0), pack-reused 0 Réception d'objets: 100% (8/8), fait. Vérification de la connectivité... fait. Chemin de sous-module 'submodule' : 'a6a38dedb65978f30fce6ffbe59d2301607d4a9e' extrait
Lorsque vous travaillez en équipe, il est possible qu’une autre personne est changé la référence au sous-module. Il vous faudra donc recharger votre sous-module avec la commande git submodule update
sinon vous aurez une notification de modification sur le répertoire du sous-module.
~/projet $ git pull Depuis https://github.com/apapillon/projet 1f869ff..87fde66 master -> origin/master Mise à jour 1f869ff..87fde66 Fast-forward submodule | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ~/projet $ git status Sur la branche master Votre branche est à jour avec 'origin/master'. Modifications qui ne seront pas validées : modifié : submodule (nouveaux commits) ~/projet $ git submodule update Chemin de sous-module 'submodule' : '680b23780ce895e2a74943199610c03aae0cf215' extrait ~/projet $ git status Sur la branche master Votre branche est à jour avec 'origin/master'. rien à valider, la copie de travail est propre
Comme on peut le voir dans l’exemple ci-dessus, suite au git pull
le git status
nous indique que submodule est différent de ce qu’il a récupérer de la source. Il convient donc de faire un git submodule update
pour récupérer la bonne version du sous-module.
Si vous désirez plus de renseignements, je vous conseille vivement de lire la page dédié au sous-module dans la documentation Git.
Source: http://git-scm.com/book/fr/v1/Utilitaires-Git-Sous-modules