git grep cherche du texte dans votre code actuel, git log -S
trouve le commit qui a introduit ou supprimé une chaîne, et
git log -L retrace l'historique d'une fonction. Ces trois outils
couvrent tous les besoins de recherche dans un dépôt Git, bien plus
efficacement que grep classique.
Prérequis : Consulter l'historique et Sélection de révisions.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Utiliser
git greppour chercher du texte dans tous les fichiers suivis - Rechercher avec
log -Sles commits qui ont introduit ou supprimé une chaîne - Localiser des changements dans une fonction avec
log -L - Combiner ces outils pour un workflow de débogage par l'historique
git grep : chercher dans le code
Section intitulée « git grep : chercher dans le code »git grep est plus rapide que grep -r car il ne parcourt que les
fichiers suivis par Git (il ignore node_modules/, .git/, les
artefacts de build...).
Recherche simple
Section intitulée « Recherche simple »Sans argument supplémentaire, git grep cherche dans l'index et le répertoire de travail, c'est-à-dire dans les fichiers tels qu'ils existent maintenant. Chaque résultat est préfixé du chemin relatif à la racine du dépôt, quel que soit le sous-répertoire depuis lequel vous lancez la commande : c'est ce qui rend la sortie directement réutilisable dans un éditeur ou un script.
# Chercher une chaîne dans tout le repogit grep "TODO"
# Résultat :# src/app.py:42: # TODO: gérer les erreurs# src/utils.py:18: # TODO: optimiser cette boucleOptions utiles
Section intitulée « Options utiles »Ces options se combinent librement, et trois d'entre elles changent la nature du résultat plutôt que sa présentation. -l ne renvoie que des chemins, ce qui en fait l'option à utiliser quand vous enchaînez sur xargs. -c renvoie un compteur par fichier, utile pour mesurer l'ampleur d'une dette avant de la traiter. -p remonte la ligne de déclaration englobante, ce qui vous évite d'ouvrir le fichier pour savoir dans quelle fonction se trouve le résultat. Les autres options affinent la correspondance sans changer le format.
| Option | Effet | Exemple |
|---|---|---|
-n | Affiche les numéros de ligne | git grep -n "TODO" |
-c | Compte les occurrences par fichier | git grep -c "TODO" |
-l | Liste uniquement les fichiers | git grep -l "TODO" |
-i | Insensible à la casse | git grep -i "error" |
-w | Mot entier uniquement | git grep -w "log" |
-p | Affiche la fonction englobante | git grep -p "calculate" |
--heading | Regroupe par fichier | git grep --heading -n "TODO" |
-e | Spécifie un motif (pour les regex) | git grep -e "err[ou]r" |
Recherche combinée avec --and/--or
Section intitulée « Recherche combinée avec --and/--or »Le point à retenir tient en une phrase : les opérateurs booléens de
git grep s'appliquent à la ligne, pas au fichier. --and ne
sélectionne donc que les lignes où les deux motifs coexistent, ce qui
n'est presque jamais ce qu'on cherche quand on veut « les fichiers qui
parlent des deux sujets ». Pour ce besoin, il faut --all-match
combiné à --or : il conserve les fichiers dont chaque motif est
satisfait par au moins une ligne, éventuellement différente.
# Lignes contenant "calculate" ET "price" sur la MÊME lignegit grep -e "calculate" --and -e "price"
# Fichiers contenant "calculate" ET "price", même sur des lignes distinctesgit grep -l --all-match -e "calculate" --or -e "price"
# Lignes contenant "error" OU "warning"git grep -e "error" --or -e "warning"Vérifiez la différence sur un fichier où les deux mots sont sur des lignes séparées : la première commande ne renvoie rien, la deuxième renvoie le fichier.
Chercher dans un commit ou une branche spécifique
Section intitulée « Chercher dans un commit ou une branche spécifique »Ajouter une révision en fin de commande fait basculer git grep du
répertoire de travail vers l'arbre de ce commit. Vous interrogez
alors le code tel qu'il était, sans avoir à changer de branche ni à
créer de copie de travail : rien n'est écrit sur le disque. C'est la
façon la plus rapide de répondre à « cette chaîne existait-elle en
v1.0 ? », et le seul piège est d'oublier que les fichiers non suivis
à cette révision sont, par définition, absents du résultat.
# Chercher dans le commit v1.0git grep "TODO" v1.0
# Chercher dans une autre branchegit grep "calculate_price" feature/pricing
# Chercher dans HEAD~5git grep "deprecated" HEAD~5git log -S : le pickaxe
Section intitulée « git log -S : le pickaxe »Le « pickaxe » trouve les commits qui ont ajouté ou supprimé une
chaîne spécifique. Contrairement à grep qui cherche dans l'état
actuel, -S explore tout l'historique :
# Qui a introduit la fonction calculate_price ?git log -S "calculate_price" --oneline# a1b2c3d Ajout du module de tarification# e4f5a6b Suppression de l'ancien calcul
# Avec le diff completgit log -S "calculate_price" -pOptions du pickaxe
Section intitulée « Options du pickaxe »Trois variantes couvrent l'essentiel des usages. -G remplace la
recherche littérale par une expression régulière évaluée sur le
diff. Le filtre -- <chemin> restreint le parcours de l'historique et
fait chuter le temps d'exécution sur un gros dépôt, ce qui compte
puisque le pickaxe reconstruit un diff pour chaque commit examiné.
--stat ajoute la liste des fichiers touchés, pratique quand la même
chaîne a migré d'un module à l'autre.
# Avec regex (-G au lieu de -S)git log -G "calc.*price" --oneline
# Limité à certains fichiersgit log -S "API_KEY" -- src/config/
# Avec les noms de fichiers affectésgit log -S "deprecated_function" --statgit log -L : historique d'une fonction
Section intitulée « git log -L : historique d'une fonction »-L retrace l'historique d'un bloc de lignes ou d'une
fonction à travers tous les commits :
Par plage de lignes
Section intitulée « Par plage de lignes »Cette forme suit un bloc de lignes dans le temps, en tenant compte
des décalages provoqués par les commits antérieurs. Les numéros que
vous indiquez sont ceux de la révision de départ, HEAD par défaut :
inutile de calculer où se trouvaient ces lignes il y a six mois, Git
remonte la piste tout seul.
# Historique des lignes 10 à 25 de app.pygit log -L 10,25:src/app.pyPar nom de fonction
Section intitulée « Par nom de fonction »# Historique de la fonction calculate_price dans app.pygit log -L :calculate_price:src/app.pyGit repère les bornes de la fonction avec un motif de hunk header.
Sans configuration, ce motif est générique : toute ligne qui commence
en colonne 0 par une lettre, un souligné ou un dollar est considérée
comme un début de bloc, ce qui suffit pour Python, Go ou C. Pour les
langages où cette heuristique échoue, déclarez le pilote adapté dans
.gitattributes, par exemple *.py diff=python. Chaque commit est
ensuite affiché avec le diff correspondant, du plus récent au plus
ancien.
Exemple de sortie
Section intitulée « Exemple de sortie »Deux détails de cette sortie méritent votre attention. L'en-tête
@@ -10,5 +10,7 @@ indique que le bloc suivi occupait 5 lignes avant
le commit et 7 après : c'est ainsi que vous repérez d'un coup d'œil un
commit qui a fait grossir une fonction. Et contrairement à un
git log -p classique, le diff est restreint au bloc suivi, même
si le commit modifiait dix autres endroits du fichier.
commit a1b2c3dAuthor: Alice <alice@example.com>Date: Mon Mar 15 14:30:00 2026
fix: corriger la remise pour les gros volumes
diff --git a/src/app.py b/src/app.py--- a/src/app.py+++ b/src/app.py@@ -10,5 +10,7 @@ def calculate_price(quantity, unit_price): total = quantity * unit_price+ if quantity > 100:+ total *= 0.9 return totalComparatif des outils de recherche
Section intitulée « Comparatif des outils de recherche »Ce tableau se lit par la colonne Besoin, formulée comme la
question que vous vous posez réellement. La ligne de partage est
simple : git grep interroge un état du dépôt, les trois formes de
git log interrogent des changements, et git blame répond à une
question de responsabilité sur une ligne précise. Se tromper de
famille est la cause la plus courante d'une recherche qui ne donne
rien, typiquement chercher avec git grep une chaîne supprimée il y a
deux ans.
| Besoin | Commande | Exemple |
|---|---|---|
| Texte dans le code actuel | git grep | git grep "TODO" |
| Texte dans une version passée | git grep ... ref | git grep "TODO" v1.0 |
| Commit ayant introduit une chaîne | git log -S | git log -S "calc" |
| Commit ayant touché une regex | git log -G | git log -G "calc.*" |
| Historique d'une fonction | git log -L | git log -L :func:file |
| Commit contenant un mot dans le message | git log --grep | git log --grep="fix" |
| Auteur d'une ligne | git blame | git blame file.py |
Combiner les outils
Section intitulée « Combiner les outils »L'enchaînement ci-dessous va du plus large au plus précis, et chaque
commande consomme le résultat de la précédente. Vous partez d'un nom
de symbole, vous obtenez des chemins, puis des commits, puis un diff
ligne à ligne, puis un auteur à qui poser la question. Suivre cet
ordre évite le réflexe coûteux qui consiste à lancer git blame en
premier : blame ne montre que le dernier commit ayant touché
chaque ligne, ce qui masque complètement l'historique d'une ligne
plusieurs fois réécrite.
# 1. Trouver où la fonction est utiliséegit grep -n "calculate_price"
# 2. Quand a-t-elle été modifiée ?git log -S "calculate_price" --oneline
# 3. Voir l'évolution complète de la fonctiongit log -L :calculate_price:src/app.py
# 4. Qui a écrit cette ligne spécifique ?git blame -L 42,50 src/app.pyDépannage
Section intitulée « Dépannage »Les quatre situations ci-dessous couvrent la quasi-totalité des
recherches qui échouent. Deux d'entre elles ne sont pas des pannes
mais des malentendus sur le périmètre : git grep ignore ce que
Git ne suit pas, et le pickaxe parcourt tout l'historique tant que
vous ne le contraignez pas. Dans les deux cas, le correctif consiste à
préciser la portée, pas à changer d'outil.
| Symptôme | Cause probable | Solution |
|---|---|---|
git grep ne trouve rien | Fichier non suivi ou ignoré | Vérifiez avec git ls-files |
-L :func: ne détecte pas la fonction | Langage non reconnu | Ajoutez un pattern dans .gitattributes |
-S retourne trop de résultats | Chaîne trop courte/générique | Précisez avec -- chemin/ |
| Recherche lente sur gros repo | Historique volumineux | Limitez avec --since ou -- chemin/ |
À retenir
Section intitulée « À retenir »git grep: rapide, cherche dans le code actuel (ou une révision donnée)git log -S(pickaxe) : trouve le commit qui a introduit/supprimé une chaînegit log -G: comme-Smais avec des regex et sur le diffgit log -L: retrace l'historique complet d'une fonction- Combinez ces outils pour un débogage efficace :
grep→-S→-L→blame