Comment utiliser Git Revert

109

Comment est-il git revertutilisé?

Cela peut sembler une question en double, mais lorsque les gens la posent, la réponse est souvent, utilisez git resetcomme pour Revenir à un commit par un hachage SHA dans Git?

Ensuite, quand quelqu'un demande comment utiliser les git resetgens, répondez en disant que vous devez utiliser git revertselon Git - comment revenir en arrière

Avant que vous ne le sachiez, 8 personnes différentes sont apparues avec leurs propres moyens uniques pour sauver le cul de l'OP, tout cela au-dessus de votre tête.

Essayons donc de coller le mémoire et d'écrire un guide des nuls git revert.

Un scénario: vous vous êtes engagé deux fois à maîtriser et c'est mauvais. Vous avez poussé et d'autres personnes ont vos mauvais changements.

Vous voulez l'annuler. Ce n'est pas quelque chose que vous pouvez annuler manuellement dans le code vous-même, disons qu'un assistant ou un gestionnaire de paquets a changé des tonnes de choses partout - vous voulez juste tout remettre comme il était.

C'est cela le contrôle de source. Je suis sûr que c'est facile.

D'accord, vous allez l'utiliser git revertmais comment?

Et après avoir couru git revert, devez-vous faire autre chose après? Devez-vous valider les modifications effectuées ou revenir directement dans le dépôt ou quoi ??

De toute évidence, vous devrez pousser à nouveau et probablement annoncer vos balles à l'équipe.

Luke Puplett
la source

Réponses:

120

git revert fait un nouveau commit

git revert crée simplement un nouveau commit qui est l'opposé d'un commit existant.

Il laisse les fichiers dans le même état que si la validation qui a été annulée n'avait jamais existé. Par exemple, considérons l'exemple simple suivant:

$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Initial text" > README.md
$ git add README.md
$ git commit -m "initial commit"
[master (root-commit) 3f7522e] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo "bad update" > README.md 
$ git commit -am "bad update"
[master a1b9870] bad update
 1 file changed, 1 insertion(+), 1 deletion(-)

Dans cet exemple, l'historique des commit a deux commits et le dernier est une erreur. Utilisation de git revert:

$ git revert HEAD
[master 1db4eeb] Revert "bad update"
 1 file changed, 1 insertion(+), 1 deletion(-)

Il y aura 3 commits dans le journal:

$ git log --oneline
1db4eeb Revert "bad update"
a1b9870 bad update
3f7522e initial commit

Il y a donc un historique cohérent de ce qui s'est passé, mais les fichiers sont comme si la mauvaise mise à jour ne s'était jamais produite:

cat README.md 
Initial text

Peu importe où dans l'historique se trouve le commit à annuler (dans l'exemple ci-dessus, le dernier commit est annulé - tout commit peut être annulé).

Questions de clôture

devez-vous faire autre chose après?

A git revertest juste un autre commit, alors par exemple, poussez vers la télécommande pour que les autres utilisateurs puissent extraire / récupérer / fusionner les modifications et vous avez terminé.

Devez-vous valider les modifications effectuées ou est-ce que la restauration s'engage directement dans le dépôt?

git revert est un commit - il n'y a pas d'étapes supplémentaires en supposant que la restauration d'un seul commit est ce que vous vouliez faire.

Évidemment, vous devrez pousser à nouveau et probablement l'annoncer à l'équipe.

En effet - si la télécommande est dans un état instable - communiquer au reste de l'équipe qu'il doit tirer pour obtenir le correctif (le commit de retour) serait la bonne chose à faire :).

AD7six
la source
En guise de confirmation, à la fois pour la première déclaration ici et pour tous ceux qui se demandent la même chose, je me suis simplement demandé comment cela fonctionne, vous pouvez annuler un retour, où il y a plusieurs nouveaux commits depuis le retour que vous rétablissez. Donc, revert n'est vraiment qu'un commit de l'opposé du commit annulé. Vous pourriez, bien sûr, avoir des conflits ... mais c'est une autre histoire.
GG2
Je trouve toujours préférable d'éviter de s'engager avec lui, juste de passer en revue les modifications en premier et j'utilise, git revert -n <commitToRevet> ou git revert --no-commit <commitToRevet>
Eklavyaa
2
Je voulais juste dire qu'après des années de stackoverflow, je pense que c'est peut-être l'une des meilleures réponses que j'ai jamais rencontrées. Excellent exemple et explication.Merci.
user3344977
Je suis entré ici en espérant obtenir plus d'informations, quelque chose comme un TLDR de ce raw.githubusercontent.com/git/git/master/Documentation/howto/…
wviana
1
@wviana Si les informations que vous avez trouvées sont insuffisantes, veuillez écrire une réponse. Notez que le débordement de pile ne remplace pas la documentation officielle (à laquelle vous semblez établir un lien et couvre une portée beaucoup plus large que cette question).
AD7six
35

Utilisez git revert comme ceci:

git revert <insert bad commit hash here>

git revertcrée un nouveau commit avec les modifications qui sont annulées. git resetefface votre historique git au lieu de faire un nouveau commit.

