499 votes

Quelle est la différence entre "git reset" et "git checkout" ?

J'ai toujours pensé que git reset y git checkout sont identiques, dans le sens où ils ramènent tous deux le projet à un commit spécifique. Cependant, je pense qu'ils ne peuvent pas être exactement les mêmes, car cela serait redondant. Quelle est la différence réelle entre les deux ? Je suis un peu confus, car le svn a seulement svn co pour annuler la livraison.

AJOUTÉ

VonC et Charles ont expliqué les différences entre git reset y git checkout vraiment bien. D'après ce que j'ai compris, il s'agit de git reset rétablit toutes les modifications par rapport à un commit spécifique, tandis que git checkout se prépare plus ou moins à la création d'une branche. Les deux diagrammes suivants m'ont été très utiles pour parvenir à cette compréhension :

http://a.imageshack.us/img651/1559/86421927.pnghttp://a.imageshack.us/img801/1986/resetr.png

AJOUTÉ 3

En http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html L'extraction et la réinitialisation peuvent émuler le rebasement.

enter image description here

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

enter image description here

0 votes

Jeter un coup d'œil sur git-scm.com/blog/2011/07/11/reset.html

1 votes

Re : "Est-ce une erreur ou une simplification excessive ?" Oui, le premier diagramme est trompeur en ce qui concerne la différence entre l'extraction et la réinitialisation. (Il peut être correct en ce qui concerne la -- files variantes ; je n'en suis pas sûr). Ce diagramme donne l'impression que la principale différence réside dans le fait qu'ils affectent l'indice ou le DT. Voir ma réponse à ce sujet. Les deuxième et troisième diagrammes sont très utiles pour voir la différence réelle. Les 4ème et 5ème diagrammes sont utiles pour vérifier si vous comprenez ce que font ces commandes, mais ne vous aideront pas vraiment à y parvenir.

0 votes

J'ai trouvé la section "Vérifier" du "Git Tools Reset Demystified" pour donner le résumé le plus utile.

225voto

