Passer au contenu
GitTree

Leçon 28 · Récupération

Annuler une modification dans l'historique partagé

Annulez une mauvaise modification que d'autres ont déjà apportée en ajoutant un nouveau commit qui l'annule, au lieu de supprimer l'historique, et publiez le correctif avec un push normal.

Progression enregistrée dans ce navigateur.

La lecture charge la vidéo depuis YouTube (mode de confidentialité amélioré).

Narration en anglais · English and Arabic légendes

Ouvrez la page vidéoRegarder sur YouTube

Ce que vous apprendrez

  • Expliquez le retour comme une validation inverse et pourquoi cela convient à l'histoire des autres.
  • Prédisez le parent du nouveau commit et le fichier qu'il laisse.
  • Gérez un retour en conflit et sachez pourquoi l'annulation d'une fusion demande un parent.
  • Publiez le correctif sans forcer.

Avant de commencer

Vous êtes sur shared/dark-regression, une branche du résultat M de la leçon 18. Son dernier commit, "style : introduire la régression du contraste de répétition", ajoute une règle à styles.css, body { color: #f7f8fa; }, qui donne au texte de la page la même couleur pâle que l'arrière-plan. Ce commit se trouve déjà sur un serveur local que vous avez configuré pour cette leçon, donc un coéquipier peut l'avoir. Vous voulez que le texte soit à nouveau lisible sans réécrire quoi que ce soit que d'autres ont déjà.

Tout est local et sur le forfait gratuit (GitTree vous demande de vous connecter) : pas de compte d'hébergement, pas de fournisseur, pas d'Internet. Le serveur est un référentiel nu local, pas GitHub. Chaque identité est fictive (exemple.com). N'exécutez jamais cette leçon dans un projet réel.

Apportez les modifications dans GitTree ou avec les commandes Git natives, pas les deux dans la même copie. La lecture du résultat est toujours sûre. Les étiquettes de menu proviennent des propres chaînes de GitTree 2.0 et les commandes natives ont été exécutées avec Git 2.43 dans des copies jetables. Les étapes GitTree n'ont pas été exécutées le macOS, Windows ou Linux.

Effets de concept et d'état

Revert examine ce qu'un commit a modifié et ajoute un new commit qui applique la modification opposée. Le mauvais commit reste dans l’historique, tout comme la preuve qu’il s’est produit. Reset fait le contraire : il recule la branche et laisse le commit de côté, ce qui est bien pour le travail que vous seul avez, mais cela oblige tous ceux qui ont déjà le commit à réparer leur copie.

Ici, le parent du nouveau commit est le mauvais commit, et le fichier se termine exactement comme avant. La branche avance d'un commit et le serveur l'accepte avec un push ordinaire, car cela ne fait qu'ajouter à ce qui est là.

Un changement inverse dépend de ce qui l’entoure. Si quelqu'un a modifié les mêmes lignes après le mauvais commit, le retour s'arrête avec un conflit et vous le résolvez comme n'importe quel autre (leçon 23), ou vous abandonnez. L'annulation d'un commit merge vous demande de choisir sur quel parent le changement est mesuré : généralement le premier, dans lequel la branche a fusionné. L'annulation d'une fusion indique également à Git que ses modifications ont été gérées, donc la fusion ultérieure de la même branche peut ne rien signaler à fusionner. Cette leçon annule un commit ordinaire et affiche uniquement cette boîte de dialogue.

Seule la branche actuelle obtient un commit. Rien d'autre ne bouge jusqu'à ce que vous poussiez.

Préparer l’état exact du projet

Commencez par une copie ordinaire séparée du résultat M de la leçon 18 et laissez votre original intact. Créez la branche, enregistrez DOC_DARK_BAD sur styles.css et validez-la, créez un nouveau référentiel nu vide à côté de la copie, ajoutez-la en tant que télécommande appelée rehearsal et poussez la branche avec son amont. CSS_RESTORED est à quoi le fichier doit ressembler après le rétablissement.

Entrées de fichiers complètes

Enregistrez uniquement à la phase nommée ci-dessous. Ce sont des corps UTF-8/LF complets avec une nouvelle ligne finale ; ne collez jamais les clôtures Markdown. Les fichiers exécutables inchangés héritent de l'entrée nommée. Les versions dans des variantes distinctes ne doivent pas écraser l'original.

styles.css — DOC_DARK_BAD

Extrait de fichier · css
:root {
  color-scheme: light;
  --page: #f7f8fa;
  --surface: #ffffff;
  --text: #17212e;
  --link: #154ab5;
  --line: #bac4d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.6 system-ui, sans-serif;
}

a {
  color: var(--link);
}

.site-header,
main,
footer {
  width: min(68rem, 100% - 2rem);
  margin-inline: auto;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.hero {
  max-width: 48rem;
  padding-block: 3rem;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.2;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
}

.feature-card {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--surface);
}

section {
  margin-block-end: 2rem;
}

button,
input {
  font: inherit;
}

button,
input {
  padding: 0.5rem 0.75rem;
}

:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
}

