775 votes

Pouvez-vous nous expliquer ce que « git reset » fait en anglais plain ?

J'ai vu des postes intéressants en expliquant les subtilités à propos de git reset.

Malheureusement, de plus j'ai lu à ce sujet, plus il semble que je n'ai pas le comprendre pleinement. Je viens d'un SVN fond et Git est un tout nouveau paradigme. J'ai eu mercurial facilement, mais Git est beaucoup plus technique.

Je pense que git reset est proche de hg revert, mais il semble qu'il y a des différences.

Qu'est-ce exactement ne git reset ? Veuillez inclure des explications détaillées sur:

  • les options --hard, --soft et --merge;
  • l'étrange notation que vous utilisez, HEAD comme HEAD^ et HEAD~1;
  • des cas d'utilisation concrets et de flux de travail;
  • les conséquences sur la copie de travail, l' HEAD et votre niveau de stress.

Holly bénédiction et des tonnes de chocolat/bière/name_your_stuff pour le gars qui fait un no-brainer réponse :-)

1117voto

Jefromi Points 127932

Je pense que les docs sont vraiment très bon pour ce - peut-être vous avez besoin d'un peu de sens de la manière dont git fonctionne pour eux de vraiment évier en bien. En particulier, si vous prenez le temps de les lire attentivement, ces tableaux détaillant les états de fichiers d'index et de travail de l'arbre pour toutes les différentes options et les cas sont très très utiles. (Mais oui, ils sont très denses - me prend tout juste de les lire et de confirmer qu'ils disent ce que je sais déjà.)

En général, git reset fonction est de prendre le courant de la branche et de le remettre à quelque part d'autre, et éventuellement apporter l'index et le travail de l'arbre. Plus concrètement, si votre branche master (en cours d'extraction) est comme ceci:

- A - B - C (HEAD, master)

et vous vous rendez compte que vous souhaitez maître de point de B, non C, vous devrez utiliser git reset B déplacer:

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

Digression: C'est différent d'une caisse. Si vous souhaitez exécuter git checkout B, vous obtiendrez ceci:

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

Vous avez fini dans une maison individuelle à la TÊTE de l'état. HEAD, les travaux de l'arbre, tous les index correspondent B, mais la branche master a été laissé à l' C. Si vous faites un nouveau commit D à ce stade, vous obtiendrez ce qui n'est probablement pas ce que vous voulez:

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

Rappelez-vous, le reset ne fait pas commet, il met juste à jour une branche (qui est un pointeur vers un commit) pour pointer vers un autre commit. Le reste n'est que détails de ce qui se passe à votre index et le travail de l'arbre.

Les cas d'utilisation

Je couvre de nombreux cas d'utilisation pour l' git reset dans mes descriptions des différentes options dans la section suivante. Il peut vraiment être utilisé pour une grande variété de choses; le dénominateur commun est que tous impliquent la réinitialisation de la branche, de l'index et/ou le travail de l'arbre pour pointer vers/correspondre à une donnée de s'engager.

Choses à faire attention

  • --hard peut vous amener à vraiment perdre du travail. Il modifie votre travail de l'arbre.

  • git reset [options] commit peuvent causer une (sorte de) perdre s'engage. Dans le jouet exemple ci-dessus, nous avons perdu commettre C. Elle est encore dans le repo, et vous pouvez le trouver en regardant git reflog show HEAD ou git reflog show master, mais ce n'est pas vraiment accessible à partir de n'importe quelle branche plus.

  • Git permet de supprimer définitivement ces s'engage au bout de 30 jours, mais en attendant, vous pouvez récupérer C en pointant une direction à nouveau (git checkout C; git branch <new branch name>).

Arguments

En paraphrasant la page de man, les plus courantes d'utilisation est de la forme git reset [<commit>] [paths...], ce qui permettra de rétablir l', compte tenu des chemins de leur état de le commettre. Si les chemins d'accès ne sont pas fournies, la totalité de l'arbre est remis à zéro, et si la livraison n'est pas fournie, il est pris pour être à la TÊTE (le commit courant). C'est un modèle courant à travers les commandes git (par exemple, la caisse, diff, journal, bien que la sémantique exacte varier), donc il ne devrait pas être trop surprenant.

