Git Reset et Reflog

GitGitBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Bienvenue, voyageur temporel de Git! Aujourd'hui, nous allons explorer deux fonctionnalités puissantes de Git qui vous donneront un contrôle sans précédent sur l'historique de votre dépôt : git reset et git reflog. Ces outils sont comme les commandes avancées de votre machine à remonter le temps de Git, vous permettant de naviguer entre différents états de votre projet et même de récupérer des travaux « perdus ».

La commande git reset est un outil polyvalent qui peut vous aider à annuler des modifications, à désindexer des fichiers et même à réécrire l'historique de vos validations (commits). Cependant, avec un grand pouvoir vient une grande responsabilité, et git reset peut sembler un peu intimidant pour les nouveaux venus. C'est là que git reflog entre en jeu - c'est comme un filet de sécurité, qui enregistre toutes les modifications que vous apportez aux références (refs) de votre dépôt (comme les extrémités des branches), vous permettant de récupérer même après les réinitialisations les plus drastiques.

Dans ce laboratoire (LabEx), nous aborderons :

  1. Soft Reset (Réinitialisation douce) : Déplacer le HEAD sans modifier le répertoire de travail ni la zone de préparation (staging area)
  2. Mixed Reset (Réinitialisation mixte) : Désindexer les modifications tout en conservant les modifications dans le répertoire de travail
  3. Hard Reset (Réinitialisation totale) : Supprimer complètement les modifications
  4. Utilisation du Reflog pour récupérer après des opérations « destructrices »
  5. Réinitialisations basées sur le temps : Ramener votre dépôt à un état à un moment précis

À la fin de ce laboratoire (LabEx), vous aurez une bonne compréhension de la façon d'utiliser ces puissantes fonctionnalités de Git de manière sûre et efficace. Vous pourrez manipuler l'historique de votre dépôt avec confiance, sachant que vous pourrez toujours retrouver votre chemin si besoin.

