Close

Git subtree : l'alternative à git submodule

Portrait de Nicola Paolucci
NICOLA PAOLUCCI

Expert en développement


Internet regorge d'articles expliquant pourquoi vous ne devez pas utiliser les submodules Git. Les submodules sont utiles dans certains cas, mais ils ont plusieurs inconvénients.

Existe-t-il des alternatives ? La réponse est : oui ! Il existe (au moins) deux outils permettant de suivre l'historique des dépendances de logiciel dans votre projet tout en vous permettant de continuer à utiliser Git :

  • git subtree
  • google repo

Dans ce billet, j'explorerai git subtree et je vous expliquerai pourquoi il s'agit d'une avancée, bien qu'imparfaite, par rapport à git submodule.

Qu'est-ce que git subtree et pourquoi devrais-je l'utiliser ?


La commande git subtree vous permet d'imbriquer un dépôt à l'intérieur d'un autre sous la forme d'un sous-répertoire. C'est l'une des nombreuses façons dont les projets Git peuvent gérer les dépendances.

Diagramme avant/après l'utilisation de git subtree

Pourquoi vous pouvez envisager d'utiliser la commande git subtree

  • Il est facile de gérer un simple workflow.
  • Les anciennes versions de Git sont prises en charge (même avant v1.5.2).
  • Le code du sous-projet est disponible une fois que le superprojet est cloné.
  • git subtree n'exige pas que les utilisateurs de votre dépôt développent de nouvelles compétences. Ils peuvent ignorer le fait que vous utilisez git subtree pour gérer les dépendances.
  • git subtree n'ajoute pas de nouveaux fichiers de métadonnées comme le fait git submodule (p. ex., .gitmodule).
  • Le contenu du module peut être modifié sans avoir une copie de dépôt distincte de la dépendance à un autre emplacement.

Inconvénients (mais à notre avis, ils sont largement acceptables) :

  • Vous devez vous familiariser avec une nouvelle stratégie de merge (p. ex., git subtree).
  • Revenir à upstream pour les sous-projets peut s'avérer un peu plus compliqué.
  • C'est à vous de vous assurer de ne pas mélanger le code du superprojet avec celui du sous-projet.
Bases de données
Ressource connexe

Comment déplacer un dépôt Git complet

Logo Bitbucket
DÉCOUVRIR LA SOLUTION

Découvrir Git avec Bitbucket Cloud

Comment utiliser git subtree ?


git subtree est disponible avec la version de série de Git, disponible depuis mai 2012 (v1.7.11 ou version ultérieure). La version de Homebrew sous OS X comporte déjà une commande subtree prête à l'emploi. Sur certaines plateformes, il vous faudra cependant suivre les instructions d'installation.

Voici une utilisation classique de git subtree pour effectuer le suivi d'un plug-in vim.

La solution rapide sans suivi distant

Si vous souhaitez juste obtenir quelques commandes sur une ligne pour couper et coller, lisez ce paragraphe. Tout d'abord, ajoutez git subtree au niveau d'un dossier prefix spécifique :

git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

(La pratique courante consiste à ne pas stocker l'historique complet du sous-projet dans votre dépôt principal, mais si vous voulez le conserver, il vous suffit d'omettre le flag --squash.)

La commande ci-dessus génère la sortie suivante :

git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'

Comme vous pouvez le constater, un commit de merge est enregistré alors que l'historique complet du dépôt vim-surround est mergé dans un seul :

1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]

Si après un moment, vous souhaitez mettre à jour le code du plug-in issu du dépôt upstream, il vous suffit d'exécuter un pull git subtree :

git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

C'est très rapide et facile, mais les commandes sont un peu longues et difficiles à mémoriser. Nous pouvons les raccourcir en ajoutant le sous-projet en tant que remote.

Ajout du sous-projet en tant que remote

L'ajout du subtree en tant que remote nous permet d'y faire référence sous sa forme abrégée :

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Nous pouvons ajouter le subtree (comme avant), mais nous pouvons désormais faire référence au remote sous sa forme abrégée :

git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

On obtient alors cette commande de mise à jour du sous-projet à une date ultérieure :

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

Revenir à l'upstream

Désormais, nous pouvons librement commiter les corrections apportées au sous-projet dans notre répertoire de travail local. Quand le moment est venu de revenir au projet en amont, il faut faire un fork du projet et l'ajouter comme un autre remote :

git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git

À présent, nous pouvons utiliser la commande subtree push comme suit :

git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main

Ensuite, nous sommes prêts et nous pouvons ouvrir une pull request adressée au mainteneur du package.

Puis-je le faire sans l'aide de la commande git subtree ?

Oui, bien sûr que vous pouvez ! git subtree diffère de la stratégie de merge subtree. Vous pouvez toujours utiliser la stratégie de merge, même si git subtree n'est plus disponible pour une raison ou une autre. Voici comment procéder.

Ajoutez la dépendance comme un simple git remote :

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Avant de consigner le contenu de la dépendance dans le dépôt, il est important d'enregistrer un merge pour pouvoir suivre l'arborescence complète du plug-in jusqu'au point suivant :

git merge -s ours --no-commit tpope-vim-surround/main

Qui génère :

Automatic merge went well; stopped before committing as requested

Ensuite, nous consignons le contenu du dernier objet arbre dans le dépôt du plug-in dans notre répertoire de travail prêt à être commité :

git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main

À présent, nous pouvons faire un commit (il s'agira d'un commit de merge qui conservera l'historique de l'arborescence consigné) :

git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround

Pour mettre à jour le projet, vous pouvez maintenant faire un pull en utilisant la stratégie de merge git subtree :

git pull -s subtree tpope-vim-surround main

La commande git subtree est une excellente alternative


J'ai utilisé les submodules Git pendant un certain temps, et vous verrez que git subtree résout de nombreux problèmes qui leur sont liés. Comme d'habitude et comme avec tout dans Git, il faut passer par une phase d'apprentissage pour tirer le meilleur parti de la fonctionnalité.

Suivez-moi sur Twitter @durdn pour en savoir plus sur Git. Et découvrez Atlassian Bitbucket si vous recherchez un bon outil pour gérer vos dépôts Git.

Mise à jour : après avoir publié cet article, j'ai également écrit un article sur la puissance de git subtree.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Partager cet article
Thème suivant

Lectures recommandées

Ajoutez ces ressources à vos favoris pour en savoir plus sur les types d'équipes DevOps, ou pour les mises à jour continues de DevOps chez Atlassian.

Des personnes qui collaborent à l'aide d'un mur rempli d'outils

Le blog Bitbucket

Illustration DevOps

Parcours de formation DevOps

Démos Des démos avec des partenaires d'Atlassian

Fonctionnement de Bitbucket Cloud avec Atlassian Open DevOps

Inscrivez-vous à notre newsletter DevOps

Thank you for signing up