Quoi de neuf dans Git 2.30 ?
Par Maxime Bréhin • Publié le 19 janvier 2021 • 3 min

À chaque nouvelle version mineure de Git son lot de nouveautés. Git 2.30 est sortie le 28 décembre 2020 et apporte quelques petites choses utiles. Voici notre sélection de celles qu’on trouve sympa.

Des userdiff à jour

Vous ne le savez peut-être pas, mais Git embarque une partie d’analyse syntaxique pour certains langages, ce qui lui permet de proposer des diffs avec un affichage adapté au contexte (en en-tête des blocs). Dans cette nouvelle version, les affichages de diff ont été améliorés pour CSS, PHP et Rust.

Voyez dans l’exemple qui suit le contexte des blocs CSS donnés avant chaque hunk (portion de bloc modifiée). Prenez le dernier bloc : la différence affichée n’inclut pas la définition de la règle CSS correspondante. Néanmoins l’en-tête de diff nous donne cette info : footer a:visited.

Diff CSS avec en-têtes contextuelles

Filtrer les blocs de diff à l’aide d’une expression rationnelle

On se retrouve parfois avec des diffs importants dont ne souhaitons pas visualiser la totalité. Pour éviter ça, il existe depuis longtemps des options de configuration pour spécifier certains comportements.

Par exemple on peut spécifier quels problèmes d’espacements Git doit considérer. On peut passer sous silence les différences d’espacements en fin de lignes et lignes vierges en fin de fichier avec la configuration globale git config --global core.whitespace -trailing-space.

Git 2.30 apporte un autre comportement utilisable uniquement en ligne de commande afin de ne pas afficher les blocs de modifications (hunks) qui comprendraient certains contenus désignés par une expression rationnelle.

Voici un exemple basé sur l’exemple du diff CSS décrit avant : je ne souhaite pas afficher les blocs contenant des modifications sur les largeurs (width) et les marges (margin).

git diff -I'(width|margin)'

Diff avec blocs filtrés

Forcer le push sans écraser

Pour éviter de rendre vos collègues furax 😤 parce que vous avez forcé le push, peut-être utilisiez-vous déjà git push --force-with-lease (qu’on préfèrerait avoir en option de forçage courte plutôt que --force qui écrase sans se poser de question).

Ce --force-with-lease est très pratique à un petit détail près : si on fait une synchro fetch avec le dépôt distant avant le forçage, on peut malgré tout écraser le travail des autres. Une nouvelle option complémentaire s’ajoute donc pour éviter cela : --force-if-includes. Bon clairement ça devient lourd de multiplier les options pour un comportement qu’on peut juger normal, mais l’évolution progressive de Git et son besoin en compatibilité ascendante impose ces pratiques. Heureusement on a toujours les aliases pour nous aider à gérer tout ça plus facilement : git config --global alias.push-with-lease 'push --force-with-lease --force-if-includes'.

Pour mieux comprendre l’intérêt de cette option, revoyons l’action au ralenti :

1. Camille partage ses commits

Après avoir réalisé un premier commit sur la branche dev, Camille le partage.

Forcer le push : premier partage de Camille

2. Noah bosse et partage à son tour

Noah crée 2 commits de son côté sur cette même branche dev puis récupère les nouveautés publiées par Camille (pull)…

Forcer le push : Noah crée 2 commits et se synchronise

…avant de partager à son tour ses commits.

Forcer le push : Noah partage ses 2 commits

3. Pendant ce temps, Camille travaille

Camille produit 2 nouveaux commits…

Forcer le push : Camille crée 2 autres commits

…puis récupère les derniers ajouts de Noah, mais sans les appliquer localement (fetch). C’est ce dernier point qui ouvre une brèche dans les protections de --force-with-lease.

Forcer le push : Camille récupère les commits de Noah

Camille tente alors d’envoyer son travail avec l’option de forçage “douce”, pensant qu’en cas d’oubli de synchronisation son historique n’écrasera pas celui sur le serveur.  Et là, c’est le drame ! Le fetch précédent rend caduc ce qu’on attendait de l’option, les commits de Noah sont écrasés sur le serveur.

Forcer le push : Camille "écrase" les commits de Noah

L’emploi du complément d’option --force-if-includes aurait évité cette perte en interdisant l’envoi, indiquant le rejet et la raison : remote ref updated since checkout (référence du dépôt distant mise à jour depuis la dernière application locale).

Forcer le push : le push est interdit grâce à l'option "--force-if-includes"

Évolution de la liste des worktrees : affichage du statut verrouillé

Les worktrees permettent de travailler en simultané sur plusieurs branches d’un même dépôt local en créant une copie de l’espace de travail pointant sur le même dépôt local, mais sur une autre branche.

Par exemple la commande git worktree add -b dev ../project-dev créera un répertoire projet au même niveau que notre répertoire projet actuel après avoir créé une nouvelle branche dev pour travailler dessus.

Principe des worktrees

Un worktree peut ne pas être toujours accessible (placé sur un support intermittent comme un partage réseau, un disque dur externe ou une clé USB). Dans ce cas vous aurez peut-être choisi d’empêcher les opérations de nettoyage qui pourraient être déclenchées par Git en verrouillant ce worktree :

git worktree lock --reason 'Clé USB' ../project-dev/

Cette information de verrouillage n’était jusqu’à présent pas disponible à l’affiche des la liste des worktree. Git 2.30 a donc fait évoluer celui-ci : git worktree list.

/path/to/project      c0da886 [master]
/path/to/project-dev  0eaab3e [dev] locked

Tout savoir sur Git 2.30

Il y a toujours plus à dire sur une nouvelle version. Aussi pouvez-vous consulter directement la release note.

Tu veux aller plus loin et maîtriser pleinement les fondamentaux de Git ou être accompagné pour garantir la qualité de tes projets grâce à une bonne mise en place de Git ? On peut t’aider ou te former, il suffit de nous décrire ton besoin !