Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Git
  3. Les outils de Git
Extrait - Git Maîtrisez la gestion de vos versions (concepts, utilisation et cas pratiques) (4e édition)
Extraits du livre
Git Maîtrisez la gestion de vos versions (concepts, utilisation et cas pratiques) (4e édition) Revenir à la page d'achat du livre

Les outils de Git

Mettre de côté des modifications avec git stash

Il arrive régulièrement qu’un développeur soit dérangé pendant qu’il travaille sur une nouvelle fonctionnalité. C’est souvent en raison d’un mail débutant par le mot "URGENT" que le développeur doit stopper son développement pour corriger un bug éventuel.

Seulement, le développeur ne doit pas commiter son développement pour corriger le bug. Ce commit serait alors composé de modifications non terminées avec un code non fonctionnel et peut-être des lignes de débogage. Un commit ne doit être effectué que lorsque le projet a été testé et est fonctionnel, ce qui ne correspond pas à un travail en cours.

git stash peut avoir plusieurs utilités. Imaginons le cas d’un développeur qui souhaite faire une démonstration client (sans l’avoir prévue à l’avance). Le développeur était en plein développement et certaines pages retournent encore une page d’erreur. En utilisant git stash, le développeur remet son projet dans le même état qu’après son dernier commit tout en conservant son développement en cours pour une prochaine fois. Le développeur peut alors faire sa démonstration facilement et rapidement sans faire attendre le client.

git stash va garder toutes les modifications de côté. Elles ne seront plus présentes dans le répertoire de travail et l’index, elles ne seront pas non plus présentes dans l’historique, car elles n’auront jamais été commitées.

Pour tester git stash avec un exemple, il convient de créer un dépôt dans un nouveau dossier :

mkdir git_stash  
cd git_stash  
git init  ...

Dépôts intégrés avec submodules

Aujourd’hui, dans un grand nombre de projets, les développeurs utilisent des bibliothèques. Par exemple, beaucoup de projets web aujourd’hui intègrent des bibliothèques comme jQuery, Bootstrap ou encore AngularJS. Ces bibliothèques sont nécessaires au fonctionnement du projet, il est donc important de les avoir dans notre dépôt principal (à moins d’utiliser les services d’un CDN qui les héberge).

Le problème qui se pose lorsque les développeurs ajoutent les sources de la bibliothèque directement dans leur dépôt principal est que ces codes vont polluer les commits et les statistiques du dépôt avec du code qui n’a pas été créé par un développeur interne.

En effet, avec les sources directement présentes dans leur dépôt, à chaque mise à jour de la bibliothèque les développeurs devront copier les nouveaux fichiers de la bibliothèque et faire un commit volumineux avec comme message "Mise à jour vers Bootstrap 3.3.0".

Le dépôt contiendrait donc des commits qui ne correspondent pas du tout au projet et qui ne sont pas le fruit du travail de l’équipe de développement. De plus, si des statistiques sont effectuées sur le dépôt, les ajouts et mises à jour des bibliothèques les fausseraient.

Il existe des solutions à ce problème. La solution la plus adaptée est d’utiliser un système de gestion de dépendances versionné. Un tel système permettra de lister les bibliothèques dont les développeurs ont besoin et de spécifier la version utilisée dans le projet. Par exemple, dans un projet Python, l’outil de gestion de dépendances...

Retrouver un commit erroné

Dans tout type de développement, il arrive des cas où un développeur ajoute une régression dans son code. Une régression signifie que lors du développement d’une fonctionnalité ou lors de la correction d’un bug, les modifications du développeur ont eu pour effet de rendre une autre partie du logiciel non fonctionnelle. Les régressions sont ajoutées sans que le développeur ne s’en rende compte, et si aucun test unitaire ou fonctionnel n’est là pour détecter ce type d’erreur, alors celle-ci reste présente jusqu’à ce qu’un utilisateur ou un développeur remonte le problème.

Git aide le développeur à retrouver le commit qui a ajouté la régression par une recherche dichotomique. À chaque étape de git bisect, Git va remplacer le répertoire de travail par une ancienne version et il faut alors lui indiquer si l’erreur est toujours présente. Il va alors restreindre le nombre de commits qui sont susceptibles d’avoir ajouté l’erreur puis va effectuer une itération en modifiant à nouveau le répertoire de travail.

Une recherche dichotomique est un algorithme de recherche qui consiste à couper une plage de valeurs en deux parties égales à chaque étape. À la fin de chaque étape, on ne garde qu’une moitié comme plage de solutions acceptables puis on effectue une nouvelle étape pour amoindrir la plage de solutions.

1. Utilisation pratique de git bisect

Pour expliquer comment fonctionne la commande git bisect, il est préférable de montrer son fonctionnement au travers d’un exemple concret et pratique. L’exemple ci-dessous a été produit à partir du dépôt...

Journal des références (reflog)

