161 votes

Les utilisations pratiques de git reset --soft?

J'ai été travailler avec git pour un peu plus d'un mois. En effet, j'ai utilisé de réinitialisation pour la première fois hier, mais le soft reset ne fonctionne toujours pas beaucoup de sens pour moi.

Je comprends que je peux utiliser le soft reset pour modifier un commit sans modifier l'index ou le répertoire de travail, comme je le ferais avec git commit --amend.

Ce sont ces deux commandes vraiment le même (reset --soft vs commit --amend)? Aucune raison d'utiliser l'un ou l'autre dans la pratique? Et, plus important encore, sont-il d'autres utilisations pour reset --soft en dehors de la modification d'un commit?

122voto

VonC Points 414372

git reset est tout au sujet de se déplacer HEAD.
Question: quel est le travail de l'arbre et de l'index?
Lorsqu'ils travaillent avec des --soft, se déplace HEAD, et seulement l' HEAD.
Cette diffèrent commit --amend comme:

  • il n'est pas de créer un nouveau commit.
  • il permet en fait de déplacer la TÊTE de tout commit ( commit --amend n'est sur de ne pas bouger la TÊTE, tout en permettant de refaire le commit courant)

Je viens de trouver ce exemple de combinaison:

  • un classique de fusion
  • un sous-arbre de fusion

tous en un seul (le poulpe, car il n'y a plus de deux branches fusionné) commit de fusion.

Tomas "wereHamster" Carnecky explique dans son "sous-arbre Pieuvre fusion" article:

  • Le sous-arbre de fusion stratégie peut être utilisée si vous souhaitez fusionner un projet dans un sous-répertoire d'un autre projet, et par la suite de garder le sous-projet jusqu'à ce jour. C'est une alternative à submodules.
  • Le poulpe de fusion de la stratégie peut être utilisée pour fusionner trois ou plus de branches. La stratégie normale peut fusionner les deux seules branches et si vous essayez de fusionner, de plus, git automatiquement revient à la pieuvre de la stratégie.

Le problème, c'est que vous pouvez choisir seulement une stratégie. Mais j'ai voulu combiner les deux afin d'obtenir un propre histoire dans laquelle le dépôt est automatiquement mis à jour vers une nouvelle version.

J'ai un superproject, appelons - projectA, et un sous-projet, projectB, que j'ai regroupées dans un sous-répertoire de projectA.

(c'est le sous-arbre de fusion de la partie)

Je suis également le maintien de quelques modifications locales.
ProjectA est régulièrement mis à jour, projectB a une nouvelle version tous les deux jours ou semaines, et en général dépend d'une version particulière d' projectA.

Quand je décide de mettre à jour les deux projets, je ne pas simplement tirer à partir d' projectA et projectB car cela permettrait de créer deux s'engage pour ce qui devrait être un atomiques mise à jour de l'ensemble du projet.
Au lieu de cela, j'ai créer un seul commit de fusion qui combine projectA, projectB et de ma région s'engage.
La partie délicate est que c'est un poulpe de fusion (trois têtes), mais projectB doit être fusionné avec le sous-arbre de la stratégie. C'est donc ce que je fais:

# Merge projectA with the default strategy:
git merge projectA/master

# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master

Ici, l'auteur a utilisé un reset --hard, puis read-tree de restaurer ce que les deux premiers fusionne l'avait fait à l'arbre de travail et de l'index, mais c'est là que reset --soft peut vous aider:
Comment puis-je refaire ces deux fusions, qui ont travaillé, c'est à dire mon arbre de travail et les index sont bien, mais sans avoir à enregistrer ces deux commits?

# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}

Maintenant, nous pouvons reprendre la Tomas de la solution:

# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD

# And finally do the commit:
git commit

Donc, à chaque fois:

  • vous êtes satisfait de ce que vous vous retrouvez avec (en terme de travail de l'arbre et de l'index)
  • vous êtes pas satisfait avec tous les changements que vous avez pris pour y arriver:

git reset --soft est la réponse.

58voto

Shaun Luttin Points 1585

Cas d'utilisation - Combiner une série de modifications locales

"Oups. Ces trois commet pourrait être juste".

Ainsi, l'annulation de la dernière 3 (ou autre) s'engage (sans incidence sur l'index, ni répertoire de travail). Puis les valider tous les changements.

E. g.

> git add -A; git commit -m "Start here."
> git add -A; git commit -m "One"
> git add -A; git commit -m "Two"
> git add -A' git commit -m "Three"
> git log --oneline --graph -4 --decorate

> * da883dc (HEAD, master) Three
> * 92d3eb7 Two
> * c6e82d3 One
> * e1e8042 Start here.

> git reset --soft HEAD~3
> git log --oneline --graph -1 --decorate

> * e1e8042 Start here.

Maintenant, toutes vos modifications sont conservées et prêt à être engagé en tant qu'un.

De courtes réponses à vos questions

Ce sont ces deux commandes vraiment le même (reset --soft vs commit --amend)?

  • Pas de.

Aucune raison d'utiliser l'un ou l'autre dans la pratique?

  • commit --amend ajouter/rm fichiers depuis le dernier commit ou à modifier son message.
  • reset --soft <commit> de combiner plusieurs séquentielle s'engage dans une nouvelle.

Et, plus important encore, sont-il d'autres utilisations pour reset --soft en dehors de la modification d'un commit?

  • Pas de.

23voto

Simon Points 8717

- Je l'utiliser pour modifier plus que le dernier commit.

Disons que j'ai fait une erreur en commettre Un, puis fait commettre B. Maintenant, je peux seulement modifier B. Donc, je n' git reset --soft HEAD^^,- je corriger et re-commettre Un et puis re-commettre B.

Bien sûr, il n'est pas très pratique pour les grands s'engage... mais vous ne devriez pas faire grand s'engage de toute façon ;-)

7voto

Johannes Rudolph Points 19845

Vous pouvez utiliser git reset --soft pour changer la version que vous voulez avoir en tant que parent pour les changements que vous avez dans votre index et votre arbre de travail. Les cas où cela est utile sont rares. Parfois, vous pourriez décider que les modifications que vous avez dans votre arbre de travail doit appartenir sur une autre branche. Ou vous pouvez l'utiliser comme un moyen simple de s'effondrer plusieurs s'engage dans un (similaire à la courge/fold).

Voir cette réponse par VonC pour un exemple pratique: git: comment squash les deux premiers s'engage?

7voto

Hazok Points 825

Une bonne raison d'utiliser 'git reset --soft <sha1>' est de déplacer HEAD en un nu-repo.

Si vous essayez d'utiliser l' --mixed ou --hard option, vous obtiendrez une erreur, puisque vous êtes en train de la modifier et de l'arbre de travail et/ou d'un indice qui n'existe pas.

Remarque: Vous aurez besoin de le faire directement à partir de la nue-repo.

A noter Encore: Vous devrez vous assurer que la branche que vous souhaitez réinitialiser dans le nu de la pension de titres est la branche active. Si non, suivez VonC de réponse sur la façon de mettre à jour la branche active dans un nu-pensions lorsque vous avez un accès direct à la repo.

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