J'utilise fréquemment git stash
et git stash pop
pour enregistrer et restaurer les modifications dans mon arbre de travail. Hier, j'ai eu quelques changements dans mon arbre de travail que j'avais cachés et sautés, puis j'ai apporté plus de changements à mon arbre de travail. Je voudrais revenir en arrière et revoir les modifications cachées d'hier, mais git stash pop
semble supprimer toutes les références au commit associé.
Je sais que si j'utilise git stash
alors .git / refs / stash contient la référence du commit utilisé pour créer le stash. Et .git / logs / refs / stash contient la totalité de la cachette. Mais ces références ont disparu git stash pop
. Je sais que le commit est toujours quelque part dans mon référentiel, mais je ne sais pas ce que c'était.
Existe-t-il un moyen facile de récupérer la référence de validation de cache d'hier?
Notez que ce n'est pas critique pour moi aujourd'hui car j'ai des sauvegardes quotidiennes et je peux revenir à l'arborescence de travail d'hier pour obtenir mes modifications. Je demande parce qu'il doit y avoir un moyen plus simple!
git stash pop
, vous pouvez le faire à lagit stash apply
place. Il fait la même chose, sauf qu'il ne supprime pas la référence à la cachette appliquée.git stash
,git pull -r upstream
,git push -f origin
,git stash pop
et pop dit « fatale: journal refs / Stash est vide ». 😲 J'ai essayé un tas de ces réponses, rien n'a fonctionné. Quand j'ai regardé en .git / refs / stash , le SHA était là. Peut-être un problème avec le marquage d'un lecteur réseau Windows pour la synchronisation hors ligne? 🤷♂️Réponses:
Une fois que vous connaissez le hachage du commit de stash que vous avez supprimé, vous pouvez l'appliquer en tant que stash:
Ou, vous pouvez créer une branche distincte avec
Après cela, vous pouvez faire ce que vous voulez avec tous les outils normaux. Lorsque vous avez terminé, soufflez simplement la branche.
Trouver le hachage
Si vous venez de le faire sauter et que le terminal est toujours ouvert, vous aurez toujours la valeur de hachage imprimée par
git stash pop
à l'écran (merci, Dolda).Sinon, vous pouvez le trouver en utilisant ceci pour Linux, Unix ou Git Bash pour Windows:
... ou en utilisant Powershell pour Windows:
Cela vous montrera toutes les validations aux extrémités de votre graphique de validation qui ne sont plus référencées à partir d'une branche ou d'une balise - chaque validation perdue, y compris chaque validation de cache que vous avez jamais créée, se trouvera quelque part dans ce graphique.
Le moyen le plus simple de trouver le commit de sauvegarde que vous souhaitez est probablement de transmettre cette liste à
gitk
:... ou consultez la réponse des emragins si vous utilisez Powershell pour Windows.
Cela lancera un navigateur de référentiel vous montrant chaque commit unique dans le référentiel , qu'il soit accessible ou non.
Vous pouvez
gitk
y remplacer quelque chose commegit log --graph --oneline --decorate
si vous préférez un joli graphique sur la console plutôt qu'une application graphique distincte.Pour repérer les validations stash, recherchez les messages de validation de ce formulaire:
WIP sur somebranch : commithash Un vieux message de commit
Remarque : Le message de validation ne sera sous cette forme (commençant par "WIP activé") que si vous n'avez pas fourni de message lorsque vous l'avez fait
git stash
.la source
%{ $_.Split(' ')[2]; }
devrait faire l'équivalent de la commande{print $3}
in thatawk
dans PowerShell, mais je n'ai pas de système Windows pour le tester, et vous avez toujours besoin d'un équivalent pour la/dangling commit/
pièce. Quoi qu'il en soit, exécutez simplementgit fsck --no-reflog
et regardez la sortie. Vous voulez les hachages des lignes «dangling commit <commitID>».git stash save "<message>"
).git fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
la dernière entrée est probablement celle que vous souhaitezstash apply
.git stash apply {ref}
restauré une cachette abandonnée!git
est tellement génial que ça devrait être illégal!Si vous n'avez pas fermé le terminal, regardez simplement la sortie de
git stash pop
et vous aurez l'ID d'objet de la cachette déposée. Cela ressemble normalement à ceci:(Notez que
git stash drop
produit également la même ligne.)Pour récupérer cette réserve, exécutez simplement
git branch tmp 2cae03e
et vous l'obtiendrez comme une branche. Pour convertir cela en stash, exécutez:Le faire en tant que branche vous permet également de le manipuler librement; par exemple, pour le sélectionner ou le fusionner.
la source
git stash apply commitid
ensuitegit stash
pour obtenir une nouvelle planque.git stash pop
, cela ne supprimera pas non plus la cachette, donc ce n'est normalement pas un problème.git stash pop
. Si vous souhaitez appliquer la réserve sans la supprimer, utilisezgit stash apply
plutôt. De plus, si vous souhaitez appliquer une modification à plusieurs branches, vous pouvez également sélectionner le commit à la place.Je voulais juste mentionner cet ajout à la solution acceptée. Ce n'était pas immédiatement évident pour moi la première fois que j'ai essayé cette méthode (peut-être qu'elle aurait dû l'être), mais pour appliquer la cachette à partir de la valeur de hachage, il suffit d'utiliser "git stash apply":
Quand j'étais nouveau sur git, ce n'était pas clair pour moi, et j'essayais différentes combinaisons de "git show", "git apply", "patch", etc.
la source
Pour obtenir la liste des stashes qui sont toujours dans votre référentiel, mais qui ne sont plus accessibles:
Si vous avez donné un titre à votre cachette, remplacez "WIP"
-grep=WIP
à la fin de la commande par une partie de votre message, par exemple-grep=Tesselation
.La commande attend "WIP" car le message de validation par défaut pour une stash est sous la forme
WIP on mybranch: [previous-commit-hash] Message of the previous commit.
la source
!
).Je viens de construire une commande qui m'a aidé à retrouver mon commit de stash perdu:
Cela répertorie tous les objets dans l'arborescence .git / objects, localise ceux qui sont de type commit, puis affiche un résumé de chacun. À partir de là, il s'agissait simplement de parcourir les commits pour trouver un "WIP on work: 6a9bb2" approprié ("work" est ma branche, 619bb2 est un commit récent).
Je note que si j'utilise "git stash apply" au lieu de "git stash pop" je n'aurais pas ce problème, et si j'utilise "git stash save message " alors le commit aurait pu être plus facile à trouver.
Mise à jour: Avec l'idée de Nathan, cela devient plus court:
la source
git fsck --unreachable | grep commit
devrait montrer le sha1, bien que la liste qu'il renvoie puisse être assez grande.git show <sha1>
montrera si c'est le commit que vous voulez.git cherry-pick -m 1 <sha1>
fusionnera le commit sur la branche courante.la source
Équivalent Windows PowerShell utilisant gitk:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
Il existe probablement un moyen plus efficace de le faire dans un seul tuyau, mais cela fait le travail.
la source
Si vous souhaitez restaurer une réserve perdue, vous devez d'abord trouver le hachage de votre réserve perdue.
Comme l'a suggéré Aristote Pagaltzis, un
git fsck
devrait vous aider.Personnellement j'utilise mon
log-all
alias qui me montre chaque commit (commits récupérables) pour avoir une meilleure vue de la situation:Vous pouvez effectuer une recherche encore plus rapide si vous recherchez uniquement des messages "WIP on".
Une fois que vous connaissez votre sha1, vous changez simplement votre reflog de stash pour ajouter l'ancien stash:
Vous préférerez probablement avoir un message associé afin qu'un
-m
Et vous voudrez même l'utiliser comme alias:
la source
-d\\
devrait être-d\
(ou même plus clair-d' '
)git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
J'ai aimé l'approche d'Aristote, mais je n'ai pas aimé utiliser GITK ... car j'ai l'habitude d'utiliser GIT depuis la ligne de commande.
Au lieu de cela, j'ai pris les validations pendantes et sorti le code dans un fichier DIFF pour examen dans mon éditeur de code.
Maintenant, vous pouvez charger le fichier diff / txt résultant (son dans votre dossier personnel) dans votre éditeur txt et voir le code réel et SHA résultant.
Ensuite, utilisez simplement
la source
Vous pouvez lister tous les commits inaccessibles en écrivant cette commande dans le terminal -
Vérifier le hachage de validation inaccessible -
Enfin, appliquez si vous trouvez l'article caché -
la source
Pourquoi les gens posent-ils cette question? Parce qu'ils ne connaissent pas ou ne comprennent pas encore le reflog.
La plupart des réponses à cette question donnent de longues commandes avec des options dont presque personne ne se souviendra. Donc, les gens entrent dans cette question et copient-collent tout ce qu'ils pensent avoir besoin et l'oublient presque immédiatement après.
Je conseillerais à tout le monde avec cette question de simplement vérifier le reflog (git reflog), pas beaucoup plus que cela. Une fois que vous voyez cette liste de tous les commits, il y a cent façons de savoir quel commit vous recherchez et de le sélectionner ou de créer une branche à partir de celui-ci. Dans le processus, vous aurez appris le reflog et les options utiles de diverses commandes de base de git.
la source
Dans OSX avec git v2.6.4, je lance accidentellement git stash drop, puis je l'ai trouvé en parcourant les étapes ci-dessous
Si vous connaissez le nom de la cachette, utilisez:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>
sinon, vous trouverez l'ID du résultat manuellement avec:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show
Ensuite, lorsque vous trouvez le commit-id, appuyez simplement sur la cachette git apply {commit-id}
J'espère que cela aide quelqu'un rapidement
la source
Je veux ajouter à la solution acceptée un autre bon moyen de passer par tous les changements, lorsque vous n'avez pas de gitk disponible ou pas de X pour la sortie.
Ensuite, vous obtenez tous les différences pour ces hachages affichées l'une après l'autre. Appuyez sur 'q' pour passer au diff suivant.
la source
Je n'ai pu obtenir aucune des réponses pour travailler sur Windows dans une fenêtre de commande simple (Windows 7 dans mon cas).
awk
,grep
EtSelect-string
ne sont pas reconnus comme des commandes. J'ai donc essayé une approche différente:git fsck --unreachable | findstr "commit"
start cmd /k git show
ressemblera à ceci:
start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e
git stash apply (your hash)
n'est peut-être pas la meilleure solution, mais a fonctionné pour moi
la source
La réponse acceptée par Aristote montrera tous les commits accessibles, y compris les commits non-stash. Pour filtrer le bruit:
Cela n'inclura que les validations qui ont exactement 3 validations parentes (dont une cachette aura) et dont le message comprend "WIP on".
Gardez à l'esprit que si vous avez enregistré votre cachette avec un message (par exemple
git stash save "My newly created stash"
), cela remplacera le message par défaut "WIP on ...".Vous pouvez afficher plus d'informations sur chaque commit, par exemple afficher le message de commit, ou le transmettre à
git stash show
:la source
Mon préféré est ce one-liner:
C'est fondamentalement la même idée que cette réponse mais beaucoup plus courte. Bien sûr, vous pouvez toujours ajouter
--graph
pour obtenir un affichage arborescent.Lorsque vous avez trouvé le commit dans la liste, appliquez avec
Pour moi, l'utilisation
--no-reflogs
a révélé l'entrée cachée perdue, mais--unreachable
(comme dans de nombreuses autres réponses) ne l'a pas fait.Exécutez-le sur git bash lorsque vous êtes sous Windows.
Crédits: Les détails des commandes ci-dessus sont tirés de https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf
la source
Récupéré en utilisant les étapes suivantes:
Identifiez le code de hachage caché supprimé:
gitk --all $ (git fsck --no-reflog | awk '/ dangling commit / {print $ 3}')
Cherry Pick the Stash:
git cherry-pick -m 1 $ stash_hash_code
Résolvez les conflits, le cas échéant, en utilisant:
git mergetool
De plus, vous pouvez rencontrer des problèmes avec le message de validation si vous utilisez gerrit. Veuillez cacher vos modifications avant de suivre les alternatives suivantes:
la source
Ce que je suis venu ici, c'est comment récupérer la cachette, indépendamment de ce que j'ai vérifié. En particulier, j'avais caché quelque chose, puis extrait une version plus ancienne, puis l'avais sortie, mais la cachette était un no-op à ce moment-là, donc la cachette a disparu; Je ne pouvais pas simplement le
git stash
repousser sur la pile. Cela a fonctionné pour moi:Rétrospectivement, j'aurais dû utiliser
git stash apply
nongit stash pop
. Je faisais unbisect
et j'avais un petit patch que je voulais appliquer à chaquebisect
étape. Maintenant je fais ça:la source
stash apply
.