Y a-t-il une différence entre «git reset –hard hash» et «git checkout hash»?

Bien que la reset et la checkout aient des usages différents la plupart du temps, je ne vois pas quelle différence il y a entre ces deux.

Il y en a probablement un ou personne n’aurait pris la peine d’append une option --hard pour faire quelque chose que la checkout base peut faire.

Peut-être y a-t-il une différence dans la façon dont vous verrez l’histoire?

Cette réponse est la plupart du temps citée de ma réponse à une question précédente: git reset en anglais clair .

Les deux sont très différents. Ils génèrent le même état pour votre index et votre arbre de travail, mais l’historique et la twig en cours ne sont pas identiques.

Supposons que votre historique ressemble à ceci, avec la twig principale actuellement extraite:

 - A - B - C (HEAD, master) 

et vous lancez git reset --hard B Vous obtiendrez ceci:

 - A - B (HEAD, master) # - C is still here, but there's no # branch pointing to it anymore 

Vous obtiendrez effectivement cet effet si vous utilisez --mixed ou --soft aussi – la seule différence est ce qui arrive à votre arbre de travail et à votre index. Dans le cas --hard , l’arborescence et l’index correspondent.

Maintenant, supposons que vous exécutiez git checkout B place. Vous obtiendrez ceci:

 - A - B (HEAD) - C (master) 

Vous vous êtes retrouvé dans un état HEAD détaché. HEAD , arbre de travail, indexe toutes les correspondances B , comme avec la réinitialisation matérielle, mais la twig principale a été laissée à C Si vous faites un nouveau commit D à ce stade, vous obtiendrez ceci, ce qui n’est probablement pas ce que vous voulez:

 - A - B - C (master) \ D (HEAD) 

Donc, vous utilisez la commande pour vérifier cette validation. Vous pouvez jouer avec vous, faire ce que vous voulez, mais vous avez laissé votre twig derrière vous. Si vous souhaitez que la twig soit aussi déplacée, utilisez la réinitialisation.

Si la documentation fournie avec Git ne vous aide pas, jetez un coup d’œil à A Visual Git Reference de Mark Lodato.

En particulier si vous comparez git checkout avec git reset --hard (hotlinked):

git checkout master ~ 3 http://soffr.miximages.com/git/checkout-detached.svg.png

git reset –hard master ~ 3 http://soffr.miximages.com/git/reset-commit.svg.png

Notez que dans le cas de git reset --hard master~3 vous laissez une partie du DAG des révisions – certains des commits ne sont référencés par aucune twig. Ceux-ci sont protégés pour (par défaut) 30 jours par le reflog ; ils seraient finalement élagués (enlevés).

git-reset hash définit la référence de la twig sur le hachage donné et le --hard avec --hard .

git-checkout hash définit l’arborescence de travail sur le hash donné; et à moins que le hash soit un nom de twig, vous vous retrouverez avec une tête détachée.

finalement, git traite de 3 choses:

  working tree (your code) ------------------------------------------------------------------------- index/staging-area ------------------------------------------------------------------------- repository (bunch of commits, trees, branch names, etc) 

git-checkout par défaut ne fait que mettre à jour l’index et l’arborescence de travail, et peut éventuellement mettre à jour quelque chose dans le référentiel (avec l’option -b )

git-reset par défaut ne fait que mettre à jour le référentiel et l’index, et éventuellement l’arborescence de travail (avec l’option --hard )

Vous pouvez penser au repository comme ceci:

  HEAD -> master refs: master -> sha_of_commit_X dev -> sha_of_commit_Y objects: (addressed by sha1) sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A .... 

git-reset manipule ce que les références de twig désignent.

Supposons que votre histoire ressemble à ceci:

  T--S--R--Q [master][dev] / A--B--C--D--E--F--G [topic1] \ Z--Y--X--W [topic2][topic3] 

Gardez à l’esprit que les twigs ne sont que des noms qui progressent automatiquement lorsque vous vous engagez.

Donc, vous avez les twigs suivantes:

  master -> Q dev -> Q topic1 -> G topic2 -> W topic3 -> W 

Et votre twig actuelle est topic2 , c’est-à-dire que le HEAD pointe vers le sujet2.

 HEAD -> topic2 

Ensuite, git reset X réinitialisera le nom topic2 pour qu’il pointe vers X; ce qui signifie que si vous faites un commit P sur le sujet de la twig2, les choses vont ressembler à ceci:

  T--S--R--Q [master][dev] / A--B--C--D--E--F--G [topic1] \ Z--Y--X--W [topic3] \ P [topic2]