VonC Points 414372
  • git reset concerne spécifiquement mise à jour de l'index , en déplaçant la TÊTE.
  • git checkout Il s'agit de mise à jour de l'arbre de travail (à l'index ou à l'arbre spécifié). Il ne mettra à jour le HEAD que si vous extrayez une branche (si ce n'est pas le cas, vous obtiendrez un fichier tête isolée ).
    (en fait, avec Git 2.23 Q3 2019, ce sera git restore pas nécessairement git checkout )

En comparaison, svn n'a pas d'index, mais seulement un arbre de travail, svn checkout copiera une révision donnée dans un répertoire séparé.
L'équivalent le plus proche pour git checkout serait :

  • svn update (si vous êtes dans la même branche, c'est-à-dire la même URL SVN)
  • svn switch (si vous consultez par exemple la même branche, mais à partir d'une autre URL de repo SVN)

Ces trois modifications de l'arbre de travail ( svn checkout , update , switch ) n'ont qu'une seule commande dans git : git checkout .
Mais comme git a aussi la notion d'index (cette "zone de transit" entre le repo et l'arbre de travail), vous avez aussi git reset .


Thinkeye mentions dans les commentaires l'article " La réinitialisation démystifiée ".

Par exemple, si nous avons deux branches, ' master et develop ' pointant vers différents commits, et nous sommes actuellement sur ' develop (HEAD l'indique donc) et nous lançons git reset master , ' develop ' lui-même pointera désormais vers le même commit que ' master ' fait.

D'autre part, si nous exécutons à la place git checkout master , ' develop ne bougera pas, HEAD lui-même le fera. HEAD pointera désormais vers ' master '.

Ainsi, dans les deux cas, nous nous déplaçons HEAD pour pointer vers l'engagement A mais la façon dont nous le faisons est très différente. reset déplacera la branche HEAD pointe vers, passe à la caisse HEAD pour pointer vers une autre branche.

http://git-scm.com/images/reset/reset-checkout.png

Sur ces points, cependant :

LarsH ajoute dans les commentaires :

Le premier paragraphe de cette réponse est toutefois trompeur : " git checkout ... ne mettra à jour le HEAD que si vous extrayez une branche (sinon, vous vous retrouverez avec un HEAD détaché)".
Ce n'est pas vrai : git checkout mettra à jour le HEAD même si vous extrayez un commit qui n'est pas une branche (et oui, vous vous retrouvez avec un HEAD détaché, mais il a quand même été mis à jour).

git checkout a839e8f updates HEAD to point to commit a839e8f.

De Novo approuve dans les commentaires :

@LarsH a raison.
Le deuxième point a une idée erronée de ce qu'est HEAD dans ne mettra à jour le HEAD que si vous extrayez une branche.
HEAD vous suit partout, comme une ombre.
La vérification d'une référence non liée à la branche (par exemple, une étiquette), ou d'un commit directement, déplacera HEAD. Une tête détachée ne signifie pas que vous vous êtes détaché de la tête, cela signifie que la tête est détachée d'une référence de branche, ce que vous pouvez voir dans, par exemple, git log --pretty=format:"%d" -1 .

  • Les États membres ci-joints commenceront par (HEAD -> ,
  • détaché sera toujours affiché (HEAD mais n'aura pas de flèche vers une branche réf.

12 votes

Je dirais que git reset consiste à modifier le "label" d'une branche et, éventuellement, à mettre à jour l'index ou l'arbre de travail. git checkout consiste à mettre à jour l'arbre de travail et à faire basculer la branche actuellement "sélectionnée" (la branche HEAD ).

2 votes

@MikkoRantalainen non. git reset concerne à 100 % la HEAD . Il fonctionne même en mode HEAD détaché ( stackoverflow.com/a/3965714/6309 ), ce qui signifie que lorsqu'il y a non git checkout fonctionne également en mode HEAD détaché, ou peut être utilisé pour extraire un SHA1 en mode HEAD détaché : là encore, aucune branche n'est impliquée.

1 votes

Oui, git reset mouvements HEAD si le fichier .git/HEAD contient un SHA-1. Toutefois, s'il contient un ref: il déplacera la branche pointée par cette référence à la place. Par exemple, git checkout master && git reset --soft HEAD^ déplace le master branche "label" vers le SHA-1 parent du commit actuel pointé par la branche master n'est-ce pas ? Et le contenu du fichier .git/HEAD est ref: refs/heads/master même si git reset est fait ou non.

73voto

Charles Bailey Points 244082

Dans leur forme la plus simple, reset réinitialise l'index sans toucher à l'arbre de travail, tandis que checkout modifie l'arbre de travail sans toucher à l'index.

Réinitialise l'index pour qu'il corresponde à HEAD L'arbre qui travaille est laissé à lui-même :

git reset

D'un point de vue conceptuel, cela permet d'extraire l'index de l'arbre de travail. Pour qu'il fasse réellement quelque chose, il faudrait utiliser -f pour l'obliger à écraser toute modification locale. Il s'agit d'une mesure de sécurité visant à s'assurer que la forme "sans argument" n'est pas destructrice :

git checkout

Lorsque l'on commence à ajouter des paramètres, il est vrai qu'il y a un certain chevauchement.

checkout est généralement utilisé avec une branche, un tag ou un commit. Dans ce cas, il réinitialisera HEAD et l'index du commit donné, ainsi que l'extraction de l'index dans l'arborescence de travail.

De même, si vous fournissez --hard a reset vous pouvez demander reset pour écraser l'arbre de travail et réinitialiser l'index.

Si vous disposez actuellement d'une branche vérifiée, il existe une différence cruciale entre reset y checkout lorsque vous fournissez une branche ou un commit alternatif. reset modifiera la branche actuelle pour qu'elle pointe vers le commit sélectionné, alors que checkout ne touchera pas à la branche courante mais vérifiera la branche ou le commit fourni à la place.

D'autres formes de reset y commit impliquent la fourniture de chemins.

Si vous fournissez des chemins d'accès à reset vous ne pouvez pas fournir --hard y reset ne changera que la version de l'index des chemins fournis à la version dans le commit fourni (ou HEAD si vous ne spécifiez pas de commit).

Si vous fournissez des chemins d'accès à checkout comme reset il mettra à jour la version de l'index des chemins fournis pour qu'elle corresponde au commit fourni (ou à l'option HEAD ) mais il extraira toujours la version indexée des chemins fournis dans l'arbre de travail.

2 votes

Il est faux de dire que "checkout" ne modifie pas l'index : il le modifie lorsqu'il est utilisé pour passer d'une branche à une autre.

1 votes

Dans leur forme la plus simple, la réinitialisation réinitialise l'index sans toucher à l'arbre de travail, tandis que la vérification modifie l'arbre de travail sans toucher à l'index. : C'est un peu déroutant :|

63voto

John Doe Points 65

Un cas d'utilisation simple lors de l'annulation d'un changement :
1. Utilisez la fonction de réinitialisation si vous souhaitez annuler la mise à disposition d'un fichier modifié.
2. Utilisez l'option "checkout" si vous souhaitez ignorer les modifications apportées aux fichiers non paginés.

18voto

LarsH Points 14726

En résumé, la différence essentielle est la suivante reset déplace la référence de la branche actuelle , tandis que checkout ne le fait pas (il déplace HEAD).

Comme l'explique le livre Pro Git sous La réinitialisation démystifiée ,

La première chose reset fera est déplacer ce que HEAD indique . Ce n'est pas la même chose que changer HEAD lui-même (ce qui est le cas de l checkout fait) ; reset déplace la branche vers lequel HEAD pointe. Cela signifie que si HEAD est défini à l'adresse master (c'est-à-dire que vous êtes actuellement sur la branche master b en cours d'exécution git reset 9e5e6a4 commencera par faire master p 9e5e6a4 . [souligné par l'auteur]

Voir aussi la réponse de VonC pour une texte et extrait de diagramme très utiles du même article, que je ne reproduirai pas ici.

Bien sûr, il y a beaucoup plus de détails sur les effets de ces mesures. checkout y reset peut avoir sur l'index et l'arbre de travail, en fonction des paramètres utilisés. Il peut y avoir de nombreuses similitudes et différences entre les deux commandes. Mais selon moi, la différence la plus importante est de savoir si elles déplacent l'extrémité de la branche courante.

6voto

De brefs moyens mnémotechniques :

git reset HEAD           :             index = HEAD
git checkout             : file_tree = index
git reset --hard HEAD    : file_tree = index = HEAD

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X