Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Sélection de révisions Git

10 min de lecture

Git offre une dizaine de syntaxes pour désigner un commit précis : SHA court, HEAD~3, main^2, HEAD@{5}, A..B. Comprendre ces syntaxes est indispensable pour utiliser efficacement log, diff, reset, rebase et cherry-pick. Ce guide couvre toutes les formes de sélection de révisions.

Prérequis : Consulter l’historique et Les branches en bref.

  • Utiliser ^ et ~ pour naviguer dans l’historique commit par commit
  • Cibler des plages de commits avec les opérateurs A..B et A...B
  • Retrouver un commit perdu avec HEAD@{N} et le reflog
  • Résoudre n’importe quelle référence en SHA avec git rev-parse

Chaque commit est identifié par un hash SHA-1 de 40 caractères :

a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0

En pratique, les 7 premiers caractères suffisent (SHA court) :

Fenêtre de terminal
git show a1b2c3d
git log --oneline # Affiche les SHA courts automatiquement

Git résout le SHA court vers le hash complet tant qu’il n’y a pas d’ambiguïté. Pour un projet très gros, utilisez 8 à 12 caractères.

Pour obtenir le SHA complet à partir d’un court :

Fenêtre de terminal
git rev-parse a1b2c3d
# a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0

Les noms de branches et tags sont des alias vers un SHA :

Fenêtre de terminal
git rev-parse main # SHA du dernier commit de main
git rev-parse v1.2.0 # SHA du commit pointé par le tag
git rev-parse HEAD # SHA du commit courant

HEAD pointe toujours vers le commit courant (via la branche active).

Deux opérateurs pour naviguer vers les parents d’un commit :

L’opérateur ~ (tilde) — remonter en ligne droite

Section intitulée « L’opérateur ~ (tilde) — remonter en ligne droite »

~n remonte de n commits sur le premier parent :

HEAD~0 = HEAD
HEAD~1 = parent de HEAD
HEAD~2 = grand-parent de HEAD
HEAD~3 = arrière-grand-parent
Fenêtre de terminal
git show HEAD~3 # 3 commits avant HEAD
git diff HEAD~5 HEAD # Différences sur les 5 derniers commits

^n sélectionne le n-ième parent d’un commit de merge :

HEAD^ = HEAD^1 = premier parent (branche dans laquelle on a mergé)
HEAD^2 = deuxième parent (branche qui a été mergée)

Pour un commit normal (non-merge), ^ et ~ sont équivalents : HEAD^ = HEAD~1.

HEAD~2^2 = grand-parent de HEAD, deuxième parent
HEAD^^ = HEAD~2 (parent du parent, premier parent à chaque fois)
HEAD^2~3 = 3 commits avant le deuxième parent de HEAD

Le reflog enregistre chaque position de HEAD (et des branches) dans le temps. Contrairement à l’historique (qui suit les commits), le reflog suit les mouvements :

Fenêtre de terminal
git reflog
# a1b2c3d HEAD@{0}: commit: Ajout feature X
# e4f5a6b HEAD@{1}: checkout: moving from main to feature
# d7c8b9a HEAD@{2}: commit: Fix bug Y

Utilisation :

Fenêtre de terminal
git show HEAD@{3} # Position de HEAD il y a 3 mouvements
git show main@{yesterday} # Où pointait main hier
git show HEAD@{2.hours.ago} # HEAD il y a 2 heures
git diff HEAD@{0} HEAD@{5} # Ce qui a changé en 5 mouvements

Le reflog est votre filet de sécurité : même après un reset --hard, le commit précédent reste dans le reflog pendant 90 jours.

Double-point A..B — commits dans B mais pas dans A

Section intitulée « Double-point A..B — commits dans B mais pas dans A »
Fenêtre de terminal
git log main..feature # Commits dans feature, absents de main
git log origin/main..HEAD # Commits locaux non encore poussés

Cette syntaxe est la plus courante. Elle répond à la question : « quels commits dois-je pousser ? » ou « quels commits apporte cette branche ? ».

Triple-point A...B — commits dans l’un OU l’autre, mais pas les deux

Section intitulée « Triple-point A...B — commits dans l’un OU l’autre, mais pas les deux »
Fenêtre de terminal
git log main...feature # Exclusifs à main OU feature
git log --left-right main...feature # Indique < (main) ou > (feature)

Résultat avec --left-right :

< d7c8b9a Fix bug Y (seulement dans main)
> a1b2c3d Ajout feature X (seulement dans feature)
> e4f5a6b Refactor module Z (seulement dans feature)
Fenêtre de terminal
git log feature --not main # Équivalent à main..feature
git log feature ^main # Même chose (^ en début = exclusion)
git log feature ^main ^develop # Dans feature, ni dans main ni develop

git rev-parse traduit n’importe quelle syntaxe en SHA :

Fenêtre de terminal
git rev-parse HEAD~3 # SHA du commit 3 avant HEAD
git rev-parse main^2 # SHA du 2e parent du dernier commit de main
git rev-parse --short HEAD # SHA court (7 caractères)
git rev-parse --verify HEAD@{5} # Vérifie que la ref existe

Cas pratiques en scripting :

Fenêtre de terminal
# Vérifier qu'on est sur main
if [[ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]]; then
echo "Pas sur main !"
exit 1
fi
# Comparer deux branches
MERGE_BASE=$(git merge-base main feature)
echo "Point de divergence : $MERGE_BASE"
SyntaxeSignificationExemple
abc1234SHA courtgit show abc1234
HEADCommit courantgit show HEAD
mainDernier commit de la branchegit log main
v1.0Commit du taggit show v1.0
HEAD~nN-ième ancêtre (premier parent)git show HEAD~3
HEAD^nN-ième parent (merge)git show HEAD^2
HEAD@{n}N-ième entrée refloggit show HEAD@{5}
@{yesterday}Reflog par dategit show main@{yesterday}
A..BDans B, pas dans Agit log main..feature
A...BExclusifs à A ou Bgit log main...feature
^A / --not AExclure Agit log feature ^main
SymptômeCause probableSolution
ambiguous argument 'HEAD^' (Windows)^ interprété par cmd.exeUtilisez HEAD^^ ou "HEAD^" entre guillemets
fatal: bad default revision 'HEAD'Repo vide, pas de commitFaites un premier commit
reflog affiche (unreachable)Commit orphelinNormal, récupérable pendant 90 jours
SHA court ambiguCollision de hash partielUtilisez plus de caractères (--abbrev=12)
  • ~n remonte de N commits en ligne droite (premier parent)
  • ^n choisit le N-ième parent d’un merge
  • A..B = commits dans B absents de A (le plus utilisé)
  • A...B = commits exclusifs à l’une ou l’autre branche
  • Le reflog (HEAD@{n}) est votre filet de sécurité local
  • git rev-parse traduit toute syntaxe en SHA

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn