Je cherche à diviser un commit et je ne suis pas sûr de l'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 comprenais pas vraiment ce que l’index git ou la zone de transit était, et donc les explications n’ont pas aidé.
De plus, les cas d'utilisation de --mixed
et de --soft
sont identiques dans cette réponse (lorsque vous souhaitez corriger et réengager). Est-ce que quelqu'un peut le décomposer encore plus? Je réalise que --mixed
est probablement l'option à utiliser, mais je veux savoir pourquoi. Enfin, qu'en est-il de --hard
?
Quelqu'un peut-il me donner un exemple de flux de travail montrant comment sélectionner les 3 options?
Lorsque vous modifiez un fichier dans votre référentiel, la modification est initialement non mise en scène. Pour le commettre, vous devez le préparer (c'est-à-dire l'ajouter à l'index) à l'aide de git add
. Lorsque vous effectuez une validation, les modifications validées sont celles qui ont été ajoutées à l'index.
git reset
change, au minimum, l'endroit où la branche actuelle (HEAD
) pointe. La différence entre --mixed
et --soft
est de savoir si votre index est également modifié ou non. Donc, si nous sommes sur la branche master
avec cette série de commits:
- A - B - C (master)
HEAD
points à C
et l'index correspond à C
.
Lorsque nous exécutons git reset --soft B
, master
(et donc HEAD
), pointe maintenant sur B
, mais l'index a toujours les modifications de C
; git status
les montrera comme mis en scène. Donc, si nous exécutons git commit
à ce stade, nous aurons un nouveau commit avec les mêmes modifications que C
.
Bon, alors à partir d'ici encore:
- A - B - C (master)
Maintenant, faisons git reset --mixed B
. (Remarque: --mixed
est l'option par défaut). Encore une fois, master
et HEAD
pointent vers B, mais cette fois, l'index est également modifié pour correspondre à B
. Si nous exécutons git commit
à ce stade, rien ne se passera puisque l'index correspond à HEAD
. Nous avons toujours les modifications dans le répertoire de travail, mais comme elles ne figurent pas dans l'index, git status
les affiche comme non mises en scène. Pour les commettre, vous devez git add
et ensuite commettre comme d'habitude.
Et finalement, --hard
est identique à --mixed
(cela change votre HEAD
et votre index), sauf que --hard
modifie également votre répertoire de travail. Si nous en sommes à C
et exécutons git reset --hard B
, les modifications ajoutées à C
, ainsi que toutes les modifications non validées que vous avez, seront supprimées et les fichiers de votre copie de travail correspondront à commit B
. Comme vous pouvez perdre définitivement les modifications de cette façon, vous devez toujours exécuter git status
avant de procéder à une réinitialisation matérielle pour vous assurer que votre répertoire de travail est propre ou que vous acceptez de perdre vos modifications non validées.
Et enfin, une visualisation:
Veuillez noter qu'il s'agit d'une explication simplifiée, conçue comme une première étape pour tenter de comprendre cette fonctionnalité complexe.
Peut être utile pour les apprenants visuels qui souhaitent visualiser l'état de leur projet après chacune de ces commandes:
Pour ceux qui utilisent Terminal avec la couleur activée (Git config --global color.ui auto):
git reset --soft A
et vous verrez le contenu de B et C en vert (mis en scène et prêt à être utilisé)
git reset --mixed A
(ou git reset A
) et vous verrez les éléments de B et C en rouge (non mis en scène et prêts à être mis en scène (verts) puis validés)
git reset --hard A
et vous ne verrez plus les modifications de B et C nulle part (comme si elles n'avaient jamais existé)
Ou pour ceux qui utilisent un programme graphique comme "Tower" ou "SourceTree"
git reset --soft A
et vous verrez le contenu de B et C dans la zone "fichiers par étapes" prêt à être utilisé
git reset --mixed A
(ou git reset A
) et vous verrez les éléments de B et C dans la zone "fichiers non staged" prêts à être déplacés vers staged puis validés
git reset --hard A
et vous ne verrez plus les modifications de B et C nulle part (comme si elles n'avaient jamais existé)
Dans les termes les plus simples:
--soft
: uncommit changes, les modifications sont laissées en étapes (index).--mixed
(par défaut): uncommit + unstage change, les modifications sont laissées dans arbre de travail.--hard
: uncommit + unstage + delete changes, il ne reste plus rien.Voici une explication de base pour les utilisateurs de TortoiseGit:
git reset --soft
et --mixed
laissez vos fichiers intacts.
git reset --hard
réellement changez vos fichiers pour correspondre au commit que vous avez réinitialisé.
Dans TortoiseGit, le concept de the index est très caché par l'interface graphique. Lorsque vous modifiez un fichier, vous n'avez pas besoin d'exécuter git add
pour ajouter la modification à la zone/au stockage intermédiaire. Lorsqu’il s’agit simplement de modifications de fichiers existants qui ne changent pas de noms de fichiers, git reset --soft
et --mixed
sont identiques! 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 rajouter vos fichiers à partir de la liste Non Versioned Files.
Toutes les autres réponses sont bonnes, mais je trouve mieux de les comprendre en divisant les fichiers en trois catégories: unstaged
, staged
, commit
:
--hard
devrait être facile à comprendre, il restaure tout--mixed
(par défaut) : unstaged
fichiers: ne change passtaged
fichiers: déplacer vers unstaged
commit
fichiers: déplacer vers unstaged
--soft
: unstaged
fichiers: ne change passtaged
fichiers: ne pas changercommit
fichiers: déplacer vers staged
En résumé:
--soft
déplace tout (sauf les fichiers unstaged
) dans staging area
--mixed
déplacera tout dans unstaged area
La différence de base entre les différentes options de la commande git reset est décrite ci-dessous.
Il y a un certain nombre de réponses ici avec une idée fausse sur git reset --soft
. Bien qu'il existe une condition spécifique dans laquelle git reset --soft
ne modifie que HEAD
(à partir d'un état d'en-tête détaché), généralement (et pour l'utilisation prévue), il déplace la référence de branche que vous avez actuellement extraite. Bien sûr, cela ne peut pas être fait si aucune branche n’a été extraite (d’où la condition spécifique dans laquelle git reset --soft
ne modifiera que HEAD
).
J'ai trouvé que c'était la meilleure façon de penser à git reset
. Vous ne déplacez pas simplement HEAD
( tout ce qui fait cela ), vous déplacez également le réf. Branche, par exemple, master
. Ceci est similaire à ce qui se produit lorsque vous exécutez git commit
(la branche en cours se déplace avec HEAD
), sauf qu'au lieu de créer (et de déplacer) un nouveau commit, vous passez à un précédent commettre.
C'est le point de reset
, changer un branche en quelque chose d'autre qu'un nouveau commit, ne pas changer HEAD
. Vous pouvez le voir dans l'exemple de documentation:
Annuler un commit, en faire une branche de sujet
$ git branch topic/wip (1) $ git reset --hard HEAD~3 (2) $ git checkout topic/wip (3)
- Vous avez fait des commits, mais vous réalisez qu'ils étaient prématurés pour être dans la branche "maître". Vous souhaitez continuer à les polir dans une branche de sujet, créez donc une branche "sujet/balayage" à partir du HEAD actuel.
- Rembobinez la branche principale pour vous débarrasser de ces trois commits.
- Passez à la branche "topic/wip" et continuez à travailler.
Quel est le point de cette série de commandes? Vous voulez déplacer une branche _, ici master
, de sorte que tant que vous avez master
emprunté, vous exécutez git reset
.
La réponse la plus votée ici est généralement bonne, mais j’ai pensé que j’ajouterais ceci pour corriger les réponses erronées.
git reset --soft <ref>
: réinitialise le pointeur de branche pour la branche actuellement extraite sur la validation à la référence spécifiée,. Les fichiers de votre répertoire de travail et de votre index ne sont pas modifiés. Commettre à partir de cette étape vous ramènera à l’endroit où vous étiez avant la commande git reset
.
git reset --mixed <ref>
ou équivalent
git reset <ref>
:
Est-ce que --soft
fait ET réinitialise également l'index pour qu'il corresponde à la validation à la référence spécifiée. Alors que git reset --soft HEAD
ne fait rien (parce qu'il dit déplacer la branche extraite vers la branche extraite), git reset --mixed HEAD
, ou de manière équivalente git reset HEAD
, est une commande courante et utile car elle réinitialise l'index à l'état de votre dernière validation.
git reset --hard <ref>
: ce que --mixed
fait ET écrase également votre répertoire de travail. Cette commande est similaire à git checkout <ref>
, sauf que (et c’est le point crucial de reset
) toutes les formes de git reset
déplacer la référence de branche que HEAD
pointe sur.}
Il n'est pas utile de dire qu'une commande déplace la HEAD
. Toute commande qui change votre position dans votre historique de validation déplace la variable HEAD
. C'est ce que la HEAD
est, un pointeur où que vous soyez. HEAD
is you , et bougera donc chaque fois que vous le ferez.
--soft
: Indique à Git de réinitialiser HEAD sur un autre commit, aussi l'index et le répertoire de travail ne seront modifiés d'aucune façon. Tous les fichiers modifiés entre le HEAD d'origine et le commit seront mis en scène.
--mixed
: Tout comme le logiciel, cela réinitialisera HEAD sur un autre commit. Il réinitialisera également l'index pour qu'il corresponde sans que le répertoire de travail ne soit touché. Toutes les modifications resteront dans le répertoire de travail et apparaîtront comme modifiées, mais pas par étapes.
--hard
: tout est réinitialisé - il réinitialise HEAD sur un autre commit, réinitialise l'index et le répertoire de travail.
La principale différence entre --mixed
et --soft
est que votre index est également modifié ou non. Vérifiez plus à ce sujet ici .
Une réponse courte dans quel contexte les 3 options sont utilisées:
Pour conserver les modifications actuelles dans le code mais réécrire l'historique de validation:
soft
: Vous pouvez tout valider en même temps et créer un nouveau commit avec une nouvelle description (si vous utilisez torotise git ou la plupart des autres interfaces graphiques, c’est celui à utiliser, car vous pouvez toujours cocher les fichiers que vous voulez dans le commit et les créer. plusieurs commits de cette façon avec différents fichiers. Dans Sourcetree, tous les fichiers seraient stockés pour la validation.)mixed
: Vous devrez ajouter à nouveau les fichiers individuels à l'index avant de procéder à des validations (dans Sourcetree, tous les fichiers modifiés ne seraient pas mis en scène)Pour réellement perdre vos modifications dans le code également:
hard
: vous ne réécrivez pas simplement l'historique, mais vous perdez également toutes vos modifications jusqu'au moment de la réinitialisation.Vous n'avez pas à vous forcer à vous rappeler les différences entre elles. Pensez à la façon dont vous avez réellement commis un commit.
1.Faire des changements.
2.git ajouter.
3.gc -m "j'ai fait quelque chose"
Doux, Mixte et Difficile est le moyen permettant d'abandonner les opérations que vous avez effectuées de 3 à 1.
Soft "fait semblant" de ne jamais vous voir avoir fait "gc -m".
Mixed "feint" de ne jamais voir que tu as fait "git add."
Dur "fait semblant" de ne jamais voir que vous avez modifié les fichiers.
Avant d’entrer dans ces trois options, il faut comprendre trois choses.
1) Histoire/HEAD
2) Stade/index
3) Répertoire de travail
reset --soft: l'historique a été modifié, HEAD a été modifié, le répertoire de travail n'est pas modifié.
reset --mixed: l'historique a été modifié, HEAD a été modifié, le répertoire de travail a été modifié avec des données non synchronisées.
reset --hard: l'historique a été modifié, HEAD a été modifié, le répertoire de travail est modifié avec des données perdues.
Il est toujours prudent d’utiliser Git --soft. On devrait utiliser une autre option dans l'exigence complexe.
la réponse de mkarasek est excellente, en termes simples, nous pouvons le dire ...
git reset --soft
: définissez la HEAD
sur le commit prévu mais conservez vos modifications à partir des derniers commitsgit reset --mixed
: identique à git reset --soft
mais la seule différence est qu'il ne modifie pas vos modifications depuis les derniers commitsgit reset --hard
: définissez votre HEAD
sur la validation que vous spécifiez et réinitialisez toutes vos modifications depuis la dernière validation, y compris les modifications non validées.