Quelle est la différence entre le git reset --mixed, --soft, et --hard?
je cherche à diviser une propagation et je ne sais pas quelle option de réinitialisation utiliser.
je regardais la page pouvez-vous expliquer ce que" git reset " fait en anglais? , mais j'ai réalisé que je ne comprends pas vraiment ce qu'est l'index git ou la zone de transit et donc les explications n'ont pas aidé.
aussi les cas d'utilisation pour --mixed
et --soft
sont les mêmes pour moi dans cette réponse (quand vous voulez fixer et se réengager.) Quelqu'un peut-il briser encore plus? Je me rends compte que --mixed
est probablement la solution, mais je veux savoir pourquoi . Enfin, qu'en est-il de --hard
?
est-ce que quelqu'un peut me donner un exemple de flux de travail de la façon dont la sélection des 3 options se produirait?
10 réponses
lorsque vous modifiez un fichier dans votre dépôt, le changement est initialement non classé. Afin de le commettre, vous devez stade, l'ajouter à l'index à l'aide de git add
. Lorsque vous faites un commit, les changements qui se sont engagés sont ceux qui ont été ajoutés à l'index.
git reset
change, au minimum, là où la branche courante ( HEAD
) pointe. La différence entre --mixed
et --soft
est de savoir si votre indice est également modifier. Donc, si nous sommes sur la branche master
avec cette série de commits:
- A - B - C (master)
HEAD
points à C
et l'indice correspond à C
.
quand on exécute git reset --soft B
, master
(et donc HEAD
) pointe maintenant à B
, mais l'indice a encore les changements de C
; git status
les montrera comme mis en scène. Donc si nous courons git commit
à ce point, nous obtiendrons un nouveau commit avec le même modifications sous C
.
Ok, donc à partir d'ici à nouveau:
- A - B - C (master)
maintenant faisons git reset --mixed B
. (Note: --mixed
est l'option par défaut). Encore une fois, master
et HEAD
pointent vers B, mais cette fois l'index est aussi modifié pour correspondre à B
. Si nous exécutons git commit
à ce point, rien ne se passera puisque l'index correspond à HEAD
. Nous avons encore les changements dans le travail répertoire, mais puisqu'ils ne sont pas dans l'index, git status
les montre comme non marqués. Pour les commettre, vous devez git add
et ensuite vous engager comme d'habitude.
et enfin, --hard
est le même que --mixed
(il change votre HEAD
et index), sauf que --hard
modifie également votre répertoire de travail. Si nous sommes à C
et exécutons git reset --hard B
, alors les modifications ajoutées dans C
, ainsi que tout non engagé les changements que vous avez, seront supprimés, et les fichiers de votre copie de travail correspondront à commit B
. Puisque vous pouvez perdre des modifications de façon permanente de cette façon, vous devriez toujours exécuter git status
avant de faire une réinitialisation dure pour s'assurer que votre répertoire de travail est propre ou que vous êtes d'accord avec la perte de vos modifications non engagées.
et enfin, une visualisation:
s'il vous Plaît être conscient, c'est une explication simplifiée conçue comme une première étape dans la recherche afin de comprendre cette fonctionnalité complexe.
peut être utile pour les apprenants visuels qui veulent visualiser à quoi ressemble l'état de leur projet après chacune de ces commandes:
pour ceux qui utilisent Terminal avec couleur allumée (git config --global de la couleur.l'interface utilisateur auto):
git reset --soft A
et vous verrez B et C de trucs en vert (mise en scène et prêt à s'engager)
git reset --mixed A
(ou git reset A
) et vous verrez B et C des trucs en rouge (unstaged et prêt à être mis en scène (en vert), puis validés)
git reset --hard A
et vous ne verrez plus les B et C des changements n'importe où (seront comme si elles n'ont jamais existé)
ou pour ceux qui utilisent un programme GUI comme 'Tower' ou 'SourceTree'
git reset --soft A
et vous verrez que B et C sont les choses dans la " mise en scène de fichiers, région prête à s'engager
git reset --mixed A
(ou git reset A
) et vous verrez les affaires de B et C dans la zone des "dossiers non classés" prêts à être déplacés sur scène et ensuite commis
git reset --hard A
et vous ne verrez plus les B et C des changements n'importe où (seront comme si elles n'ont jamais existé)
dans les termes les plus simples:
-
--soft
: uncommit change, changes is left staged ( index ). -
--mixed
(par défaut) : uncommit + unstage , changements est à gauche dans la arbre de travail . -
--hard
: uncommit + unstage + suppr des changements, rien de gauche.
Voici une explication de base pour les utilisateurs de TortoiseGit:
git reset --soft
et --mixed
laissez vos fichiers intacts.
git reset --hard
en fait modifier vos fichiers pour correspondre à la propagation que vous réinitialisez.
Dans TortoiseGit, Le concept de l'index est très caché par le GUI. Lorsque vous modifiez un fichier, vous n'avez pas à exécuter git add
ajouter le changement à la zone de rassemblement / index. Lorsqu'il s'agit simplement de modifier des fichiers existants qui ne changent pas de noms de fichiers, git reset --soft
et --mixed
sont les mêmes! Vous ne remarquerez une différence que si vous avez ajouté de nouveaux fichiers ou des fichiers renommés. Dans ce cas, si vous exécutez git reset --mixed, vous devrez ajouter à nouveau votre(Vos) fichier (s) à partir de la liste Non Versioned Files .
dans ces cas, j'aime un visuel qui peut, je l'espère, expliquer ceci:
git reset --[hard/mixed/soft]
:
donc chaque effet a des portées différentes
- Dur => WorkingDir + Index + TÊTE
- mixte = > Index + HEAD
- Soft => TÊTE seule (index et de travailler dir inchangé).
une brève réponse dans quel contexte les 3 options sont utilisées:
À garder les changements en cours dans le code mais à la réécriture de la validation de l'histoire:
-
soft
: vous pouvez tout propager à la fois et créer une nouvelle propagation avec une nouvelle description (Si vous utilisez torotise git ou n'importe quelle autre interface graphique, c'est celle à utiliser, car vous pouvez toujours cocher les fichiers que vous voulez dans la propagation et faire des diffusions multiples de cette façon). avec des fichiers différents. Dans Sourcetree tous les fichiers seraient mis en scène pour commit.) -
mixed
: vous devrez ajouter les fichiers individuels de nouveau à l'index avant de faire des propagations (dans Sourcetree tous les fichiers modifiés seraient non-marqués)
à réellement perdre vos modifications dans le code ainsi:
-
hard
: vous ne vous contentez pas de réécrire l'histoire, mais vous perdez aussi tous vos changements au point de réinitialiser
avant d'entrer dans ces trois options, il faut comprendre 3 choses.
1) Histoire / tête
2) l'Étape/index
3) répertoire de travail
réinitialiser -- soft: L'histoire a changé, la tête a changé, le répertoire de travail n'a pas changé.
reset --mixte : l'Histoire a changé, changé de TÊTE, répertoire de Travail a changé avec unstaged de données.
reset -- hard: History changé, tête changée, le répertoire de travail est changé avec les données perdues.
Il est toujours plus sûr de aller avec Git --soft. On devrait utiliser une autre option dans les exigences complexes.
--soft
: indique à Git de réinitialiser la tête vers une autre propagation, donc l'index et le répertoire de travail ne seront pas modifiés. Tous les fichiers modifiés entre la tête d'origine et la propagation seront mis en scène.
--mixed
: tout comme le soft, cela va réinitialiser la tête vers un autre commit. Il va également réinitialiser l'index pour l'apparier alors que le répertoire de travail ne sera pas touché. Toutes les modifications resteront dans le répertoire de travail et apparaîtront comme modifiées, mais pas une mise en scène.
--hard
: cela réinitialise tout - il réinitialise HEAD back to another commit, réinitialise l'index pour l'apparier, et réinitialise le répertoire de travail pour l'apparier aussi.
la principale différence entre --mixed
et --soft
est de savoir si votre indice est également modifié ou non. En savoir plus sur ce ici .
différence de base entre les différentes options de la commande de réinitialisation git sont comme ci-dessous.
- --soft: ne réinitialise la tête qu'à la propagation que vous sélectionnez. Fonctionne essentiellement de la même façon que git checkout mais ne crée pas un État de tête détaché.
- --mixed (option par défaut): réinitialise la tête à la propagation que vous sélectionnez dans l'historique et annule les changements dans l'index.
- --hard: Réinitialise la TÊTE à la validation que vous sélectionnez dans à la fois l'histoire, annule les changements dans l'indice, et annule les changements dans votre répertoire de travail.
la réponse de mkarasek est grande, en termes simples nous pouvons dire...
-
git reset --soft
: définissez leHEAD
à la propagation prévue, mais gardez vos changements échelonnés de la dernière propagation -
git reset --mixed
: c'est même commegit reset --soft
mais la seule différence est-il de l'onu en scène vos changements de dernière s'engage -
git reset --hard
: définissez votreHEAD
sur le commit que vous spécifiez et réinitialisez toutes vos modifications de la dernière propagation y compris les changements engagés par l'ONU.