Avant de parler du journal des références, il est utile de rappeler que HEAD est une référence (c’est-à-dire un pointeur) qui pointe vers le commit le plus récent de la branche courante.

Il existe un journal de toutes les références prises par le pointeur HEAD dans Git qui s’appelle le reflog (raccourci de log de référence). C’est un journal qui va enregistrer tous les commits par lesquels passe ce pointeur. Le reflog va par exemple être capable d’enregistrer les changements de branche ou alors l’ajout de commit.

Pour visualiser ce journal, il faut utiliser la commande suivante :

git reflog 

Utilisée sur le dépôt de la partie consacrée à git bisect de ce chapitre, cette commande affiche la sortie suivante :

1f28629 HEAD@{0}: checkout: moving from 
be902d9cc6cacfc7a927a8a07a5774a6aff6f0b4 to master  
be902d9 HEAD@{1}: checkout: moving from d42018b585c7a5b6b3593031
faaefb09376bb14c to be902d9cc6cacfc7a927a8a07a5774a6aff6f0b4  
d42018b HEAD@{2}: checkout: moving from 
5b9094ff2f09fb74ec6c9965bdd02f6b6666ab88 to 
d42018b585c7a5b6b3593031faaefb09376bb14c  
... Sortie tronquée ...  
d42018b HEAD@{21}: commit: LICENCE : ajout  
2992238 HEAD@{22}: commit: README : ajout de détails  
a894f82 HEAD@{23}: commit (initial): README : ajout 

La première partie de la sortie a été générée par les changements successifs de git bisect dans l’exemple précédent. La deuxième partie correspond aux commits effectués au début du projet.

L’intérêt principal du reflog est de pouvoir retrouver tous les états par lesquels est passé le répertoire de travail....

Les hooks

Les hooks sont des scripts qui sont exécutés lors d’actions spécifiques sur le dépôt. Ils permettent d’automatiser certaines tâches récurrentes comme la minification de fichiers JavaScript, la vérification du message de commit ou encore l’exécution de tests automatisés. Parfois, les hooks sont également appelés des crochets dans le but de franciser ce terme. Cependant, dans de nombreuses entreprises, le terme « hook » reste largement utilisé.

1. Les différents types de hooks

Les hooks peuvent être séparés en deux familles différentes :

  • les hooks côté serveur,

  • les hooks côté client.

Les hooks côté serveur sont exécutés sur les dépôts distants. Ils permettent d’effectuer des actions telles que :

  • vérifier que l’utilisateur a le droit de pusher vers une branche,

  • déployer une nouvelle version du projet.

Les hooks côté client sont exécutés sur les dépôts locaux et permettent d’effectuer des actions telles que :

  • minifier des fichiers JS/CSS après un changement de branche,

  • vérifier la syntaxe des fichiers,

  • lancer les tests automatisés.

Chaque hook est identifié par un nom qui définit le moment où Git l’exécutera.

Les hooks côté serveur sont les suivants :

  • pre-receive : ce hook est exécuté par le serveur au début de la réception d’un push. Il sert à vérifier que la politique de push est bien respectée (commit conforme aux bonnes pratiques, droit de push sur la branche, etc.). Le push peut être refusé si les conditions du hook ne sont pas remplies.

  • post-receive : ce hook est exécuté...

Les notes Git

Git propose un système permettant d’attribuer des commentaires à des commits. Ce système de notes ne remplace absolument pas le message de commit. Contrairement aux messages de commit, les notes Git ne modifient pas le commit. Les notes sont attachées à un commit sans le modifier. Cela permet par exemple d’ajouter des détails concernant un commit ou encore de suivre les revues de code d’un commit.

Dans une équipe utilisant Gt-Flow, il est d’ailleurs tout à fait possible au dernier commit des branches hotfix d’ajouter une note avec un flag #readyToDeploy pour spécifier que le commit est prêt à être déployé. Ce type de flag n’aurait rien à faire dans un message de commit car il ne pourrait pas être supprimé, alors qu’avec les notes c’est possible.

1. Créer une note

Pour créer une note sur un commit, il faut utiliser la commande suivante :

git notes add <commit> 

Il est possible d’utiliser l’argument -m pour définir le message ou alors de laisser Git ouvrir l’éditeur de texte.

Une fois le message validé, Git crée un nouvel objet correspondant au message et l’attache au commit. Il faut rester vigilant lorsqu’on enregistre une note sur un commit à partir d’une référence dynamique. Une note enregistrée sur master ne correspondra plus à master lorsqu’un nouveau commit y aura été ajouté.

2. Afficher les notes

Il existe plusieurs moyens de consulter les notes à utiliser en fonction du besoin. 

a. Lister les notes

Pour lister les notes du dépôt, il faut utiliser la commande suivante :

git notes list 

Cette commande affiche la sortie suivante :

632e4fe73c3da8c9018008dbda117fc6b00e3e83  
f846282cd4dcf33be050d8d405bfbfc71ba3391c ...