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
.