form {
  display: grid;
  max-width: 28rem;
  gap: 0.5rem;
}

body { color: #f7f8fa; }

styles.css — CSS_RESTORED

Extrait de fichier · css
:root {
  color-scheme: light;
  --page: #f7f8fa;
  --surface: #ffffff;
  --text: #17212e;
  --link: #154ab5;
  --line: #bac4d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.6 system-ui, sans-serif;
}

a {
  color: var(--link);
}

.site-header,
main,
footer {
  width: min(68rem, 100% - 2rem);
  margin-inline: auto;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.hero {
  max-width: 48rem;
  padding-block: 3rem;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.2;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
}

.feature-card {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--surface);
}

section {
  margin-block-end: 2rem;
}

button,
input {
  font: inherit;
}

button,
input {
  padding: 0.5rem 0.75rem;
}

:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
}

form {
  display: grid;
  max-width: 28rem;
  gap: 0.5rem;
}

Dans GitTree

Ouvrez la palette avec Commande+Maj+P (Ctrl+Maj+P sur Ubuntu). Les actions sur une validation utilisent le menu contextuel de cette validation.

  1. Construisez la branche, le commit et le serveur local comme le montre la section suivante. Gardez shared/dark-regression extrait et l'arborescence de travail propre.
  2. Dans le graphique, sélectionnez le mauvais commit et lisez ses détails : un chemin modifié, styles.css et une ligne ajoutée.
  3. Faites un clic droit dessus et choisissez Revert Commit. Il s'applique immédiatement sur la succursale où vous vous trouvez ; il n'y a pas d'éditeur de messages. L'avis indique "Inversé". S'il s'arrête à la place, la bannière "Reverting… on shared/dark-regression" propose Resolve, Continue et Abort….
  4. Sélectionnez le nouveau commit. Son sujet est Revert "style: introduce the rehearsal contrast regression" et son parent est le mauvais commit. Le mauvais commit est toujours dans le graphique.
  5. Ouvrir styles.css : c'est CSS_RESTORED, sans la règle ajoutée.
  6. Cliquez sur la barre d'outils Push. Il s'agit d'une poussée normale de la branche vers l'amont ; ne choisissez pas Force Push (With Lease)…. L'avis indique "Poussement partagé/dark-régression vers répétition/partagé/dark-régression".
  7. Vérifiez le résultat : l'arborescence de travail est propre, les deux commits sont dans le graphe et la branche serveur est sur le nouveau commit.

Si vous cliquez avec le bouton droit sur une validation de fusion, Revert Commit ouvre « Annuler la fusion… » avec First parent (the branch merged into) et Second parent (the branch merged in). Ne l'exécutez pas ici.

Pour chaque commit ordinaire du cours : Summary est le sujet indiqué, Description est vide et les options Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit et Allow Empty Commit restent désactivées.

Dans la borne

Dans une copie séparée du résultat de la leçon 18 :

Command · bash
git switch --create shared/dark-regression

Enregistrez DOC_DARK_BAD sous styles.css, puis :

Command · bash
git add -- styles.css
git commit --quiet -m "style: introduce the rehearsal contrast regression"
BAD_SHA="$(git rev-parse HEAD)"
git init --quiet --bare --initial-branch=main ../gittree-revert-origin.git
git remote add rehearsal ../gittree-revert-origin.git
git push --quiet --set-upstream rehearsal shared/dark-regression

Maintenant revenez, publiez et lisez le résultat :

Command · bash
git revert --no-edit "$BAD_SHA"
git merge-base --is-ancestor "$BAD_SHA" HEAD; echo $?
git log -1 --format=%s
git push --quiet rehearsal shared/dark-regression
git status --short
git ls-remote --heads rehearsal refs/heads/shared/dark-regression
git rev-parse HEAD
Sortie
0
Revert "style: introduce the rehearsal contrast regression"

La vérification de l'ancêtre affiche 0 : le mauvais commit est toujours derrière HEAD. styles.css est CSS_RESTORED, le statut est vide et les deux identifiants de ls-remote et rev-parse sont égaux. Aucune option de force n’était impliquée. Dans une copie séparée où un commit ultérieur modifie la même ligne, git revert s'arrête avec "CONFLIT (contenu)" et les indices git revert --continue et git revert --abort. Et git revert lors d'une validation de fusion refuse avec "est une fusion mais aucune option -m n'a été donnée" ; -m 1 choisit le premier parent.

Résultat

Where you end: shared/dark-regression a un nouveau commit qui annule le mauvais. La page utilise CSS_RESTORED, le mauvais commit est toujours dans l'historique, la branche du serveur est sur le nouveau commit, l'arborescence de travail est propre et rien n'a été forcé.

