Git avancé : recherche et diagnostic
Git est aussi un outil d’enquête : retrouver quand, pourquoi et par qui une ligne a changé, et quel commit a introduit un bogue.
git log : filtrer
Section intitulée « git log : filtrer »git log --oneline --graph --decorate --all -30git log --since="2 weeks ago" --until="yesterday"git log --author="Alice"git log --grep="correction" -i # dans le messagegit log --no-merges # sans les commits de fusiongit log --first-parent main # suivre seulement la branche principalegit log -- src/app.js # commits qui touchent un fichiergit log --follow -- src/app.js # suit le fichier malgré les renommagesgit log main..fonctionnalite # commits de la branche absents de maingit log --diff-filter=D --name-only # fichiers supprimésgit log --stat # fichiers modifiés par commitgit log -p -3 # patch des 3 derniers commitsgit log --pretty=format:'%h %ad %an : %s' --date=shortgit log --pretty=format:'%C(yellow)%h%Creset %C(green)%ad%Creset %s %C(blue)<%an>%Creset' --date=shortgit config --global alias.lg "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(auto)%d%Creset %s %C(green)(%cr) %C(blue)<%an>%Creset' --abbrev-commit"| Code | Contenu |
|---|---|
%h / %H |
Empreinte courte / complète |
%an, %ae |
Auteur, e-mail |
%ad, %cr |
Date, date relative |
%s, %b |
Sujet, corps |
%d |
Références (branches, étiquettes) |
git blame : qui a écrit cette ligne ?
Section intitulée « git blame : qui a écrit cette ligne ? »git blame src/app.jsgit blame -L 40,60 src/app.js # lignes 40 à 60git blame -w src/app.js # ignore les changements d'espacesgit blame -M src/app.js # détecte le code déplacé dans le fichiergit blame -C -C src/app.js # détecte le code copié depuis d'autres fichiersgit blame --ignore-rev a1b2c3d src/app.js # ignore un commit (reformatage global)git blame --ignore-revs-file .git-blame-ignore-revs src/app.jsgit config --global blame.ignoreRevsFile .git-blame-ignore-revs.git-blame-ignore-revs liste les commits de reformatage massif (Prettier : intégration continue et hooks) pour qu’ils n’apparaissent plus comme auteurs de chaque ligne.
blame indique le dernier commit qui a touché la ligne, pas forcément son origine : suivre avec git show <commit> puis git blame <commit>^ -- fichier pour remonter plus loin.
Pickaxe : quand cette chaîne est-elle apparue ou disparue ?
Section intitulée « Pickaxe : quand cette chaîne est-elle apparue ou disparue ? »git log -S"calculerTotal" --oneline # commits qui changent le NOMBRE d'occurrencesgit log -S"calculerTotal" -p # avec le patchgit log -G"calculer(Total|Remise)" --oneline # expression régulière dans les lignes modifiéesgit log -S"timeout" --pickaxe-regex -- src/ # -S avec expression régulière| Option | Détecte |
|---|---|
-S<texte> |
Un commit qui ajoute ou retire une occurrence du texte |
-G<regex> |
Un commit dont le patch contient une ligne correspondant à la regex |
Parfait pour retrouver quand une fonction a été supprimée ou quand une constante a été introduite.
git log -L : l’historique d’une fonction
Section intitulée « git log -L : l’historique d’une fonction »git log -L :calculerTotal:src/panier.js # évolution de la fonctiongit log -L 20,45:src/panier.js # évolution des lignes 20 à 45Affiche chaque commit qui a modifié ce passage, avec le patch limité à ce passage : bien plus précis qu’un git log -p fichier.
git grep : chercher dans le code
Section intitulée « git grep : chercher dans le code »git grep "TODO"git grep -n -i "motdepasse" -- '*.js'git grep -c "console.log" # nombre d'occurrences par fichiergit grep "calculerTotal" a1b2c3d # dans une version passéegit grep -e "foo" --and -e "bar" # les deux sur la même lignegit grep --heading --break -n "export default"Plus rapide que grep -r (il ne lit que les fichiers suivis) et il sait chercher dans n’importe quelle révision.
git bisect : trouver le commit fautif
Section intitulée « git bisect : trouver le commit fautif »Rappel des bases : Annuler et corriger. Version automatique :
git bisect startgit bisect bad # le commit actuel est fautifgit bisect good v1.2.0 # une version connue pour fonctionnergit bisect run npm test # Git teste chaque étape tout seulgit bisect log # historique de la recherchegit bisect reset # revenir à la branche d'originegit bisect run exécute la commande à chaque étape : code de sortie 0 = bon, 1 à 127 (sauf 125) = mauvais, 125 = commit impossible à tester (à sauter). Pour un script de test dédié :
cat > /tmp/test-bogue.sh <<'SCRIPT'#!/bin/shnpm ci --silent && node scripts/reproduire-le-bogue.jsSCRIPTchmod +x /tmp/test-bogue.shgit bisect start HEAD v1.2.0git bisect run /tmp/test-bogue.shUn historique de commits atomiques qui compilent tous rend bisect très efficace (c’est un argument supplémentaire en faveur des commits propres : Rebase et historique).
Statistiques et synthèses
Section intitulée « Statistiques et synthèses »git shortlog -sn --no-merges # commits par auteurgit shortlog -sn --since="1 year ago"git log --format='%an' | sort | uniq -c | sort -rn | headgit diff --stat main...fonctionnalitegit diff --numstat main...fonctionnalitegit log --since="1 month ago" --name-only --pretty=format: | sort | uniq -c | sort -rn | head # fichiers les plus modifiésgit describe --tags # version la plus proche (v1.2.0-14-ga1b2c3d)git tag --contains a1b2c3d # dans quelles versions se trouve ce commitgit branch --contains a1b2c3d -a # dans quelles branchesgit rev-list --count main..fonctionnalite # nombre de commits d'avancegit describe donne un nom lisible pour un commit ; git tag --contains répond à « dans quelle version cette correction est-elle arrivée ? ».
Comparer
Section intitulée « Comparer »git diff # dossier de travail contre l'indexgit diff --staged # index contre le dernier commitgit diff a1b2c3d f4e5d6c -- src/ # deux révisionsgit diff main...fonctionnalite # depuis l'ancêtre commungit diff --word-diff # différences mot par motgit diff --color-moved # met en évidence le code déplacégit diff -w --ignore-blank-linesgit diff --name-status main # fichiers ajoutés, modifiés, supprimésgit diff --check # espaces en fin de ligne, marqueurs de conflit oubliésgit config --global diff.algorithm histogram # algorithme de comparaison souvent plus lisiblegit range-diff main@{1} main fonctionnalite # comparer deux versions d'une branche réécritegit range-diff compare deux séries de commits (avant et après un rebase) : idéal pour relire les changements d’une demande de fusion mise à jour.
Retrouver l’origine d’une régression : méthode
Section intitulée « Retrouver l’origine d’une régression : méthode »- Reproduire le bogue avec une commande (un test qui échoue).
- Identifier une version bonne (étiquette, date) et une mauvaise.
git bisect runavec cette commande.- Lire le commit trouvé (
git show), vérifier pourquoi il casse. - Ajouter un test qui échoue sans la correction, puis corriger.
Chercher dans les messages
Section intitulée « Chercher dans les messages »git log --all --grep="issue #42" -igit log --all --oneline | grep -i "migration"git log -i --grep="^fix" --oneline # conventions de messages (voir commitlint)git log --format='%s' | grep -E '^(feat|fix)' | wc -lDes messages au format Conventional Commits (Husky : commitlint) rendent ces recherches fiables.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
git log -- fichier ne montre rien |
Fichier renommé : --follow, ou chemin incorrect |
blame pointe un commit de reformatage |
--ignore-revs-file |
bisect ne converge pas |
Test non déterministe, ou commit impossible à compiler : git bisect skip (ou code 125) |
git log -S ne trouve pas |
-S compte les occurrences : un déplacement sans changement de nombre n’est pas vu ; essayer -G |
git grep ne trouve pas un fichier récent |
Fichier non suivi : git add -N ou git grep --untracked |
| Sortie très longue | git --no-pager, ou git config --global core.pager "less -FRX" |
fatal: ambiguous argument |
Référence et chemin confondus : git log branche -- chemin |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune propre à Ubuntu ; range-diff et --color-moved demandent des versions récentes de Git, présentes sur les deux versions.