Comprendre git reset et git checkout : manipulation des arbres Git

Git repose sur trois structures de données principales qui représentent l'état de votre projet à différents niveaux :

Arbre Rôle
HEAD Instantanné du dernier commit, parent du prochain commit
Index (zone de staging) Instantanné préparé pour le prochain commit
Répertoire de travail Environnement de développement où vous modifiez les fichiers

La commande git reset permet de réécrire l'état de ces trois arbres selon une séquence précise, avec des niveaux d'arrêt définis par les options :

# Étape 1 : déplacer la référence HEAD (option --soft)
git reset --soft HEAD~n

# Étape 2 : mettre à jour l'index (option --mixed, par défaut)
git reset --mixed HEAD~n

# Étape 3 : mettre à jour le répertoire de travail (option --hard)
git reset --hard HEAD~n

Le comportement s'interrompt à l'étape correspondant à l'option fournie :

  • Avec --soft : seule la branche pointée par HEAD est déplacée.
  • Avec --mixed (ou sans option) : l'index est synchronisé avec le nouveau HEAD.
  • Avec --hard : le répertoire de travail est également écrasé.

Utilisation avec un chemin spécifique

Vous pouvez limiter l'action à un fichier particulier :

git reset fichier.txt
git reset --mixed HEAD fichier.txt

Dans ce scénario :

  • Le déplacement de HEAD est ignoré.
  • L'index est mis à jour à partir de HEAD pour le fichier ciblé.

Cela équivaut à annuler le staging du fichier, soit l'inverse exact de git add.

Pour récupérer une version spécifique d'un fichier depuis un commit particulier :

git reset <SHA-1> -- fichier.txt

Ici :

  • HEAD n'est pas déplacé.
  • L'index est mis à jour avec le contenu du fichier issu du commit SHA-1.

Comparaison avec git checkout

La commande git checkout manipule également les trois arbres, mais son comportement diffère selon qu'un chemin est fourni ou non.

Sans chemin : basculer de branche

Exécuter git checkout [branche] ressemble à git reset --hard [branche] : les trois arbres sont mis à jour. Cependant, deux différences majeures existent :

  • Sécurité du répertoire de travail : checkout tente une fution douce pour éviter de perdre des modifications non commitées. reset --hard écrase tout sans vérification.
  • Mise à jour de HEAD : reset déplace la branche courante (ex : develop) vers le commit cible. checkout déplace uniquement le pointeur HEAD vers une autre branche, sans modifier la branche précédente.

Exemple : si vous êtes sur develop (HEAD pointe sur develop) et que vous exécutez git reset master, develop pointe désormais sur le même commit que master. Avec git checkout master, develop reste inchangé et HEAD bascule directement sur master.

Avec chemin : restaurer un fichier

Lorsqu'un fichier est spécifié, checkout ne déplace pas HEAD. Il copie le contenu du commit (ou de l'index) vers l'index et le répertoire de travail :

git checkout [branche|SHA-1] -- fichier.txt

Cela équivaut à un git reset --hard [branche] fichier.txt (si cette syntaxe existait). Contrairement à reset sans chemin, cette opération n'est pas sécurisée : elle écrase les modifications locales du fichier.

Comme git reset et git add, git checkout accepte l'option --patch pour restaurer sélectivement des portions d'un fichier.

Étiquettes: git reset git checkout HEAD index working directory

Publié le 9 juillet à 01h49