J'ai eu des changements non validés dans ma branche de développement et je les ai cachés en utilisant git stash
, mais il y avait des changements qui étaient très importants parmi ceux qui étaient cachés. Existe-t-il un moyen de récupérer ces changements?
En outre, j'ai apporté des modifications au-dessus des fichiers de code cachés depuis.
Y a-t-il une chance que je puisse récupérer les modifications cachées dans une nouvelle branche si possible?
Réponses:
La réponse facile à la question facile est
git stash apply
Vérifiez simplement la branche sur laquelle vous souhaitez que vos modifications soient effectuées, puis
git stash apply
. Utilisez ensuitegit diff
pour voir le résultat.Une fois que vous avez terminé vos modifications - l'
apply
apparence est bonne et vous êtes sûr que vous n'avez plus besoin de la cachette - puis utilisezgit stash drop
pour vous en débarrasser.Je suggère toujours d'utiliser
git stash apply
plutôt quegit stash pop
. La différence est que lesapply
feuilles autour de la planque pour rejuger facile duapply
ou pour regarder, etc. Sipop
est en mesure d'extraire la planque, il sera immédiatement aussidrop
, et si vous le réalisez soudainement que vous vouliez extraire quelque part d'autre (dans une branche différente), ou avec--index
, ou quelque chose comme ça, ce n'est pas si facile. Si vousapply
, vous pouvez choisir quanddrop
.C'est tout de même assez mineur d'une manière ou d'une autre, et pour un débutant, il devrait être à peu près la même chose. (Et vous pouvez sauter tout le reste!)
Et si vous faites des choses plus avancées ou plus compliquées?
Il existe au moins trois ou quatre "façons différentes d'utiliser git stash", pour ainsi dire. Ce qui précède est pour la "voie 1", la "voie facile":
Vous avez commencé avec une branche propre, travailliez sur certains changements, puis vous avez réalisé que vous les faisiez dans la mauvaise branche. Vous voulez juste prendre les changements que vous avez maintenant et les "déplacer" vers une autre branche.
C'est le cas facile, décrit ci-dessus. Exécutez
git stash save
(ou simplementgit stash
, la même chose). Découvrez l'autre branche et utilisezgit stash apply
. Cela permet à git de fusionner dans vos modifications précédentes, en utilisant le mécanisme de fusion plutôt puissant de git. Inspectez soigneusement les résultats (avecgit diff
) pour voir si vous les aimez, et si vous le faites, utilisezgit stash drop
pour déposer la réserve. Vous avez terminé!Vous avez commencé certains changements et les avez cachés. Ensuite, vous êtes passé à une autre branche et avez commencé d'autres changements, oubliant que vous aviez les cachés.
Vous souhaitez maintenant conserver, voire déplacer, ces modifications et appliquer également votre cachette.
Vous pouvez en fait à
git stash save
nouveau, car celagit stash
fait une "pile" de changements. Si vous faites cela, vous avez deux cachettes, une juste appeléestash
- mais vous pouvez également écrirestash@{0}
- et une orthographiéestash@{1}
. Utilisezgit stash list
(à tout moment) pour les voir tous. Le plus récent est toujours le plus petit. Lorsque vousgit stash drop
, il supprime le plus récent et celui qui étaitstash@{1}
déplacé vers le haut de la pile. Si vous en aviez encore plus, celui qui l'étaitstash@{2}
devientstash@{1}
, et ainsi de suite.Vous pouvez aussi
apply
, puisdrop
une cachette spécifique:,git stash apply stash@{2}
et ainsi de suite. En supprimant une réserve spécifique, vous ne renumérotez que les numéros plus élevés. Encore une fois, celui sans numéro l'est aussistash@{0}
.Si vous empilez beaucoup de cachettes, cela peut devenir assez salissant (était-ce la cachette que je voulais
stash@{7}
ou était-cestash@{4}
? Attendez, j'en ai juste poussé une autre, maintenant elles sont 8 et 5?). Personnellement, je préfère transférer ces modifications dans une nouvelle succursale, car les succursales ont des noms et représententcleanup-attempt-in-December
beaucoup plus pour moi questash@{12}
. (Lagit stash
commande prend un message de sauvegarde facultatif, et ceux-ci peuvent aider, mais d'une manière ou d'une autre, toutes mes réserves se terminent par un nomWIP on branch
.)(Extra-avancé) Vous avez utilisé
git stash save -p
, ou soigneusementgit add
et / ougit rm
des bits spécifiques de votre code avant de lancergit stash save
. Vous aviez une version dans l'index / zone de stockage caché et une autre version (différente) dans l'arborescence de travail. Vous voulez conserver tout cela. Alors maintenant, vous utilisezgit stash apply --index
, et cela échoue parfois avec:Vous utilisez
git stash save --keep-index
pour tester "ce qui sera commis". Celui-ci dépasse le cadre de cette réponse; voir cette autre réponse StackOverflow à la place.Pour les cas compliqués, je recommande de commencer par un répertoire de travail "propre" en validant toutes les modifications que vous avez maintenant (sur une nouvelle branche si vous le souhaitez). De cette façon, le «quelque part» que vous appliquez ne contient rien d'autre, et vous essayerez simplement les changements cachés:
Vous êtes maintenant sur un point de départ "propre". Ou peut-être que cela ressemble plus à ceci:
La principale chose à retenir est que le "stash" est un commit, c'est juste un commit légèrement "drôle / bizarre" qui n'est pas "sur une branche". L'
apply
opération examine ce que le commit a changé et essaie de le répéter où que vous soyez. La cachette sera toujours là (la garderaapply
autour), donc vous pouvez la regarder plus, ou décider que ce n'était pas le bon endroitapply
et réessayer différemment, ou autre chose.Chaque fois que vous avez une cachette, vous pouvez utiliser
git stash show -p
pour voir une version simplifiée de ce qu'elle contient. (Cette version simplifiée ne regarde que les modifications de "l'arborescence de travail finale", pas les modifications d'index enregistrées qui sont--index
restaurées séparément.) La commandegit stash apply
, sans--index
, essaie maintenant de faire ces mêmes modifications dans votre répertoire de travail maintenant.Cela est vrai même si vous avez déjà des modifications. La
apply
commande est heureuse d'appliquer une cachette à un répertoire de travail modifié (ou au moins, d'essayer de l'appliquer). Vous pouvez, par exemple, faire ceci:Vous pouvez choisir ici la commande «appliquer», en sélectionnant des masques particuliers à appliquer dans une séquence particulière. Notez cependant que chaque fois que vous effectuez une "fusion git", et comme la documentation de fusion l'avertit:
Si vous commencez avec un répertoire propre et que vous effectuez simplement plusieurs
git apply
opérations, il est facile de revenir en arrière: utilisezgit reset --hard
pour revenir à l'état propre et modifiez vosapply
opérations. (C'est pourquoi je recommande de commencer par un répertoire de travail propre, pour ces cas compliqués.)Et le pire cas possible?
Disons que vous faites beaucoup de trucs Git avancés, et que vous avez créé une stash, et que vous le souhaitez
git stash apply --index
, mais il n'est plus possible d'appliquer la stash enregistrée avec--index
, car la branche a trop divergé depuis le moment où vous l'avez enregistrée.C'est pour ça
git stash branch
.Si vous:
stash
, puisgit stash apply --index
la tentative de recréer les changements sans aucun doute va fonctionner. C'est ce qui fait. (Et il supprime ensuite la réserve car il a été appliqué avec succès.)
git stash branch newbranch
Quelques derniers mots sur
--index
(de quoi diable s'agit-il?)Ce que cela
--index
fait est simple à expliquer, mais un peu compliqué en interne:git add
(ou les "mettre en scène") avant de lescommit
ing.git stash
, vous avez peut- être édité les deux fichiersfoo
etzorg
, mais n'en avez créé qu'un seul.git add
sont lesadd
choses éditées et nongit add
les choses non ajoutées. Autrement dit, si vous avezadd
éditéfoo
mais paszorg
avant de faire lestash
, il serait peut-être bien d'avoir exactement la même configuration. Ce qui a été mis en scène, devrait à nouveau être mis en scène; ce qui a été modifié mais pas mis en scène, devrait à nouveau être modifié mais pas mis en scène.Le
--index
drapeau pourapply
tente de configurer les choses de cette façon. Si votre arbre de travail est propre, cela fonctionne généralement bien. Si votre arbre de travail contient déjà des élémentsadd
, vous pouvez voir comment il peut y avoir des problèmes ici. Si vous omettez--index
cetteapply
opération , l' opération n'essaie pas de conserver l'intégralité de la configuration par étapes / non. Au lieu de cela, il appelle simplement la machine de fusion de git, en utilisant la validation de l'arbre de travail dans le "sac de dissimulation" . Si vous ne vous souciez pas de la préservation par étapes / sans mise en scène, laisser de côté--index
facilite beaucoup la tâchegit stash apply
.la source
git stash pop
? Ou voulez-vous dire: vous avez modifié certains fichiers, mais ne les avez pasgit stash
encore exécutés ? Ou voulez-vous dire autre chose entièrement?apply
créer une cachette. Vous n'êtes pas obligé de le faire, mais cela rend les choses beaucoup plus simples à regarder. Vous pouvez utiliserrebase -i
pour écraser ensemble plusieurs validations, ou sélectionner des modifications particulières, ou quoi que ce soit, plus tard.git stash apply --index
(rappelez-vous les deux tirets). Si vous omettez--index
, ce n'est pas grave; le seul point--index
est de conserver la configuration par étapes / non par étapes. (Vous n'avez probablement pas eu de configuration spéciale en premier lieu.) Ensuite,git status
etc, et ajoutez / validez comme vous le souhaitez, etc. Quand (et seulement quand) vous avez terminé avec la cachette, utilisezgit stash drop
pour la jeter.drop
oupop
) la cachette, vous avez toujours le code caché d'origine en sécurité lors d'une validation, car une cachette est une validation! Si vous voulez le récupérer exactement, mais sur une branche, utilisezgit stash branch
(voir cette section ci-dessus, ou le livre Pro Git dans la réponse de Shunya ). Vous pouvez alorsgit checkout
cette branche, ougit cherry-pick
la validation hors de cette branche, etc.va tout remettre en place
comme suggéré dans les commentaires, vous pouvez utiliser
git stash branch newbranch
pour appliquer la cachette à une nouvelle branche, ce qui revient à exécuter:la source
git stash branch newbranch
fera effectivement cela; mais sachez qu'il crée la nouvelle branche avec son parent défini sur la validation qui étaitHEAD
au moment où l'opération astash
été effectuée. En d'autres termes, c'est quand vous revenez après une longue session de piratage ou autre, regardez le désordre et décidez "j'aurais dû mettre ça sur une branche, plutôt que de le cacher" :-)Pour simplifier, vous avez deux options pour réappliquer votre stash:
git stash pop
- Restaurez à l'état enregistré, mais il supprime la cachette de la mémoire temporaire.git stash apply
- Restaurez à l'état enregistré et laisse la liste cachée pour une éventuelle réutilisation ultérieure.Vous pouvez lire plus en détail sur les cachettes git dans cet article.
la source
Pour vérifier votre contenu caché: -
appliquer un no de stash particulier de la liste de stash: -
ou pour appliquer uniquement le premier stash: -
Remarque: git stash pop supprimera la stash de votre liste de stash tandis que git stash ne s'applique pas. Utilisez-les donc en conséquence.
la source
Sur mac, cela a fonctionné pour moi:
git stash list (voir toutes vos stashs)
git stash applique (juste le numéro que vous voulez dans votre liste de stash)
comme ça:
la source
vous pouvez cacher les modifications non validées en utilisant "git stash" puis passer à une nouvelle branche en utilisant "git checkout -b" puis appliquer les commits cachés "git stash apply"
la source