Les étapes suivantes sont les mêmes que pour tout autre commit.

Johnny Z
la source
La différence entre "revenir à une validation" et "revenir à une validation" est assez subtile pour que je me débatte avec cette commande depuis des années. Votre explication l'a résolu pour moi instantanément. Merci!
claviska le
24

La raison resetetrevert tendance à revenir souvent dans les mêmes conversations est que différents systèmes de contrôle de version les utilisent pour signifier des choses différentes.

En particulier, les personnes habituées à SVN ou P4 qui souhaitent supprimer les modifications non validées d'un fichier vont souvent chercher revertavant de se faire dire qu'elles le souhaitent réellement reset.

De même, l' revertéquivalent dans d'autres VCS est souvent appelé rollbackou quelque chose de similaire - mais «rollback» peut aussi signifier «Je veux complètement supprimer les derniers commits», ce qui est approprié resetmais pas revert. Donc, il y a beaucoup de confusion où les gens savent ce qu'ils veulent faire, mais ne savent pas quelle commande ils devraient utiliser pour cela.

Quant à vos questions réelles sur le retour ...

D'accord, vous allez utiliser git revert mais comment?

git revert first-bad-commit..last-bad-commit

Et après avoir exécuté git revert, devez-vous faire autre chose après? Devez-vous valider les modifications effectuées ou revenir directement dans le dépôt ou quoi ??

Par défaut, git revertvous demande un message de validation, puis valide les résultats. Cela peut être annulé. Je cite la page de manuel :

--Éditer

Avec cette option, git revert vous permettra de modifier le message de validation avant de valider la restauration. Il s'agit de la valeur par défaut si vous exécutez la commande à partir d'un terminal.

--no-commit

Habituellement, la commande crée automatiquement des validations avec des messages de journal de validation indiquant quels validations ont été annulées. Cet indicateur applique les modifications nécessaires pour rétablir les commits nommés dans votre arborescence de travail et l'index, mais n'effectue pas les commits. De plus, lorsque cette option est utilisée, votre index ne doit pas nécessairement correspondre à la validation HEAD. Le retour est effectué par rapport à l'état de début de votre index.

Ceci est utile lorsque vous rétablissez l'effet de plusieurs validations sur votre index à la suite.

En particulier, par défaut, il crée un nouveau commit pour chaque commit que vous annulez. Vous pouvez utiliser revert --no-commitpour créer des modifications en les annulant toutes sans les valider en tant que commits individuels, puis vous engager à votre guise.

ToxicFrog
la source
git revert first-bad-commit..last-bad-commit: Je pense que cela devrait être git revert parent-of-first-bad-commit..last-bad-commit.
user1071847
9

La question est assez ancienne mais le retour est toujours déroutant les gens (comme moi)

En tant que débutant, après quelques essais et erreurs (plus d'erreurs que d'essais), j'ai un point important:

  • git revertnécessite l'ID du commit que vous souhaitez supprimer pour le conserver dans votre historique

  • git resetrequiert le commit que vous souhaitez conserver et supprimera par conséquent tout ce qui suit de l'historique.

Autrement dit, si vous utilisez revert avec le premier identifiant de commit, vous vous retrouverez dans un répertoire vide et un commit supplémentaire dans l'historique, tandis qu'avec reset votre répertoire sera .. retourné au commit initial et votre historique deviendra comme si le ou les derniers commit (s) ne se sont jamais produits.

Pour être encore plus clair, avec un journal comme celui-ci:

# git log --oneline

cb76ee4 wrong
01b56c6 test
2e407ce first commit

L' utilisation git revert cb76ee4volonté par défaut apporter vos fichiers à 01b56c6 et ajoutera un autre engagement à votre histoire:

8d4406b Revert "wrong"
cb76ee4 wrong
01b56c6 test
2e407ce first commit

git reset 01b56c6 à la place ramènera vos fichiers à 01b56c6 et nettoiera tout autre commit après cela de votre historique:

01b56c6 test
2e407ce first commit

Je sais que ce sont "la base" mais c'était assez déroutant pour moi, en exécutant revertsur le premier identifiant ('premier commit') je m'attendais à trouver mes fichiers initiaux, il a fallu un certain temps pour comprendre que si vous avez besoin de récupérer vos fichiers en tant que «premier commit», vous devez utiliser l'identifiant suivant.

nnsense
la source
J'ai observé la même chose. c'est vraiment déroutant mais si important à savoir. tout récemment, j'ai dû aider un collègue et j'ai oublié cela. C'était un peu embarrassant.
ExOfDe
1

J'ai annulé quelques commits en exécutant 'git revert commit id' tel que:

git revert b2cb7c248d416409f8eb42b561cbff91b0601712

Ensuite, j'ai été invité à valider le retour (comme vous le feriez lors de l'exécution de 'git commit'). Mon programme de terminal par défaut est Vim donc j'ai couru:

:wq 

Enfin, j'ai poussé le changement vers le référentiel avec:

git push
jrc16
la source