Tutoriel

git log, diff, show et blame : lire l'historique d'un projet Git

Mis à jour: · Skillaria.Top

git log affiche la liste des commits et sait les filtrer par auteur, date, fichier et texte ; git diff compare le répertoire de travail, l'index et n'importe quels commits ; git show affiche un commit en entier ; git blame indique quel commit a modifié en dernier chaque ligne d'un fichier.

Quatre commandes répondent à presque toutes les questions sur l'historique d'un projet. git log répond à « que s'est-il passé », git diff à « qu'est-ce qui a changé exactement », git show à « que contient ce commit précis », git blame à « qui a écrit cette ligne et quand ». Voici les techniques utiles pour chacune, avec les options réellement employées au quotidien.

git log : la liste des commits

Sans argument, git log affiche les commits de la branche courante, du plus récent au plus ancien : hash SHA-1 complet, auteur, date et message. La sortie défile dans un pager (généralement less) : espace pour la page suivante, /texte pour chercher, q pour quitter.

commit 7be41d0c9a2e4f1b8d6c3e5a7f9b0c2d4e6f8a1b
Author: Anna Petrova <anna@example.com>
Date:   Mon Oct 5 14:22:10 2026 +0300

    feat: mise en cache des réponses de l'API

Inutile de copier le hash en entier : Git accepte tout préfixe unique d'au moins 4 caractères ; en pratique, 7 suffisent.

Sortie compacte : --oneline

git log --oneline -10
# 7be41d0 (HEAD -> main, origin/main) feat: mise en cache des réponses de l'API
# 1c02e8f fix: timeout des requêtes
# 9a4b3c2 refactor: client extrait dans un module

L'option -10 (ou -n 10) limite le nombre de commits. Entre parenthèses figurent les références : où se trouvent HEAD, les branches locales et distantes, les tags.

Graphe des branches : git log --graph

La recherche « git graph » désigne généralement ceci : la visualisation des branches et des fusions directement dans le terminal.

git log --oneline --graph --all
# * 3e1f0aa (feature/auth) feat: connexion par token
# | * 7be41d0 (HEAD -> main) feat: mise en cache des réponses de l'API
# |/
# * 1c02e8f fix: timeout des requêtes
# *   5d2c7b1 Merge branch 'feature/search'
# |\
# | * 8f3a9e0 feat: recherche
# |/
# * 9a4b3c2 refactor: client extrait dans un module

--all affiche toutes les branches, pas seulement la courante. Pratique d'en faire un alias : git config --global alias.lg "log --oneline --graph --all --decorate", puis un simple git lg suffit.

Format personnalisé : --pretty=format

git log --pretty=format:"%h %ad %an %s" --date=short
# 7be41d0 2026-10-05 Anna Petrova feat: mise en cache des réponses de l'API

Principaux paramètres : %h — hash court, %H — hash complet, %an — auteur, %ae — son e-mail, %ad — date de l'auteur, %ar — date relative (« 2 days ago »), %s — titre du message.

Filtrer l'historique avec git log

Par auteur et par date

git log --author="Anna"
git log --since="2 weeks ago" --until="2026-10-01"
git log --since=yesterday --oneline

--author accepte une expression régulière et cherche dans le nom et l'e-mail. Git comprend les dates en langage libre comme au format ISO.

Par texte du message

git log --grep="fix" -i --oneline

-i rend la recherche insensible à la casse. Si votre équipe met les numéros de ticket dans les messages, vous retrouvez ainsi rapidement tous les commits d'un ticket.

Par fichier ou dossier

git log --oneline -- src/api/client.py
git log --follow -p -- src/api/client.py

Le double tiret sépare les chemins des branches. --follow suit l'historique du fichier à travers les renommages (pour un seul fichier), -p affiche le patch de chaque commit.

Par code modifié : la recherche « pioche »

git log -S "retry_count" --oneline     # commits où le nombre d'occurrences de la chaîne a changé
git log -G "timeout\s*=" --oneline    # commits dont le diff contient des lignes correspondant à la regex

