Historique et recherche#
L’historique de Git est une mine d’informations. Chaque commit enregistre non seulement un instantané du code, mais aussi l’identité de son auteur, la date précise de la modification et un message descriptif. Cet historique structuré constitue une ressource inestimable pour le débogage, la compréhension de l’évolution d’un projet et l’audit du code. Encore faut-il savoir l’exploiter efficacement.
Git offre un arsenal complet de commandes pour naviguer dans l’historique, filtrer les commits selon de multiples critères, retrouver l’origine d’une ligne de code, traquer l’introduction d’un bogue par recherche dichotomique, ou encore chercher des motifs dans les fichiers suivis. Ce chapitre couvre en profondeur chacun de ces outils : git log avancé, git blame, git bisect, git grep et git shortlog. Maitriser ces commandes, c’est transformer l’historique d’un dépôt en un outil de travail quotidien.
Préparation du dépôt de démonstration#
Pour illustrer les différentes commandes de ce chapitre, nous allons créer un dépôt avec un historique riche : plusieurs auteurs, des dates variées et des messages de commit significatifs.
%%bash
cd /tmp && rm -rf demo-log && mkdir demo-log && cd demo-log && git init
git config user.email "alice@example.com" && git config user.name "Alice"
# Commit 1 — Alice crée le projet
echo "# Calculatrice" > README.md
echo "def add(a, b): return a + b" > calc.py
git add . && git commit -m "Init: création du projet calculatrice" --date="2024-01-15 10:00:00"
# Commit 2 — Alice ajoute la soustraction
echo "def sub(a, b): return a - b" >> cal.py
git add . && git commit -m "feat: ajout de la soustraction" --date="2024-02-01 14:30:00"
# Commit 3 — Bob ajoute la multiplication
git config user.name "Bob" && git config user.email "bob@example.com"
echo "def mul(a, b): return a * b" >> calc.py
git add . && git commit -m "feat: ajout de la multiplication" --date="2024-03-10 09:15:00"
# Commit 4 — Bob corrige un bug
sed -i 's/def mul(a, b): return a \* b/def mul(a, b): return a * b # corrige/' calc.py
git add . && git commit -m "fix: correction commentaire multiplication" --date="2024-03-12 11:00:00"
# Commit 5 — Alice ajoute la division
git config user.name "Alice" && git config user.email "alice@example.com"
echo "def div(a, b): return a / b if b != 0 else None" >> calc.py
git add . && git commit -m "feat: ajout de la division avec garde zero" --date="2024-04-05 16:45:00"
# Commit 6 — Alice ajoute les tests
echo 'assert add(2, 3) == 5' > tests.py
echo 'assert sub(5, 3) == 2' >> tests.py
echo 'assert mul(4, 3) == 12' >> tests.py
echo 'assert div(10, 2) == 5' >> tests.py
git add . && git commit -m "test: ajout des tests unitaires" --date="2024-05-20 08:00:00"
# Commit 7 — Bob refactorise
git config user.name "Bob" && git config user.email "bob@example.com"
echo "## Fonctions disponibles" >> README.md
echo "- add, sub, mul, div" >> README.md
git add . && git commit -m "docs: mise a jour du README" --date="2024-06-01 10:30:00"
# Commit 8 — Alice ajoute la puissance
git config user.name "Alice" && git config user.email "alice@example.com"
echo "def power(a, b): return a ** b" >> calc.py
git add . && git commit -m "feat: ajout de la fonction puissance" --date="2024-07-15 14:00:00"
echo "--- Dépôt créé avec succès ---"
Dépôt Git vide initialisé dans /tmp/demo-log/.git/
[main (commit racine) 895e0b0] Init: création du projet calculatrice
Date: Mon Jan 15 10:00:00 202
4 +0100
2 files changed, 2 insertions(+)
create mode 100644 README.md
create mode 100644 calc.py
[main 0c367ea] feat: ajout de la soustraction
Date: Thu Feb 1 14:30:00 2024 +0100
1 file changed,
1 insertion(+)
create mode 100644 cal.py
[main 5dbddad] feat: ajout de la multiplication
Date: Sun Mar 10 09:15:00 2024 +0100
1 file change
d, 1 insertion(+)
[main 5c4d4bd] fix: correction commentaire multiplication
Date: Tue Mar 12 11:00:00 2024 +0100
1 f
ile changed, 1 insertion(+), 1 deletion(-)
[main eee1f3a] feat: ajout de la division avec garde zero
Date: Fri Apr 5 16:45:00 2024 +0200
1 fi
le changed, 1 insertion(+)
[main 0d7c91d] test: ajout des tests unitaires
Date: Mon May 20 08:00:00 2024 +0200
1 file changed
, 4 insertions(+)
create mode 100644 tests.py
[main b5ed5bc] docs: mise a jour du README
Date: Sat Jun 1 10:30:00 2024 +0200
1 file changed, 2 i
nsertions(+)
[main 230c691] feat: ajout de la fonction puissance
Date: Mon Jul 15 14:00:00 2024 +0200
1 file ch
anged, 1 insertion(+)
--- Dépôt créé avec succès ---
Git log avancé#
La commande git log affiche l’historique des commits du dépôt. Sous sa forme la plus simple, elle présente les commits du plus récent au plus ancien avec toutes leurs métadonnées. Mais sa véritable puissance réside dans ses nombreuses options de filtrage et de formatage.
Format compact#
L’option --oneline affiche chaque commit sur une seule ligne : le hash abrégé suivi du message.
%%bash
cd /tmp/demo-log
git log --oneline
230c691 feat: ajout de la fonction puissance
b5ed5bc docs: mise a jour du README
0d7c91d test: ajout des tests unitaires
eee1f3a feat: ajout de la division avec garde zero
5c4d4bd f
ix: correction commentaire multiplication
5dbddad feat: ajout de la multiplication
0c367ea feat: ajo
ut de la soustraction
895e0b0 Init: création du projet calculatrice
Graphe visuel#
L’option --graph dessine le graphe de commits en ASCII. Combinée avec --all et --decorate, elle offre une vue d’ensemble de toutes les branches et de leurs relations.
%%bash
cd /tmp/demo-log
git log --oneline --graph --all --decorate
* 230c691 (HEAD -> main) feat: ajout de la fonction puissance
* b5ed5bc docs: mise a jour du README
* 0d7c91d test: ajout des tests unitaires
* eee1f3a feat: ajout de la division avec garde zero
* 5c4
d4bd fix: correction commentaire multiplication
* 5dbddad feat: ajout de la multiplication
* 0c367ea feat: ajout de la soustraction
* 895e0b0 Init:
création du projet calculatrice
Filtrer par auteur#
L’option --author filtre les commits par nom d’auteur. Elle accepte une expression régulière.
%%bash
cd /tmp/demo-log
echo "=== Commits d'Alice ==="
git log --oneline --author="Alice"
echo ""
echo "=== Commits de Bob ==="
git log --oneline --author="Bob"
=== Commits d'Alice ===
230c691 feat: ajout de la fonction puissance
0d7c91d test: ajout des tests unitaires
eee1f3a feat: ajout de la division avec garde zero
0c367ea f
eat: ajout de la soustraction
895e0b0 Init: création du projet calculatrice
=== Commits de Bob ===
b5ed5bc docs: mise a jour du README
5c4d4bd fix: correction commentaire multiplication
5dbddad feat:
ajout de la multiplication
Filtrer par date#
Les options --since et --until (ou leurs synonymes --after et --before) permettent de restreindre l’historique à une plage temporelle.
%%bash
cd /tmp/demo-log
echo "=== Commits entre janvier et mars 2024 ==="
git log --oneline --since="2024-01-01" --until="2024-03-31"
echo ""
echo "=== Commits depuis juin 2024 ==="
git log --oneline --since="2024-06-01"
=== Commits entre janvier et mars 2024 ===
=== Commits depuis juin 2024 ===
230c691 feat: ajout de la fonction puissance
b5ed5bc docs: mise a jour du README
0d7c91d test: ajout des tests unitaires
eee1f3a feat: ajout de la division avec garde zero
5c4d4bd f
ix: correction commentaire multiplication
5dbddad feat: ajout de la multiplication
0c367ea feat: ajo
ut de la soustraction
895e0b0 Init: création du projet calculatrice
Rechercher dans les messages de commit#
L’option --grep filtre les commits dont le message contient un motif donné.
%%bash
cd /tmp/demo-log
echo "=== Commits contenant 'feat' ==="
git log --oneline --grep="feat"
echo ""
echo "=== Commits contenant 'fix' ==="
git log --oneline --grep="fix"
=== Commits contenant 'feat' ===
230c691 feat: ajout de la fonction puissance
eee1f3a feat: ajout de la division avec garde zero
5dbddad feat: ajout de la multiplication
0c367ea
feat: ajout de la soustraction
=== Commits contenant 'fix' ===
5c4d4bd fix: correction commentaire multiplication
Pickaxe : rechercher dans le contenu#
L’option -S (dite pickaxe) recherche les commits qui ont ajouté ou supprimé une chaine donnée dans le code. C’est l’un des outils les plus puissants de Git pour retrouver quand une fonction, une variable ou un morceau de code a été introduit ou retiré.
%%bash
cd /tmp/demo-log
echo "=== Commits qui ajoutent ou retirent 'def div' ==="
git log --oneline -S "def div"
echo ""
echo "=== Commits qui ajoutent ou retirent 'def power' ==="
git log --oneline -S "def power"
=== Commits qui ajoutent ou retirent 'def div' ===
eee1f3a feat: ajout de la division avec garde zero
=== Commits qui ajoutent ou retirent 'def power' ===
230c691 feat: ajout de la fonction puissance
Remarque 48
L’option -S (pickaxe) est un outil remarquablement puissant pour l’archéologie du code. Elle parcourt l’ensemble des diffs de l’historique et identifie les commits ou le nombre d’occurrences d’une chaine change. Contrairement à --grep qui cherche dans les messages de commit, -S cherche dans les modifications effectives du code. Pour retrouver quand une fonction spécifique a ete introduite dans un projet de milliers de commits, git log -S "nom_fonction" donne la réponse en quelques secondes.
Historique d’un fichier spécifique#
L’option -- chemin/vers/fichier restreint l’historique à un fichier particulier. Combinée avec -p, elle affiche le diff à chaque commit.
%%bash
cd /tmp/demo-log
echo "=== Historique de calc.py ==="
git log --oneline -- calc.py
echo ""
echo "=== Dernier patch sur calc.py ==="
git log -1 -p -- calc.py
=== Historique de calc.py ===
230c691 feat: ajout de la fonction puissance
eee1f3a feat: ajout de la division avec garde zero
5c4d4bd fix: correction commentaire multiplicatio
n
5dbddad feat: ajout de la multiplication
895e0b0 Init: création du projet calculatrice
=== Dernier patch sur calc.py ===
commit 230c691e8a51ccf424aac6a98e582ffc8c3af5a8
Author: Alice <alice@example.com>
Date: Mon Jul 15
14:00:00 2024 +0200
feat: ajout de la fonction puissance
diff --git a/calc.py b/calc.py
index
d4d6412..dabc468 100644
--- a/calc.py
+++ b/calc.py
@@ -1,3 +1,4 @@
def add(a, b): return a + b
d
ef mul(a, b): return a * b # corrige
def div(a, b): return a / b if b != 0 else None
+def power(a,
b): return a ** b
Format personnalisé#
L’option --format (ou --pretty=format:) permet de définir un format de sortie sur mesure avec des codes de substitution.
%%bash
cd /tmp/demo-log
echo "=== Format personnalisé ==="
git log --format="%h | %an | %ad | %s" --date=short
=== Format personnalisé ===
230c691 | Alice | 2024-07-15 | feat: ajout de la fonction puissance
b5ed5bc | Bob | 2024-06-01 | docs: mise a jour du README
0d7c91d | Alice | 2024-05-20 | test: ajout
des tests unitaires
eee1f3a | Alice | 2024-04-05 | feat: ajout de la division avec garde zero
5c4d4b
d | Bob | 2024-03-12 | fix: correction commentaire multiplication
5dbddad | Bob | 2024-03-10 | feat:
ajout de la multiplication
0c367ea | Alice | 2024-02-01 | feat: ajout de la soustraction
895e0b0 |
Alice | 2024-01-15 | Init: création du projet calculatrice
Les codes de substitution les plus courants sont :
Code |
Signification |
|---|---|
|
Hash complet |
|
Hash abrégé |
|
Nom de l’auteur |
|
Email de l’auteur |
|
Date de l’auteur |
|
Sujet (message court) |
Git blame#
Définition 49 (Git blame)
La commande git blame annote chaque ligne d’un fichier en indiquant le commit qui l’a modifiée en dernier, l”auteur de ce commit et la date de la modification. Pour chaque ligne, on obtient ainsi la reponse à la question : « qui a écrit ça, quand, et dans quel commit ? ».
Annoter un fichier entier#
%%bash
cd /tmp/demo-log
git blame calc.py
^895e0b0 (Alice 2024-01-15 10:00:00 +0100 1) def add(a, b): return a + b
5c4d4bd0 (Bob 2024-03-12
11:00:00 +0100 2) def mul(a, b): return a * b # corrige
eee1f3a6 (Alice 2024-04-05 16:45:00 +0200 3
) def div(a, b): return a / b if b != 0 else None
230c691e (Alice 2024-07-15 14:00:00 +0200 4) def p
ower(a, b): return a ** b
Chaque ligne affiche le hash abrégé du commit, l’auteur, la date et le contenu de la ligne. On peut ainsi voir immédiatement que la fonction add a été écrite par Alice en janvier, tandis que la fonction mul est l’oeuvre de Bob en mars.
Annoter un intervalle de lignes#
L’option -L debut,fin restreint l’annotation à un intervalle de lignes.
%%bash
cd /tmp/demo-log
echo "=== Blame des lignes 1 a 3 ==="
git blame -L 1,3 calc.py
echo ""
echo "=== Blame des lignes 4 a 5 ==="
git blame -L 4,5 calc.py
=== Blame des lignes 1 a 3 ===
^895e0b0 (Alice 2024-01-15 10:00:00 +0100 1) def add(a, b): return a + b
5c4d4bd0 (Bob 2024-03-12
11:00:00 +0100 2) def mul(a, b): return a * b # corrige
eee1f3a6 (Alice 2024-04-05 16:45:00 +0200 3
) def div(a, b): return a / b if b != 0 else None
=== Blame des lignes 4 a 5 ===
230c691e (Alice 2024-07-15 14:00:00 +0200 4) def power(a, b): return a ** b
Remarque 49
Malgré son nom évocateur, git blame n’est pas un outil d’accusation. Son véritable objectif est la compréhension de l’historique. Il permet de retrouver le commit et donc le message explicatif associé à une modification, d’identifier la personne la mieux placée pour répondre à une question sur un morceau de code, et de comprendre le contexte dans lequel une ligne a été écrite. Certains outils proposent d’ailleurs l’alias git annotate, sémantiquement plus neutre.
Git bisect#
Définition 50 (Git bisect)
La commande git bisect effectue une recherche dichotomique (ou binaire) dans l’historique des commits pour identifier le commit qui a introduit un bogue. Au lieu de tester chaque commit séquentiellement en \(O(n)\), elle divise l’espace de recherche en deux à chaque étape, trouvant le commit fautif en \(O(\log n)\) tests. Pour un historique de 1000 commits, cela signifie environ 10 tests au lieu de 1000.
Le principe est simple :
On indique un commit bon (good) ou le bogue n’existait pas.
On indique un commit mauvais (bad) ou le bogue est présent.
Git sélectionne le commit au milieu de l’intervalle.
On teste ce commit et on le marque comme good ou bad.
Git réduit l’intervalle de moitié et propose le commit suivant.
On répète jusqu’à ce que Git identifie le commit fautif.
Démonstration pas à pas#
Créons un dépôt ou un « bogue » est introduit à un commit spécifique.
%%bash
cd /tmp && rm -rf demo-bisect && mkdir demo-bisect && cd demo-bisect && git init
git config user.email "demo@example.com" && git config user.name "Demo"
# Commit A — tout fonctionne
echo "resultat = 42" > app.py
git add . && git commit -m "A: valeur initiale correcte"
# Commit B — tout fonctionne
echo "# commentaire" >> app.py
git add . && git commit -m "B: ajout commentaire"
# Commit C — tout fonctionne
echo "version = 1" >> app.py
git add . && git commit -m "C: ajout version"
# Commit D — tout fonctionne
echo "debug = False" >> app.py
git add . && git commit -m "D: ajout flag debug"
# Commit E — LE BOGUE est introduit ici !
sed -i 's/resultat = 42/resultat = -1/' app.py
git add . && git commit -m "E: refactorisation interne"
# Commit F — le bogue persiste
echo "mode = production" >> app.py
git add . && git commit -m "F: mode production"
# Commit G — le bogue persiste
echo "log_level = INFO" >> app.py
git add . && git commit -m "G: configuration logging"
# Commit H — le bogue persiste
echo "cache = True" >> app.py
git add . && git commit -m "H: activation du cache"
echo "=== Historique ==="
git log --oneline
Dépôt Git vide initialisé dans /tmp/demo-bisect/.git/
[main (commit racine) 85ea1ac] A: valeur initiale correcte
1 file changed, 1 insertion(+)
create m
ode 100644 app.py
[main e369c10] B: ajout commentaire
1 file changed, 1 insertion(+)
[main be903a0] C: ajout version
1 file changed, 1 insertion(+)
[main c3fc52b] D: ajout flag debug
1 file changed, 1 insertion(+)
[main d028660] E: refactorisation interne
1 file changed, 1 insertion(+), 1 deletion(-)
[main 1e8f66c] F: mode production
1 file changed, 1 insertion(+)
[main b019dc2] G: configuration logging
1 file changed, 1 insertion(+)
[main 8930e78] H: activation du cache
1 file changed, 1 insertion(+)
=== Historique ===
8930e78 H: activation du cache
b019dc2 G: configuration logging
1e8f66c F: mode production
d028660 E: refactorisation interne
c3fc52b D: ajout flag debug
be903a0 C:
ajout version
e369c10 B: ajout commentaire
85ea1ac A: valeur initiale correcte
Nous savons que le commit A est bon (resultat vaut 42) et que le commit H est mauvais (resultat vaut -1). Lancons git bisect pour trouver le coupable.
%%bash
cd /tmp/demo-bisect
GOOD_HASH=$(git log --oneline | tail -1 | cut -d' ' -f1)
git bisect start
git bisect bad HEAD
git bisect good $GOOD_HASH
echo ""
echo "=== Test du commit proposé ==="
cat app.py | head -1
status : en attente d'un commit bon et d'un commit mauvais
status : en attente de bon(s) commit(s), un mauvais commit connu
Bissection : 3 révisions à tester après ceci (à peu près 2 étapes)
[c3fc52b55e1c9852bddfa9160aedf178d2a58e5b] D: ajout flag debug
=== Test du commit proposé ===
resultat = 42
Git a selectionné le commit au milieu de l’intervalle. Testons : si resultat = 42, le commit est bon ; sinon, il est mauvais.
%%bash
cd /tmp/demo-bisect
# Le commit D contient encore "resultat = 42", donc il est bon
FIRST_LINE=$(head -1 app.py)
if echo "$FIRST_LINE" | grep -q "42"; then
echo ">>> Ce commit est BON (resultat = 42)"
git bisect good
else
echo ">>> Ce commit est MAUVAIS (resultat != 42)"
git bisect bad
fi
echo ""
echo "=== Test du commit suivant ==="
cat app.py | head -1
>>> Ce commit est BON (resultat = 42)
Bissection : 1 révision à tester après ceci (à peu près 1 étape)
[1e8f66ce175b74a8a9dde0288c4d52161bad6818] F: mode production
=== Test du commit suivant ===
resultat = -1
%%bash
cd /tmp/demo-bisect
# On continue le test
FIRST_LINE=$(head -1 app.py)
if echo "$FIRST_LINE" | grep -q "42"; then
echo ">>> Ce commit est BON (resultat = 42)"
git bisect good
else
echo ">>> Ce commit est MAUVAIS (resultat != 42)"
git bisect bad
fi
>>> Ce commit est MAUVAIS (resultat != 42)
Bissection : 0 révision à tester après ceci (à peu près 0 étape)
[d02866013d02be0f58ae923a6526a289a34f0b41] E: refactorisation interne
%%bash
cd /tmp/demo-bisect
# Dernier test pour isoler le commit fautif
FIRST_LINE=$(head -1 app.py)
if echo "$FIRST_LINE" | grep -q "42"; then
echo ">>> Ce commit est BON (resultat = 42)"
git bisect good
else
echo ">>> Ce commit est MAUVAIS (resultat != 42)"
git bisect bad
fi
>>> Ce commit est MAUVAIS (resultat != 42)
d02866013d02be0f58ae923a6526a289a34f0b41 is the first bad commit
commit d02866013d02be0f58ae923a6526a289a34f0b41
Author: Demo <demo@example.com>
Date: Sun Mar 15 2
1:25:40 2026 +0100
E: refactorisation interne
app.py | 2 +-
1 file changed, 1 insertion(+),
1 deletion(-)
Git a identifié le commit fautif. Terminons la session bisect pour revenir à l’état normal.
%%bash
cd /tmp/demo-bisect
git bisect reset
La position précédente de HEAD était sur d028660 E: refactorisation interne
Basculement sur la branche 'main'
Visualisation de la recherche dichotomique#
Le diagramme suivant illustre le déroulement de git bisect sur notre historique de 8 commits. A chaque étape, l’intervalle de recherche est divisé par deux.
Sur 8 commits, git bisect n’a eu besoin que de 3 tests pour isoler le commit fautif. Sur un historique de 1024 commits, il n’en faudrait que 10. C’est la puissance de la recherche dichotomique.
Remarque 50
La commande git bisect run <script> automatise entièrement le processus. On fournit un script de test qui retourne 0 si le commit est bon et un code non nul si le commit est mauvais. Git exécute le script à chaque étape et détermine automatiquement le commit fautif. Par exemple :
git bisect start HEAD <bon-commit>
git bisect run python -c "exec(open('app.py').read()); assert resultat == 42"
Cette automatisation est particulièrement précieuse sur les grands projets ou le test peut impliquer une compilation et une suite de tests automatisés.
Exemple 15 (Session bisect automatisée)
Voici un exemple complet de session git bisect run :
On démarre la session :
git bisect startOn marque l’état courant comme mauvais :
git bisect badOn marque un ancien commit comme bon :
git bisect good abc1234On lance le script de test :
git bisect run ./test_resultat.shGit parcourt automatiquement l’historique et affiche le premier commit mauvais.
On termine :
git bisect reset
Le script test_resultat.sh peut être aussi simple que :
#!/bin/bash
grep -q "resultat = 42" app.py
Ce script retourne 0 (succès) si la ligne est présente, 1 (échec) sinon.
Git grep#
Définition 51 (Git grep)
La commande git grep recherche des motifs (expressions régulières ou chaines littéral) dans les fichiers suivis par Git. Elle est optimisée pour les dépôts Git et ne parcourt que les fichiers indexés, ignorant automatiquement les fichiers non suivis et ceux décrits dans .gitignore. Elle est généralement plus rapide que grep -r sur un dépôt Git.
Recherche dans l’arbre de travail#
%%bash
cd /tmp/demo-log
echo "=== Recherche de 'return' dans le dépôt ==="
git grep "return"
=== Recherche de 'return' dans le dépôt ===
cal.py:def sub(a, b): return a - b
calc.py:def add(a, b): return a + b
calc.py:def mul(a, b): return
a * b # corrige
calc.py:def div(a, b): return a / b if b != 0 else None
calc.py:def power(a, b): r
eturn a ** b
Recherche avec numéros de ligne#
L’option -n affiche le numéro de ligne de chaque correspondance.
%%bash
cd /tmp/demo-log
echo "=== Recherche de 'def' avec numéros de ligne ==="
git grep -n "def"
=== Recherche de 'def' avec numéros de ligne ===
cal.py:1:def sub(a, b): return a - b
calc.py:1:def add(a, b): return a + b
calc.py:2:def mul(a, b):
return a * b # corrige
calc.py:3:def div(a, b): return a / b if b != 0 else None
calc.py:4:def powe
r(a, b): return a ** b
Recherche dans une révision specifique#
On peut rechercher un motif dans une version antérieure du dépôt en spécifiant une référence de commit.
%%bash
cd /tmp/demo-log
echo "=== Recherche de 'def' dans HEAD~3 ==="
git grep -n "def" HEAD~3
echo ""
echo "=== Recherche de 'def' dans HEAD (actuel) ==="
git grep -n "def" HEAD
=== Recherche de 'def' dans HEAD~3 ===
HEAD~3:cal.py:1:def sub(a, b): return a - b
HEAD~3:calc.py:1:def add(a, b): return a + b
HEAD~3:calc
.py:2:def mul(a, b): return a * b # corrige
HEAD~3:calc.py:3:def div(a, b): return a / b if b != 0
else None
=== Recherche de 'def' dans HEAD (actuel) ===
HEAD:cal.py:1:def sub(a, b): return a - b
HEAD:calc.py:1:def add(a, b): return a + b
HEAD:calc.py:2:
def mul(a, b): return a * b # corrige
HEAD:calc.py:3:def div(a, b): return a / b if b != 0 else Non
e
HEAD:calc.py:4:def power(a, b): return a ** b
On constate que la révision HEAD~3 contient moins de fonctions que la révision actuelle, ce qui est cohérent avec l’ajout progressif de fonctionnalités.
Remarque 51
Contrairement à grep -r qui parcourt tous les fichiers d’un répertoire (y compris les fichiers non suivis, les artefacts de build, les dépendances dans node_modules/, etc.), git grep ne parcourt que les fichiers suivis par Git. Sur un dépôt contenant un répertoire node_modules/ de plusieurs gigaoctets, la différence de performance est considérable. De plus, git grep peut chercher dans n’importe quelle revision de l’historique, ce que grep ne peut pas faire.
Git shortlog#
La commande git shortlog regroupe les commits par auteur. Combinée avec les options -s (compte uniquement) et -n (tri par nombre décroissant), elle fournit une vue statistique de la contribution de chaque auteur.
%%bash
cd /tmp/demo-log
echo "=== Nombre de commits par auteur ==="
git shortlog -sn
echo ""
echo "=== Détail par auteur ==="
git shortlog
=== Nombre de commits par auteur ===
Cette commande est particulièrement utile pour obtenir une vue d’ensemble de l’activité d’un projet : qui sont les contributeurs principaux, quelle est la répartition du travail, et comment l’activite évolue dans le temps.
Résumé#
Le tableau suivant récapitule les commandes de recherche et d’exploration de l’historique couvertes dans ce chapitre.
Commande |
Description |
|---|---|
|
Affichage compact de l’historique |
|
Graphe visuel de toutes les branches |
|
Filtrer par auteur |
|
Filtrer par plage de dates |
|
Rechercher dans les messages de commit |
|
Pickaxe : commits qui ajoutent/retirent une chaine |
|
Historique avec diffs pour un fichier |
|
Format de sortie personnalisé |
|
Annotation ligne par ligne (auteur, date, commit) |
|
Annotation d’un intervalle de lignes |
|
Démarrer une recherche dichotomique |
|
Marquer un commit comme bon ou mauvais |
|
Automatiser la recherche avec un script |
|
Terminer la session bisect |
|
Rechercher un motif dans les fichiers suivis |
|
Rechercher avec numéros de ligne dans une révision |
|
Nombre de commits par auteur |