Plongeons-y et commençons à maîtriser git reset et reflog!


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/SetupandConfigGroup(["Setup and Config"]) git(("Git")) -.-> git/BasicOperationsGroup(["Basic Operations"]) git(("Git")) -.-> git/DataManagementGroup(["Data Management"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git/SetupandConfigGroup -.-> git/init("Initialize Repo") git/BasicOperationsGroup -.-> git/status("Check Status") git/BasicOperationsGroup -.-> git/commit("Create Commit") git/DataManagementGroup -.-> git/reset("Undo Changes") git/BranchManagementGroup -.-> git/log("Show Commits") git/BranchManagementGroup -.-> git/reflog("Log Ref Changes") subgraph Lab Skills git/init -.-> lab-387491{{"Git Reset et Reflog"}} git/status -.-> lab-387491{{"Git Reset et Reflog"}} git/commit -.-> lab-387491{{"Git Reset et Reflog"}} git/reset -.-> lab-387491{{"Git Reset et Reflog"}} git/log -.-> lab-387491{{"Git Reset et Reflog"}} git/reflog -.-> lab-387491{{"Git Reset et Reflog"}} end

Configuration de votre espace de travail

Avant de commencer à effectuer des réinitialisations (resets) et à utiliser le reflog, configurons un espace de travail avec quelques validations (commits) sur lequel nous pourrons expérimenter. Nous allons créer un nouveau répertoire, initialiser un dépôt Git et ajouter quelques fichiers avec plusieurs validations.

Ouvrez votre terminal et tapez ces commandes :

cd ~/project
mkdir git-reset-lab
cd git-reset-lab
git init

Maintenant, créons quelques fichiers et effectuons une série de validations en copiant et en collant les commandes suivantes dans votre terminal :

echo "## Git Reset and Reflog Lab" > README.md
git add README.md
git commit -m "Initial commit"

echo "function add(a, b) { return a + b; }" > math.js
git add math.js
git commit -m "Add addition function"

echo "function subtract(a, b) { return a - b; }" >> math.js
git add math.js
git commit -m "Add subtraction function"

echo "function multiply(a, b) { return a * b; }" >> math.js
git add math.js
git commit -m "Add multiplication function"

Analysons ce que nous venons de faire :

  1. Nous avons créé un fichier README et effectué notre première validation.
  2. Nous avons créé un fichier JavaScript avec une fonction d'addition et l'avons validé.
  3. Nous avons ajouté une fonction de soustraction au même fichier et l'avons validé.
  4. Enfin, nous avons ajouté une fonction de multiplication et l'avons validée.

Maintenant, nous avons un dépôt avec un historique sur lequel nous pouvons expérimenter!

Soft Reset (Réinitialisation douce) : Déplacement du HEAD

Le premier type de réinitialisation que nous allons explorer est la « réinitialisation douce » (soft reset). Une réinitialisation douce déplace le HEAD (et la branche actuelle) vers une autre validation (commit), mais elle ne modifie ni la zone de préparation (staging area) ni le répertoire de travail. Cela est utile lorsque vous souhaitez « annuler » certaines validations tout en conservant toutes les modifications pour une nouvelle validation.

Essayons une réinitialisation douce :

git reset --soft HEAD~1

Cette commande déplace le HEAD d'une validation en arrière. Le ~1 signifie « une validation avant la validation actuelle ». Vous pouvez utiliser ~2, ~3, etc., pour reculer de plusieurs validations.

Maintenant, si vous exécutez git status, vous verrez que les modifications de la dernière validation sont indexées et prêtes à être validées à nouveau. Les fichiers de votre répertoire de travail n'ont pas été modifiés.

Cela est utile dans les scénarios où vous souhaitez « fusionner » vos dernières validations en une seule. Vous pouvez effectuer une réinitialisation douce en arrière de quelques validations, puis effectuer une nouvelle validation avec toutes ces modifications.

Effectuons une nouvelle validation de ces modifications avec un nouveau message :

git commit -m "Add subtraction and multiplication functions"

N'oubliez pas que, bien que la réinitialisation douce soit généralement sûre (car elle ne supprime aucune modification), elle réécrit l'historique. Si vous avez déjà poussé (push) les validations originales, vous devrez effectuer un push forcé pour mettre à jour la branche distante, ce qui peut poser des problèmes pour les collaborateurs. Communiquez toujours avec votre équipe avant de réécrire l'historique partagé!

Mixed Reset (Réinitialisation mixte) : Désindexation des modifications

Le prochain type de réinitialisation que nous allons examiner est la « réinitialisation mixte ». En fait, c'est le mode par défaut de git reset si vous ne spécifiez pas de drapeau. Une réinitialisation mixte déplace le HEAD et met à jour la zone de préparation (staging area) en conséquence, mais elle ne touche pas au répertoire de travail.

Effectuons quelques modifications et indexons-les :

echo "function divide(a, b) { return a / b; }" >> math.js
git add math.js

Maintenant, disons que nous avons changé d'avis et que nous ne souhaitons pas encore indexer cette modification. Nous pouvons utiliser une réinitialisation mixte :

git reset HEAD

Cela désindexe nos modifications mais les conserve dans le répertoire de travail. Si vous exécutez git status maintenant, vous verrez que math.js a été modifié mais n'est pas indexé.

La réinitialisation mixte est utile lorsque vous avez indexé certaines modifications mais que vous décidez ensuite que vous n'êtes pas prêt à les valider (committer) encore. Peut-être que vous souhaitez revoir les modifications ou apporter d'autres modifications avant de les indexer.

N'oubliez pas que, contrairement à la réinitialisation douce (soft reset), la réinitialisation mixte modifie la zone de préparation. Cependant, elle reste sûre dans le sens où elle ne supprime aucune de vos modifications - tout est toujours dans votre répertoire de travail.

Hard Reset (Réinitialisation totale) : Suppression des modifications

Le troisième et le plus radical type de réinitialisation est la « réinitialisation totale » (hard reset). Une réinitialisation totale déplace le HEAD, met à jour la zone de préparation (staging area) et met à jour le répertoire de travail en conséquence. Cela signifie qu'elle supprime toutes les modifications depuis la validation (commit) vers laquelle vous effectuez la réinitialisation.

Essayons une réinitialisation totale :

git add math.js
git commit -m "Add division function"
git status
git reset --hard HEAD~1

Cela indexe et valide notre fonction de division, puis effectue une réinitialisation totale vers la validation précédente, annulant ainsi effectivement notre dernière validation et supprimant les modifications.

Si vous regardez le fichier math.js maintenant, vous verrez que la fonction de division a disparu. C'est comme si nous ne l'avions jamais écrite.

La réinitialisation totale est puissante mais dangereuse. Elle est utile lorsque vous souhaitez complètement supprimer certains travaux et repartir à partir d'une validation précédente. Cependant, soyez très prudent avec elle, car elle peut supprimer définitivement des modifications.

Vérifiez toujours deux fois que vous effectuez la réinitialisation vers la bonne validation avant de faire une réinitialisation totale. Si vous n'êtes pas sûr, il est plus sûr d'utiliser une réinitialisation douce (soft reset) ou mixte (mixed reset), ou de créer une nouvelle branche avant d'expérimenter.

Utilisation du reflog pour récupérer des validations perdues

Maintenant, que se passe-t-il si vous réalisez que vous n'avez pas voulu supprimer cette fonction de division? C'est là que git reflog vient à la rescousse. Le reflog est un journal de tous les emplacements où le HEAD s'est trouvé dans votre dépôt local. C'est comme un super-historique qui enregistre même les commandes de réécriture de l'historique telles que le reset.

Regardons le reflog :

git reflog

Vous devriez voir une liste de toutes les actions récentes que vous avez effectuées, y compris vos réinitialisations. Chaque entrée a un identifiant HEAD@{n}.

Pour récupérer votre validation perdue, vous pouvez réinitialiser à l'état précédent votre réinitialisation totale :

git reset --hard HEAD@{1}

Cela réinitialise à l'état du HEAD avant votre dernière action (qui était la réinitialisation totale).

Vérifiez le fichier math.js maintenant, et vous devriez voir que votre fonction de division est de retour!

cat math.js
function add(a, b) { return a + b; }
function subtract(a, b) { return a - b; }
function multiply(a, b) { return a * b; }
function divide(a, b) { return a / b; }

Le reflog est un puissant filet de sécurité qui vous permet de récupérer à partir de presque tout accident Git. Cependant, n'oubliez pas qu'il est local à votre machine et temporaire (les entrées sont généralement conservées pendant 30 à 90 jours). Il n'est pas un substitut aux sauvegardes régulières ni à la publication de votre travail sur un dépôt distant.

Réinitialisations basées sur le temps

Git vous permet également de réinitialiser votre dépôt à l'état qu'il avait à un moment précis. Cela peut être utile si vous vous souvenez approximativement de quand votre dépôt était dans l'état auquel vous souhaitez revenir.

Essayons une réinitialisation basée sur le temps :

git reset --hard master@{"1 hour ago"}

Cela réinitialise votre dépôt à l'état qu'il avait il y a 1 heure. Vous pouvez utiliser divers descripteurs de temps tels que "hier", "il y a 2 jours", "il y a 3 minutes", etc.

Faites attention avec les réinitialisations basées sur le temps, car elles peuvent être moins précises que la réinitialisation à une validation spécifique. Vérifiez toujours l'état de votre dépôt après une réinitialisation basée sur le temps pour vous assurer que vous êtes arrivé à l'endroit prévu.

N'oubliez pas que vous pouvez toujours utiliser le reflog pour annuler une réinitialisation basée sur le temps si elle ne vous donne pas le résultat attendu.

Résumé

Félicitations, seigneur du temps de Git! Vous venez de maîtriser certaines des commandes les plus puissantes et potentiellement dangereuses de Git. Récapitulons les concepts clés que nous avons couverts :

  1. Soft Reset (Réinitialisation douce) : Déplace le HEAD sans modifier la zone de préparation (staging area) ni le répertoire de travail. Utile pour fusionner des validations (squashing commits).
  2. Mixed Reset (Réinitialisation mixte) : Déplace le HEAD et met à jour la zone de préparation, mais ne touche pas au répertoire de travail. Parfait pour désindexer des modifications.
  3. Hard Reset (Réinitialisation totale) : Déplace le HEAD, met à jour la zone de préparation et met à jour le répertoire de travail. Puissant mais potentiellement destructeur.
  4. Reflog : Un filet de sécurité qui enregistre toutes les modifications apportées au HEAD, vous permettant de récupérer à partir de presque tout accident Git.
  5. Réinitialisations basées sur le temps : Vous permettent de réinitialiser votre dépôt à l'état qu'il avait à un moment précis.

N'oubliez pas que avec de grands pouvoirs viennent de grandes responsabilités. Bien que ces commandes vous donnent un contrôle incroyable sur l'historique de votre dépôt, elles peuvent également être dangereuses si elles sont utilisées sans précaution. Vérifiez toujours deux fois avant d'effectuer une réinitialisation, en particulier une réinitialisation totale, et rappelez-vous que le reflog est votre ami si quelque chose tourne mal.

Au fur et à mesure de votre parcours avec Git, pratiquez ces commandes dans un environnement sûr jusqu'à ce que vous vous sentiez à l'aise avec elles. Ce sont des outils puissants qui peuvent grandement améliorer votre flux de travail Git lorsqu'ils sont utilisés correctement.

Bonne réinitialisation, et que votre historique Git soit toujours propre et significatif!