-S trouve le commit où une fonction ou une variable a été ajoutée ou supprimée — indispensable pour comprendre où est passé un morceau de code.

Plages de commits

git log main..feature      # ce qui est dans feature mais pas dans main
git log origin/main..HEAD  # mes commits locaux pas encore poussés
git log --no-merges        # sans les commits de merge
git log --stat             # fichiers modifiés et nombre de lignes

git diff : qu'est-ce qui a changé exactement

L'essentiel à comprendre sur git diff : quels deux états il compare. La confusion ici explique la question « pourquoi le diff est vide alors que j'ai tout modifié ».

CommandeCe qu'elle compare
git diffrépertoire de travail contre index (modifications non indexées)
git diff --staged (--cached)index contre dernier commit (ce qui entrera dans le commit)
git diff HEADrépertoire de travail contre dernier commit (tout ensemble)
git diff A Bdeux commits, branches ou tags
git diff A...Bles changements de B depuis sa divergence avec A

Après un git add, le git diff simple devient vide — les modifications sont dans l'index, regardez --staged. Les fichiers nouveaux, jamais ajoutés, n'apparaissent pas du tout dans le diff.

Lire la sortie d'un diff

diff --git a/config.py b/config.py
index 3b18e51..a1c4f02 100644
--- a/config.py
+++ b/config.py
@@ -10,7 +10,7 @@ DEFAULTS = {
     "host": "localhost",
-    "timeout": 5,
+    "timeout": 30,
     "retries": 3,

Les lignes avec - sont supprimées, celles avec + ajoutées, les autres servent de contexte. L'en-tête @@ -10,7 +10,7 @@ signifie : le fragment commence à la ligne 10 et occupe 7 lignes dans l'ancienne et la nouvelle version.

Options utiles de git diff

git diff --stat main feature      # résumé par fichier
git diff --name-only HEAD~3       # seulement les noms des fichiers modifiés
git diff --word-diff               # changements mot par mot, pratique pour les textes
git diff -w                        # ignorer les changements d'espaces
git diff main feature -- src/      # limiter à un dossier

Avant chaque commit, regardez git diff --staged : c'est la dernière chance de repérer un print de débogage ou un fichier ajouté par erreur.

git show : un commit en entier

git show affiche les métadonnées d'un commit et son diff par rapport au parent. Sans argument — le dernier commit.

git show 7be41d0
git show HEAD~2 --stat           # sans patch, juste le résumé
git show v1.2.0                  # tag : annotation et commit
git show main:src/config.py      # le fichier tel qu'il était dans ce commit

La dernière forme <révision>:<chemin> est particulièrement utile : elle montre une ancienne version d'un fichier sans basculer dessus. Redirigez la sortie vers un fichier et vous récupérez un contenu supprimé sans checkout.

git blame : qui a modifié cette ligne

git blame fichier affiche pour chaque ligne le dernier commit qui l'a modifiée, son auteur et sa date. Le nom sonne accusateur, mais c'est en réalité un outil de recherche de contexte : trouver le commit, lire son message et comprendre pourquoi le code est ainsi.

git blame -L 40,60 src/api/client.py
# 1c02e8f3 (Anna Petrova 2026-09-28 11:04:51 +0300 41)     timeout = settings.timeout
# 9a4b3c2e (Ivan Smirnov 2026-09-14 18:30:02 +0300 42)     session = build_session()
  • -L 40,60 — seulement une plage de lignes ; -L :nom_fonction fonctionne aussi.
  • -w — ignorer les changements d'espaces, pour ne pas tomber sur des commits de formatage.
  • -C — suivre les lignes déplacées depuis d'autres fichiers.
  • --ignore-rev <hash> ou le fichier .git-blame-ignore-revs — ignorer les commits massifs comme un reformatage automatique.

Scénario d'enquête type : git blame trouve le commit, git show l'affiche en entier, git log sur le fichier montre les modifications voisines.

On peut désigner des commits autrement que par leur hash. HEAD~1 est le parent du commit courant, HEAD~3 l'arrière-grand-parent. HEAD^2 est le second parent d'un commit de merge. Les noms de branches, de tags et de branches distantes fonctionnent aussi : origin/main~2. Pour voir tout le projet à un ancien commit : git switch --detach <hash> ; pour revenir : git switch -.

Bon et mauvais historique

Toutes ces commandes ne valent que ce que vaut l'historique. Des messages comme « fix », « wip », « encore des modifs » rendent git log --grep et git blame inutiles. Un bon commit = un changement logique et un titre qui explique quoi et pourquoi : fix: timeout de l'API porté à 30 s à cause d'une passerelle lente. Dans six mois, c'est ce commit que blame retrouvera, et il vous fera gagner une heure.

En pratique : enquêter sur un bug grâce à l'historique

Supposons qu'après une release, les requêtes vers l'API se mettent à échouer par timeout. Voici comment l'enchaînement des commandes mène à la cause en deux minutes.

  1. On regarde ce que contient la release : git log v1.4.0..v1.5.0 --oneline. La liste est courte, mais les titres ne désignent pas de coupable évident.
  2. On restreint au fichier : git log v1.4.0..v1.5.0 --oneline -- src/api/. Il reste deux commits.
  3. On cherche dans le code : git log -S "timeout" --oneline -- src/api/ trouve le commit où la valeur du timeout a changé.
  4. On l'affiche en entier : git show 1c02e8f. Le diff montre que le timeout est passé de 30 à 5 secondes, avec pour explication « accélérer la réactivité de l'UI ».
  5. On vérifie qui d'autre a touché cette ligne : git blame -L :build_session src/api/client.py.

La suite relève de l'ingénierie : restaurer la valeur, déplacer le timeout dans la configuration ou annuler le commit avec git revert. Et si les commits se comptent par centaines et que le coupable est introuvable à l'œil, git bisect vient à la rescousse — une recherche dichotomique dans l'historique qui désigne en quelques étapes le commit ayant cassé le comportement.

Réglages qui facilitent la vie

git config --global log.date iso            # format des dates dans log
git config --global diff.colorMoved zebra   # mise en évidence des lignes déplacées dans le diff
git config --global core.pager "less -FRX"  # ne pas ouvrir le pager pour une sortie courte

Si la sortie doit être traitée par un script, désactivez couleurs et pager : git --no-pager log --format="%H %s" --no-color. Pour un traitement automatisé, utilisez le hash complet %H : les préfixes courts peuvent devenir ambigus avec le temps dans un gros dépôt.

Conclusion

git log, avec les filtres --oneline, --graph, --author, -S et les chemins, répond à la question « que s'est-il passé ». git diff compare répertoire de travail, index et commits — l'essentiel est de se rappeler ce qu'il compare par défaut. git show détaille un commit ou une ancienne version de fichier, et git blame remonte d'une ligne de code à la décision qui l'a produite. La lecture de l'historique et la navigation entre commits sont pratiquées dans le cours Git.

Questions fréquentes

Comment quitter git log ?

Appuyez sur q — la sortie est ouverte dans le pager less ; pour afficher sans pager, utilisez git --no-pager log ou l'option -n avec un petit nombre.

Comment voir l'historique d'un fichier supprimé ?

Lancez git log --oneline -- chemin/vers/fichier (avec le double tiret), et pour le contenu avant suppression — git show &lt;hash&gt;^:chemin/vers/fichier.

Comment comparer une branche locale avec la branche distante ?

D'abord git fetch, puis git diff origin/main ou git log origin/main..HEAD pour voir vos commits non poussés.

Existe-t-il un affichage graphique de l'historique ?

Oui, gitk est fourni avec Git, et un graphe de l'historique est intégré à VS Code, aux IDE JetBrains et aux interfaces web de GitHub et GitLab.

Pourquoi git diff n'affiche rien ?

Les modifications sont probablement déjà dans l'index via git add — regardez git diff --staged ; les nouveaux fichiers non suivis n'apparaissent jamais dans git diff.

Apprenez ce sujet en vidéo

Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».

Voir le cours