Reset, checkout et revert
Les commandes git reset
, git checkout
et git revert
comptent parmi les outils les plus utiles de votre boîte à outils Git. Toutes vous permettent d'annuler certains types de changement dans votre dépôt. De plus, vous pouvez utiliser les deux premières pour gérer des commits ou des fichiers individuels.
Comme elles sont très similaires, veillez à ne pas les confondre : à chaque scénario sa commande ! Dans cet article, nous allons comparer les configurations les plus courantes de git reset
, git checkout
et git revert
. Ainsi, vous n'éprouverez aucune difficulté à utiliser ces commandes pour parcourir votre dépôt.
Vous pourrez réfléchir à chaque commande en fonction de l'impact sur les trois mécanismes de gestion des états d'un dépôt Git : le répertoire de travail, l'instantané stagé et l'historique des commits. Ces composants sont parfois appelés « Les trois arborescences » de Git. Nous explorons en détail les trois arborescences sur la page git reset
. Gardez ces mécanismes à l'esprit lorsque vous lisez cet article.
Un checkout est une opération qui permet de déplacer le pointeur de réf HEAD
vers un commit spécifique. Pour démontrer ce point, prenons l'exemple suivant.

Cet exemple illustre une séquence de commits sur la branche principale (main
). Les réfs HEAD
et de branche (main
) pointent actuellement vers le commit d. Exécutons maintenant git checkout b
.

Il s'agit d'une mise à jour de l'arborescence « Historique des commits ». La commande git checkout
peut être utilisée dans un commit ou un périmètre de niveau fichier. Un checkout de niveau fichier modifiera le contenu du fichier pour correspondre à celui du commit spécifique.
Un revert est une opération qui prend un commit spécifique et crée un nouveau commit qui inverse le commit spécifique. La commande git revert
peut uniquement être exécutée pour un périmètre de niveau commit et ne dispose d'aucune fonctionnalité de niveau fichier.
Un reset est une opération qui prend un commit spécifique et réinitialise les « trois arborescences » de sorte qu'elles correspondent à l'état du dépôt au niveau du commit spécifique. Un reset peut être appelé dans trois modes différents qui correspondent aux trois arborescences.
Le checkout et le reset sont généralement utilisés pour procéder à des « annulations » locales ou privées. Ils modifient l'historique d'un dépôt, ce qui peut entraîner des conflits lors d'un push vers des dépôts partagés distants. Le revert est considéré comme une opération sûre, étant donné qu'il crée un nouvel historique qui peut être partagé à distance et n'écrase pas un historique dont peuvent dépendre les membres de l'équipe à distance.
Référence git reset, git revert et git checkout
Le tableau ci-dessous répertorie les utilisations les plus courantes de toutes ces commandes. Veillez à le conserver pour vous y référer ultérieurement, car vous aurez sans doute besoin d'en utiliser au moins quelques-unes en tant que développeur Git.
Commande | Périmètre | Utilisations courantes |
---|---|---|
git reset | Niveau commit | Supprime les commits dans une branche privée ou les changements non commités |
git reset | Niveau fichier | Annuler le staging d'un fichier |
Git checkout | Niveau commit | Basculer entre les branches ou inspecter d'anciens instantanés |
Git checkout | Niveau fichier | Annuler des changements dans le répertoire de travail |
Git revert | Niveau commit | Annuler des commits dans une branche publique |
Git revert | Niveau fichier | (N/A) |
Opérations de niveau commit
Les paramètres que vous définissez pour git reset
et git checkout
déterminent leur périmètre. Si vous ne spécifiez pas de chemin d'accès dans vos paramètres, ceux-ci s'appliqueront à tous les commits. Pour plus d'informations sur le sujet, consultez la section ci-dessous. Remarque : git revert
n'a pas d'homologue au niveau fichier.
Reset d'un commit spécifique
À l'échelle des commits, la réinitialisation permet de déplacer la pointe d'une branche vers un autre commit. Elle peut également servir à supprimer des commits dans la branche courante. Par exemple, la commande suivante fait reculer la branche hotfix
de deux commits.
git checkout hotfix git reset HEAD~2
Les deux commits situés à la fin de hotfix
constituent désormais des commits libres ou orphelins. Cela signifie qu'ils seront supprimés au prochain nettoyage de type garbage collection effectué par Git. En d'autres termes, cette opération revient à supprimer les commits concernés. Elle peut être visualisée comme suit :

Cette utilisation de git reset
constitue une manière simple d'annuler des changements qui n'ont pas encore été partagés. Cette commande est incontournable lorsque vous commencez à travailler sur une fonctionnalité, puis que tout à coup, vous vous rendez compte que vous vous êtes trompé et que vous voulez tout recommencer.
En plus de déplacer la branche courante, vous pouvez exécuter git reset
pour modifier l'instantané stagé et/ou le répertoire de travail en y ajoutant l'un des flags suivants :
--soft
– L'instantané stagé et le répertoire de travail restent inchangés.--mixed
– L'instantané stagé est aligné sur le commit spécifié, tandis que le répertoire de travail reste inchangé. C'est l'option par défaut.--hard
: l'instantané stagé et le répertoire de travail sont tous deux alignés sur le commit spécifié.
Pour vous aider, considérez ces modes comme une manière de définir le périmètre d'une opération git reset
. Pour en savoir plus, consultez la page git reset
.
Faire un checkout des anciens commits
La commande git checkout
est utilisée pour mettre à jour l'état du dépôt à un point spécifique de l'historique des projets. Une fois la branche nommée, vous pouvez basculer entre les branches.
git checkout hotfix
En interne, la commande ci-dessus a pour seul effet de déplacer HEAD
vers une autre branche et de mettre à jour le répertoire de travail. Puisque cette opération est susceptible d'annuler vos changements en local, Git vous oblige à faire un commit ou un stash de tout changement dans le répertoire de travail qui sera perdu lors du checkout. Contrairement à git reset
, git checkout
ne déplace aucune branche.