Par exemple, git reset other-branch path/to/foo réinitialise tout chemin/vers/foo à son état dans d'autres secteurs, git reset -- . réinitialise le répertoire courant de son état dans la TÊTE, et un simple git reset réinitialise tout à son état dans la TÊTE.

Le travail principal de l'arbre et des options sur l'indice

Il existe quatre options pour contrôler ce qui se passe à votre travail à l'arbre et de l'index lors de la réinitialisation.

Rappelez-vous, l'indice est git "zone de transit" - c'est là que les choses vont quand vous dites git add dans la préparation de la validation.

  • --hard rend tout match de la validation que vous avez réinitialisé. C'est le plus facile à comprendre, sans doute. Toutes vos modifications locales d'obtenir assommé. Une utilisation principale souffle loin de votre travail, mais pas de commutation s'engage à: git reset --hard moyen git reset --hard HEAD, c'est à dire ne pas changer la direction générale, mais de se débarrasser de toutes les modifications locales. L'autre est tout simplement le déplacement d'une branche d'un endroit à un autre, et de garder l'index du travail/de l'arbre de synchronisation. C'est le seul qui peut vraiment vous faire perdre du travail, car il modifie votre travail à l'arbre. Très très sûr que vous voulez jeter locaux de travail avant d'exécuter n'importe quel reset --hard.

  • --mixed est la valeur par défaut, c'est à dire git reset moyen git reset --mixed. Il remet à l'index, mais pas le travail de l'arbre. Cela signifie que tous vos fichiers sont intacts, mais les différences entre l'original s'engager et d'une réinitialisation à la volonté de montrer que les modifications locales (ou sans traces de fichiers) avec git status. Utilisez cette fonction lorsque vous réalisez que vous avez fait quelques mauvaises s'engage, mais vous voulez garder tout le travail que vous avez fait de sorte que vous pouvez le corriger et de le réaffirmer. Dans le but de commettre, vous aurez pour ajouter des fichiers à l'index à nouveau (git add ...).

  • --soft ne touche pas à l'index ou le travail de l'arbre. Tous vos fichiers sont intacts avec --mixed, mais toutes les modifications apparaissent en tant que changes to be committed avec git status (c'est à dire enregistrés en préparation pour commettre). Utilisez cette fonction lorsque vous vous rendez compte que vous avez fait quelques mauvaises s'engage, mais le travail est tout bon - tout ce que vous devez faire est de s'engager de nouveau les choses différemment. L'indice est intacte, de sorte que vous pouvez vous engager immédiatement si vous voulez - la validation ont tous le même contenu que l'endroit où vous étiez avant de les réinitialiser.

  • --merge a été ajouté récemment, et est destiné à vous aider à abandonner l'échec d'une fusion. Ceci est nécessaire car l' git merge va effectivement vous permettre de tenter une fusion avec un sale boulot de l'arbre (avec des modifications locales), tant que ces modifications sont dans les fichiers affectés par la fusion. git reset --merge réinitialise l'index (comme --mixed - tous les changements se traduisent par des modifications locales), et restaure les fichiers concernés par la fusion, mais laisse les autres seuls. Ce sera, nous l'espérons de tout restaurer à comment c'était avant le mauvais fusion. Vous aurez l'habitude de l'utiliser en tant que git reset --merge (signifiant git reset --merge HEAD) parce que vous ne voulez réinitialiser à l'écart de la fusion, pas vraiment déplacer la branche. (HEAD n'a pas encore été mis à jour, depuis la fusion a échoué)

    Pour être plus concret, supposons que vous avez modifié les fichiers A et B, et vous essayez de fusionner dans une branche qui a modifié les fichiers C et D. La fusion échoue pour une raison quelconque, et que vous décidez de l'annuler. Vous utilisez git reset --merge. Il apporte C et D, revenir à la façon dont ils ont été en HEAD, mais laisse vos modifications A et B seul, car ils ne faisaient pas partie de la tentative de fusion.

Étrange notation

La "drôle de notation" (HEAD^ et HEAD~1) que vous mentionnez est simplement un raccourci pour spécifier s'engage, sans avoir à utiliser un nom de hachage comme 3ebe3f6. Il est entièrement documenté dans la "spécification de révisions" de la section de la page de man pour git-rev-parse, avec beaucoup d'exemples et liées à la syntaxe. L'accent circonflexe et tilde en fait signifier différentes choses:

  • HEAD~ "est l'abréviation de HEAD~1 et les moyens de la validation du premier parent. HEAD~2 signifie que la livraison du premier parent du premier parent. Pensez HEAD~n "n engage avant de la TÊTE" ou "le n-ième génération ancêtre de la TÊTE".
  • HEAD^ (ou HEAD^1) signifie également que la livraison du premier parent. HEAD^2 signifie que la validation du deuxième parent. Rappelez-vous, une normale de fusion s'engager a deux parents, le premier parent est issu de la fusion en commettre, et le second parent est le commit qui a été fusionnée. En général, la fusion peut avoir arbitrairement de nombreux parents (poulpe, fusionne).
  • L' ^ et ~ opérateurs peuvent être enchaînés, comme en HEAD~3^2, le deuxième parent de la troisième génération, ancêtre de l' HEAD, HEAD^^2, le deuxième parent du premier parent d' HEAD, ou même HEAD^^^, ce qui est équivalent à HEAD~3.

caret and tilde

91voto

John Feminella Points 116878

Rappelez-vous que, en git vous avez:

  • l' HEAD pointeur, qui vous dit ce commit, vous travaillez sur
  • l' arbre de travail, qui représente l'état des fichiers sur votre système
  • la zone de transit (également appelé l' index), qui "stades" modifications afin qu'ils puissent plus tard être engagés ensemble

Veuillez inclure des explications détaillées sur:

--hard, --soft et --merge;

Dans l'ordre croissant de dangereux-ness:

  • --soft coups HEAD mais ne touche pas la zone de transit ou de l'arbre de travail.
  • --mixed coups HEAD et les mises à jour de la zone de transit, mais pas de l'arbre de travail.
  • --merge coups HEAD, réinitialise la zone de transit, et tente de passer tous les changements dans votre arbre de travail dans le nouvel arbre de travail.
  • --hard coups HEAD et ajuste votre zone de transit et de travail de l'arbre de la nouvelle - HEAD, de jeter tout.

des cas d'utilisation concrets et des flux de travail;

  • Utiliser --soft lorsque vous souhaitez déplacer vers un autre commit et patch les choses sans "perdre votre place". C'est assez rare que vous ayez besoin de cela.

--

# git reset --soft example
touch foo                            // Add a file, make some changes.
git add foo                          // 
git commit -m "bad commit message"   // Commit... D'oh, that was a mistake!
git reset --soft HEAD^               // Go back one commit and fix things.
git commit -m "good commit"          // There, now it's right.

--

  • Utiliser --mixed (qui est la valeur par défaut) si vous voulez voir ce que les choses ressemblent à une autre livraison, mais vous ne voulez pas perdre toutes les modifications que vous avez déjà.

  • Utiliser --merge lorsque vous souhaitez déplacer vers un nouveau spot tout en intégrant les modifications que vous avez déjà que l'arbre de travail.

  • Utiliser --hard à effacer tout et de lancer une nouvelle tablette chez le nouveau commit.

41voto

Daniel Hershcovich Points 1370

Le poste de Réinitialisation Démystifié dans le blog Pro Git donne un no-brainer explication sur git reset et git checkout.

Après tout, la discussion utile en haut de ce post, l'auteur réduit les règles suivantes simple en trois étapes:

C'est essentiellement cela. L' reset commande écrase ces trois arbres dans un ordre spécifique, s'arrêtant quand vous dites qu'il.

  1. Aller quelle que soit CHEF de la direction générale des points à (stop si --soft)
  2. ENSUITE, faire l'Index de ressembler à ça (ici de s'arrêter à moins d' --hard)
  3. ENSUITE, faites le Répertoire de Travail ressembler à ça

Il y a aussi --merge et --keep options, mais je préfère garder les choses simples pour l'instant - que ce sera pour un autre article.

32voto

love Points 241

Lorsque vous vous engager à quelque chose de git, vous devez d'abord l'étape (ajouter à l'index) vos modifications. Cela signifie que vous avez à git ajouter tous les fichiers que vous souhaitez inclure dans ce commit avant git les considère comme faisant partie de la livraison. Nous allons d'abord jeter un oeil sur l'image d'un repo git: enter image description here

donc c'est simple maintenant. Nous devons travailler dans le répertoire de travail, la création de fichiers, de répertoires et de tous. Ces changements sont sans traces de changements. De faire leur suivi, nous avons besoin de les ajouter à git index à l'aide de git add commande. Une fois qu'ils sont ajoutés à git de l'index. Nous pouvons maintenant valider ces modifications, si nous voulons pousser à dépôt git.

Mais tout à coup, nous est venu de savoir tout de validation que nous avons un fichier supplémentaire, auquel nous avons ajouté dans l'index n'est pas nécessaire de pousser dans le dépôt git. Cela signifie que nous ne voulons pas de ce fichier dans l'index. Maintenant, la question est comment faire pour supprimer ce fichier à partir de git indice, Puisque nous avons utilisé la commande git add pour les mettre dans l'index, il serait logique d'utiliser git rm? Faux! git rm va tout simplement supprimer le fichier et l'ajouter à la suppression de l'index. Alors, que faire maintenant:

Utilisation:-

git reset

Il Efface votre index, les feuilles de votre répertoire de travail intacte. (il suffit de unstaging tout).

Il peut être utilisé avec un certain nombre d'options. Il existe trois principales options à utiliser avec git reset: --dur, --soft et --mélangé. Ces affecter ce qui est de réinitialisation en plus de la TÊTE du pointeur lorsque vous réinitialisez.

Tout d'abord, --hard réinitialise tout. Votre répertoire courant serait exactement comme il l'aurait fait si vous aviez été à la suite de cette branche. Le répertoire de travail et de l'index sont changé pour s'engager. C'est la version que j'utilise le plus souvent. git reset --hard est quelque chose comme svn revert .

Ensuite, tout le contraire, doux, ne pas réinitialiser l'arbre de travail, ni à l'index. Il ne se déplace le pointeur de têtes. Cela laisse votre état actuel avec les modifications différentes de la validation vous passez à en placer dans votre répertoire, et de "mise en scène" pour avoir commis. Si vous faites un commit en local mais je n'ai pas poussé la validation pour le serveur git, vous pouvez le réinitialiser à la précédente s'engager, et engager de nouveau avec un bon message de commit.

Enfin, --mélangé réinitialise l'index, mais pas de l'arbre de travail. Ainsi, les modifications sont toujours là, mais sont "unstaged" et aurait besoin d'être git add ed ou git commit-a. nous utilisons ce parfois si nous avons engagé plus de nous destiné à avec git commit -a, on peut revenir le commit avec git reset --mélangé, ajoutez les choses que nous avons envie de s'engager et d'engager ceux-ci.

Différence entre git revert et git reset :-


En termes simples, git reset est une commande pour "aidez-uncommited erreurs" et git revert est une commande pour "aidez-commis l'erreur".

Cela signifie que si nous avons fait une erreur dans un peu de changement et engagés et ont poussé le même pour repo git, puis git revert est la solution. Et si dans le cas que nous avons identifié la même erreur avant de pousser/validation, nous pouvons utiliser git reset pour résoudre le problème.

J'espère que ça va vous aider à vous débarrasser de votre confusion.

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