Comment récupérer les changements non engagés

j'ai eu quelques changements non engagés dans ma branche de développement et je les ai planqués en utilisant git stash , mais il y a eu quelques changements qui étaient très importants parmi ceux planqués. Est-il possible de récupérer ces changements?

aussi, j'ai fait quelques changements en plus 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?

437
demandé sur Flimzy 2013-09-25 14:56:21

3 réponses

la réponse facile à la question facile est git stash apply

il suffit de vérifier la branche sur laquelle vous voulez vos modifications, puis git stash apply . Ensuite, utilisez git diff pour voir le résultat.

une fois que vous avez terminé vos modifications-le apply a l'air bien et vous êtes sûr que vous n'avez plus besoin de la cachette - puis utilisez git stash drop pour vous en débarrasser.

je suggère toujours d'utiliser git stash apply plutôt que git stash pop . La différence est que apply laisse la cachette autour pour ré-essayer facile du apply , ou pour regarder, etc. Si pop est capable d'extraire la cachette, il sera immédiatement aussi drop elle, et si vous le réalisez soudainement que vous vouliez l'extraire ailleurs (dans une autre branche), ou avec --index , ou certains de ces, Ce n'est pas si facile. Si vous apply , vous choisir quand à drop .

tout est assez mineur d'une façon ou d'une autre, et pour un débutant à git, il devrait être à peu près le même. (Et vous pouvez ignorer tout le reste de ce!)


et si vous faites des choses plus avancées ou plus compliquées?

il y a au moins trois ou quatre" façons différentes d'utiliser git stash", pour ainsi dire. Ce qui précède est pour "way 1", Le "easy way":

  1. vous avez commencé avec une branche propre, vous 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 "déplacer" vers une autre branche.

    C'est le cas facile, décrit ci-dessus. Exécuter git stash save (ou simple git stash , même chose). Découvrez l'autre branche et utiliser git stash apply . Cela permet à git de fusionner avec vos modifications précédentes, en utilisant le mécanisme de fusion plutôt puissant de git. inspectez soigneusement les résultats (avec git diff ) pour voir si vous les aimez, et si vous le faites, utilisez git stash drop pour déposer la cachette. Vous avez terminé!

  2. vous avez commencé des changements et les avez cachés. Puis vous êtes passé à une autre branche et avez commencé plus de changements, oubliant que vous aviez les cachées.

    Maintenant vous voulez garder, ou même déplacer, ces changements, et appliquer votre cachette.

    vous pouvez en fait git stash save à nouveau, comme git stash fait une" pile " de changements. Si vous faites cela, vous avez deux cachettes, l'une juste appelée stash -mais vous pouvez aussi écrire stash@{0} -et une orthographiée stash@{1} . Utiliser git stash list (à tout moment) pour les voir toutes. La plus récente est toujours la plus basse. Quand vous git stash drop , il baisse le plus récent, et celui qui était stash@{1} se déplace vers le haut de la pile. Si vous aviez encore plus , celui qui était stash@{2} devient stash@{1} , et ainsi de suite.

    vous pouvez apply et puis drop une cachette spécifique, aussi: git stash apply stash@{2} , et ainsi de suite. Laisser tomber une cachette spécifique, renuméroter seulement les plus hauts numérotés. Encore une fois, celui sans numéro est aussi stash@{0} .

    Si vous accumuler beaucoup de caches, il peut obtenir assez bordélique (c'était la cachette je voulais stash@{7} ou stash@{4} ? Attendre, J'en ai poussé un autre, maintenant ils ont 8 et 5 ans?). Personnellement, je préfère transférer ces changements à une nouvelle succursale, parce que les succursales ont des noms, et cleanup-attempt-in-December signifie beaucoup plus pour moi que stash@{12} . (La commande git stash prend un message de sauvegarde optionnel, et ceux-ci peuvent aider, mais d'une façon ou d'une autre, toutes mes planques se terminent juste nommé WIP on branch .)

  3. (Extra-advanced) vous avez utilisé git stash save -p , ou avec précaution git add - ed et / ou git rm - ed bits spécifiques de votre code avant d'exécuter git stash save . Vous aviez une version dans l'index caché / zone de repos, et une autre (différente) version dans l'arbre de travail. Vous souhaitez conserver tout cela. Donc maintenant vous utilisez git stash apply --index , et qui échoue parfois avec:

    Conflicts in index.  Try without --index.
    
  4. vous utilisez git stash save --keep-index pour tester" ce qui sera commis". Celle-ci dépasse la portée de cette réponse; voir cette autre StackOverflow réponse à la place.

pour les cas compliqués, je recommande de commencer par un répertoire de travail "propre", en commettant tout changement que vous avez maintenant (sur une nouvelle branche si vous le souhaitez). De cette façon, le "quelque part" où vous les appliquez, n'a rien d'autre dedans, et vous essayerez juste les changements cachés:

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Maintenant, vous êtes sur un "propre" point de départ. Ou peut-être il va plus comme ça:

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