Vous pouvez également réaliser un checkout des commits arbitraires en ajoutant la référence du commit plutôt qu'une branche. Cette opération revient à faire un checkout d'une branche : la référence HEAD
est déplacée vers le commit spécifié. Par exemple, la commande suivante va extraire le grand-parent du commit courant :
git checkout HEAD~2
Elle peut s'avérer utile pour jeter un coup d'œil rapide à une ancienne version de votre projet. Cependant, puisqu'aucune référence de branche n'est associée au marqueur HEAD
courant, vous passez à l'état HEAD
détaché. Attention : si vous commencez à ajouter de nouveaux commits, il vous sera impossible de les récupérer une fois que vous aurez basculé sur une autre branche. C'est la raison pour laquelle vous devez toujours créer une nouvelle branche avant d'ajouter des commits à un HEAD
détaché.
Annuler les commits publics avec git revert
L'opération revert annule un commit en créant un nouveau commit. C'est une méthode sûre pour annuler des changements, car elle ne risque pas de réécrire l'historique du commit. Par exemple, la commande suivante détermine les changements contenus dans les commits (du 2e au dernier), crée un nouveau commit qui annule ces changements et ajoute le nouveau commit au projet existant.
git checkout hotfix git revert HEAD~2
Elle peut être visualisée comme suit :
Veillez à ne pas confondre cette commande avec git reset
, qui modifie l'historique des commits existant. Par conséquent, utilisez git revert
pour annuler des changements apportés à une branche publique, et git reset
pour faire de même, mais sur une branche privée.
Gardez à l'esprit que git revert
sert à annuler des changements commités, tandis que git reset HEAD
permet d'annuler des changements non commités.
À l'instar de git checkout
, git revert
est susceptible d'écraser des fichiers dans le répertoire de travail et vous demandera donc de faire un commit ou un stash des changements qui risqueraient d'être perdus pendant le revert.
Opérations de niveau fichier
Les commandes git reset
et git checkout
permettent aussi d'utiliser un chemin d'accès optionnel en guise de paramètre. Leur comportement s'en trouve fortement modifié. Au lieu d'opérer sur des instantanés entiers, elles se limitent à un seul fichier.
Commande git reset sur un fichier spécifique
Associée à un chemin d'accès, la commande git reset
met à jour l'instantané stagé staged snapshot pour l'aligner sur la version issue du commit spécifié. Par exemple, elle récupère la version de foo.py
dans l'avant-dernier commit et l'indexe pour le prochain commit :
git reset HEAD~2 foo.py
Tout comme la version de git reset
de niveau commit, elle est plus souvent utilisée avec HEAD
plutôt qu'avec un commit arbitraire. L'exécution de git reset HEAD foo.py
annulera foo.py
. Les changements qu'il contient seront toujours apparents dans le répertoire de travail.
Les flags --soft
, --mixed
et --hard
n'ont aucun effet sur la version de git reset
de niveau fichier, puisque l'instantané stagé est continuellement mis à jour, tandis que le répertoire de travail ne l'est jamais.
Checkout de fichier dans Git
L'extraction de fichiers s'apparente à l'utilisation de git reset
associée à un chemin d'accès, à cela près que c'est le répertoire de travail qui est mis à jour, et non la zone de staging. Contrairement à la version de cette commande de niveau commit, la référence HEAD
n'est pas déplacée, donc vous ne basculez pas entre les branches.
Par exemple, la commande suivante aligne le fichier foo.py
du répertoire de travail sur celui de l'avant-dernier commit :
git checkout HEAD~2 foo.py
Tout comme la version de git checkout
de niveau commit, cette commande peut être utilisée pour examiner les anciennes versions d'un projet. Cependant, son périmètre est limité au fichier spécifié.
Si vous indexez et commitez le fichier extrait, il sera remplacé par son ancienne version. Remarque : cette opération supprime tous les changements ultérieurs apportés au fichier, alors que la commande git revert
annule uniquement les changements apportés par le commit spécifié.
À l'instar de git reset
, cette commande est souvent utilisée avec HEAD
en guise de référence de commit. Par exemple, git checkout HEAD foo.py
a pour effet d'ignorer les changements non stagés apportés à foo.py
. Le résultat est le même que pour git reset HEAD --hard
à cela près que seul le fichier spécifié est concerné.
Résumé
À présent, vous avez toutes les clés pour annuler des changements dans un dépôt Git. Les commandes git reset
, git checkout
et git revert
peuvent prêter à confusion, mais si vous pensez à leurs effets sur le répertoire de travail, l'instantané stagé et l'historique des commits, vous n'aurez aucun mal à utiliser la bonne commande pour votre tâche en cours.