Erreurs courantes

  • Utiliser la réinitialisation et une poussée forcée pour "supprimer" un commit que d'autres ont déjà.
  • En attendant que le mauvais commit disparaisse du journal.
  • Annuler une fusion sans choisir volontairement son parent.
  • En poussant avant de regarder le fichier, vous revenez à gauche.

Si quelque chose ne va pas

Si le retour s'arrête avec un conflit, lisez la bannière. Resolve et Continue terminent-le comme dans la leçon 23 ; Abort… renvoie la branche là où elle se trouvait. Si le retour lui-même était une erreur une fois terminé, annulez le retour : il s'agit simplement d'un autre commit.

Vérifiez votre compréhension

Répondez à chaque question, puis lisez pourquoi. Les questions marquées « Obligatoire » comptent pour terminer la leçon.

  1. Question 1 de 6

    Que fait le revert au mauvais commit ?

    Choisissez une réponse.

  2. Question 2 de 6

    Après le retour, lesquels sont vrais ?

    Choisissez chaque réponse qui s'applique.

  3. Question 3 de 6
    Obligatoire

    Vous annulez le mauvais commit et poussez normalement. Où est la branche du serveur après ?

    Choisissez une réponse.

  4. Question 4 de 6

    Modifiez l'entrée : un commit ultérieur modifie la même ligne que le mauvais commit ajouté, puis vous annulez le mauvais commit. Ce qui se produit?

    Choisissez une réponse.

  5. Question 5 de 6
    Obligatoire

    Vous essayez d'annuler une validation de fusion et Git dit "il s'agit d'une fusion mais aucune option -m n'a été donnée". Que se passe-t-il et que faites-vous ?

    Choisissez une réponse.

  6. Question 6 de 6
    Obligatoire

    Après le retour et la poussée, quelles relectures montrent qu'il a fait ce que dit la leçon ?

    Choisissez chaque réponse qui s'applique.

0 sur 6 corrects

Répondez correctement aux questions requises pour terminer la leçon.

Vérifié dans ce navigateur.

Pratique

Signalez le sujet du retour, son parent, si le mauvais commit est toujours un ancêtre et si la branche du serveur est égale à HEAD. Prédisez ensuite ce qui se passerait si une validation ultérieure avait modifié la même ligne avant votre retour.

Votre propre confirmation : le site ne peut pas voir votre ordinateur.

Pour terminer la leçon, répondez correctement aux questions demandées et confirmez l'exercice pratique.

Récapitulatif

  • Revert ajoute un commit qui en annule un autre.
  • L’histoire reste ; le fichier remonte.
  • Une poussée normale suffit.

Termes du glossaire introduits

Revenir — عكس; changement inverse — تغيير معاكس; parent principal - الأب الرئيسي.

Transcription vidéo

La narration de la vidéo, repère par repère.

Afficher la transcription
  1. Annuler une modification déjà effectuée par d'autres personnes avoir.
  2. La réinitialisation ramène la branche en arrière. Revert ajoute un nouveau commit à la place.
  3. D'autres ont déjà l'ancien commit. Revenir laisse sa copie valable.
  4. Construisez la branche partagée avec un mauvais commit, et un serveur local qui l'a.
  5. Le graphique montre M et le mauvais commit sur haut.
  6. Le mauvais commit ajoute une ligne et le texte devient pâle.
  7. Notez son identifiant.
  8. Faites un clic droit dessus et choisissez Revert Commit.
  9. Cela s’applique immédiatement. Il n'y a pas de message éditeur.
  10. L'avis indique que c'est annulé.
  11. Le nouveau commit porte le nom de l'ancien.
  12. Son parent est le mauvais commit. Rien n'était supprimé.
  13. Le fichier est de retour tel qu'il était. La pâle règle est parti.
  14. Et le graphique montre les deux commits. Le l'histoire n'a fait que grandir.
  15. Seule cette branche a bougé. Rien n'est encore publié.
  16. La branche a un commit d'avance sur le serveur.
  17. Cliquez sur Pousser. C'est une poussée normale.
  18. L'avis nomme la succursale et le serveur.
  19. Aucune force n’était nécessaire. La poussée n'a fait qu'ajouter un commettre.
  20. Dans le terminal, git revert sans modification fait de même.
  21. Le mauvais commit est toujours un ancêtre. Le la réponse est zéro.
  22. Et le sujet commence par Revert.
  23. Push, puis comparez l'ID du serveur avec TÊTE. Ils sont égaux.
  24. Modifier l'entrée : quelqu'un a modifié la même chose ligne plus tard.
  25. Le retour s'arrête avec un conflit. Résoudre et continuer, ou abandonner.
  26. L'annulation d'une fusion demande un parent. Habituellement, c'est le premier.
  27. Après avoir annulé une fusion, fusionnez-la la branche à nouveau ne peut rien faire.
  28. Pratique : signaler le sujet, le parent, vérification de l'ancêtre et l'ID du serveur.
  29. Ensuite, trouvez un commit perdu avec le reflog.