la principale chose à se rappeler 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'opération apply regarde ce que le commit a changé, et tente de le répéter où que vous soyez maintenant. La cachette sera toujours là ( apply la garde autour), donc vous pouvez regarder plus, ou décider que c'était le mauvais endroit pour apply il et essayer à nouveau différemment, ou quoi que ce soit.


chaque fois que vous avez une réserve, vous pouvez utiliser git stash show -p pour voir une version simplifiée de ce qui est dans la réserve. (Cette version simplifiée ne prend en compte que les modifications de "l'arbre de travail final", et non .) La commande git stash apply , sans --index , essaie juste de faire ces mêmes changements dans votre répertoire de travail maintenant.

Cela est vrai même si vous avez déjà quelques changements. La commande apply est heureuse d'appliquer une stash à un répertoire de travail modifié (ou du moins, d'essayer de l'appliquer). Vous pouvez, par exemple, faire ceci:

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

vous pouvez choisir l'ordre" apply " ici, En choisissant des réserves particulières à appliquer dans une séquence particulière. Notez, cependant, que chaque fois que vous faites essentiellement une "git merge", et que la documentation de la fusion warns:

lancer la fusion git avec des changements non-triviaux non engagés est déconseillé: tout est possible, il peut vous laisser dans un état qui est dur de revenir en arrière dans le cas d'un conflit.

si vous commencez avec un répertoire propre et que vous ne faites que plusieurs opérations git apply , il est facile de faire marche arrière: utilisez git reset --hard pour revenir à l'état propre, et changer votre apply des opérations. (C'est pourquoi je recommande de commencer par un répertoire de travail propre, pour ces cas compliqués.)


Qu'en est-il du pire cas possible?

disons que vous faites beaucoup de choses avancées Git, et vous avez fait une cachette, et veulent git stash apply --index , mais il n'est plus possible d'appliquer la cachette économisée avec --index , parce que la branche a divergé trop depuis le temps que vous avez sauvé il.

C'est à ça que sert git stash branch .

si vous:

  1. découvrez les exact commettre vous étiez lorsque vous avez l'original stash , puis
  2. créer une nouvelle branche, et enfin
  3. git stash apply --index

la tentative de re-créer les changements définitivement sera travail. C'est ce que fait git stash branch newbranch . (Et il tombe alors la cachette depuis qu'il a été appliqué avec succès.)


quelques derniers mots sur --index (qu'est-ce que c'est?)

ce que fait le --index est simple à expliquer, mais un peu compliqué à l'intérieur:

  • quand vous avez des changements, vous devez git add (ou" étape") les avant commit ing.
  • Ainsi, lorsque vous avez couru git stash , vous pourrait ont édité les deux dossiers foo et zorg , mais seulement mis en scène un de ceux.
  • donc quand vous demandez de récupérer la cachette, il pourrait être agréable si elle git add s le add ed choses et fait pas git add les choses non-ajoutées. C'est-à-dire, si vous add ed foo mais pas zorg retour avant que vous n'avez fait le stash il pourrait être agréable d'avoir exactement la même configuration. Ce qui a été mis en scène, doit à nouveau être mis en scène; ce qui a été modifié mais pas mis en scène, doit à nouveau être modifié mais pas mis en scène.

le --index drapeau à apply tente de mettre les choses en place de cette façon. Si votre arbre de travail est propre,cela fonctionne habituellement. Si votre arbre de travail a déjà des trucs add ed, cependant, vous pouvez voir comment il pourrait y avoir des problèmes ici. Si vous omettez --index , le L'opération apply ne vise pas à préserver l'ensemble de la configuration mise en scène/non mise en scène. Au lieu de cela, il invoque simplement la machine de fusion de git, en utilisant l'arbre de travail commit dans le "Stash bag" . Si vous ne vous souciez pas de préserver mis en scène ou non, l'exclusion de --index rend beaucoup plus facile pour git stash apply de faire sa chose.

727
répondu torek 2017-05-23 12:18:15
git stash pop

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, qui est la même chose que l'exécution:

git checkout -b newbranch
git stash pop
37
répondu Stefano Falasca 2017-06-14 08:35:42

pour faire simple, vous avez deux options pour remettre votre cachette:

  1. git stash pop - restaurer de nouveau à l'état sauvé, mais il supprime la cachette du stockage temporaire.
  2. git stash apply - restauration de l'état sauvegardé et sort de la liste de stock pour une éventuelle réutilisation ultérieure.

vous pouvez lire plus en détail sur git stashes dans cet article.

5
répondu Nesha Zoric 2018-05-25 07:49:29