Question Comment puis-je annuler git reset --hard HEAD ~ 1?


Est-il possible d'annuler les changements provoqués par la commande suivante? Si c'est le cas, comment?

git reset --hard HEAD~1

911
2017-08-07 23:22


origine


Réponses:


Pat Notz a raison. Vous pouvez récupérer le commit aussi longtemps que cela ne dure que quelques jours. git seulement les ordures se rassemblent après environ un mois ou plus à moins que vous le disiez explicitement pour enlever de nouveaux blobs.

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

Vous pouvez voir dans l'exemple que le fichier 2 a été supprimé à la suite de la réinitialisation matérielle, mais a été remis en place lorsque j'ai réinitialisé via le refog.


1398
2017-08-22 04:36



Ce que vous voulez faire est de spécifier le sha1 du commit que vous voulez restaurer. Vous pouvez obtenir le sha1 en examinant le reflog (git reflog) et ensuite faire

git reset --hard <sha1 of desired commit>

Mais n'attendez pas trop longtemps ... après quelques semaines, git finira par voir que commettre comme non référencé et supprimer tous les blobs.


313
2017-08-09 05:30



La réponse est cachée dans la réponse détaillée ci-dessus, vous pouvez simplement faire:

$> git reset --hard HEAD@{1}

(Voir la sortie de git reflog spectacle)


123
2018-02-26 15:13



Il est possible de le récupérer si Git n'a pas encore collecté les ordures.

Obtenez un aperçu des commits qui pendent avec fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Récupérer le commit suspendu avec rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

82
2017-08-22 06:11



Si vous êtes vraiment chanceux, comme je l'étais, vous pouvez revenir dans votre éditeur de texte et appuyer sur «Annuler».

Je sais que ce n'est pas vraiment une bonne réponse, mais cela m'a fait économiser une demi-journée, alors j'espère que ça fera la même chose pour quelqu'un d'autre!


33
2018-01-13 00:48



Exemple de cas IRL:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

27
2017-08-15 07:01



Pour autant que je sache, --hard rejettera les modifications non validées. Depuis ceux-ci ne sont pas suivis par git. mais vous pouvez annuler le discarded commit.

$ git reflog

listes de volonté:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

4bac331 est le discarded commit.

Maintenant, déplacez simplement la tête vers ce commit ::

$ git reset --hard 4bac331

25
2018-04-02 08:57



Dans la plupart des cas, oui.

En fonction de l'état dans lequel se trouvait votre référentiel lorsque vous avez exécuté la commande, les effets de git reset --hard peut varier de trivial à annuler, à essentiellement impossible.

Ci-dessous j'ai énuméré une gamme de différents scénarios possibles, et comment vous pourriez récupérer d'eux.

Tous mes changements ont été commis, mais maintenant les commits sont partis!

Cette situation se produit généralement lorsque vous exécutez git reset avec un argument, comme dans git reset --hard HEAD~. Ne vous inquiétez pas, c'est facile à récupérer!

Si vous venez de courir git reset et n'a rien fait d'autre depuis, vous pouvez revenir à l'endroit où vous étiez avec ce one-liner:

git reset --hard @{1}

Cela réinitialise votre branche actuelle quel que soit l'état dans lequel elle se trouvait avant la dernière modification (dans votre cas, la modification la plus récente de la branche serait la réinitialisation matérielle que vous essayez d'annuler).

Si, cependant, vous avoir fait d'autres modifications à votre branche depuis la réinitialisation, le one-liner ci-dessus ne fonctionnera pas. Au lieu de cela, vous devriez courir git reflog  <branchname> pour voir une liste de tous les changements récents apportés à votre branche (y compris les réinitialisations). Cette liste ressemblera à ceci:

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

Trouvez l'opération dans cette liste que vous voulez "annuler". Dans l'exemple ci-dessus, ce serait la première ligne, celle qui dit "reset: moving to HEAD ~". Puis copiez la représentation du commit avant (ci-dessous) cette opération. Dans notre cas, ce serait master@{1}(ou 3ae5027, ils représentent tous les deux le même commit), et courent git reset --hard <commit> pour réinitialiser votre branche actuelle à cette validation.

J'ai mis en scène mes changements avec git add, mais jamais commis. Maintenant, mes changements sont partis!

C'est un peu plus difficile à récupérer. git Est-ce que avoir des copies des fichiers que vous avez ajoutés, mais comme ces copies n'ont jamais été liées à un commit particulier, vous ne pouvez pas restaurer les modifications en une fois. Au lieu de cela, vous devez localiser les fichiers individuels dans la base de données de git et les restaurer manuellement. Vous pouvez le faire en utilisant git fsck.

Pour plus de détails à ce sujet, voir Annuler git reset --hard avec les fichiers non validés dans la zone de transit.

J'ai eu des changements dans les fichiers de mon répertoire de travail que je n'ai jamais mis en scène avec git addet jamais commis. Maintenant, mes changements sont partis!

Oh oh. Je déteste te le dire, mais tu n'as probablement pas de chance. git ne stocke pas les modifications que vous n'ajoutez pas ou ne commettez pas, et selon le documentation pour git reset:

--difficile

Réinitialise l'index et l'arbre de travail. Toutes les modifications apportées aux fichiers suivis dans l'arborescence de travail depuis <commit> sont jetés.

Il est possible que vous pourrait être en mesure de récupérer vos modifications avec une sorte d'utilitaire de récupération de disque ou un service de récupération de données professionnel, mais à ce stade, c'est probablement plus de problèmes que cela en vaut la peine.


23
2018-01-16 18:37



Si vous n'avez pas encore collecté vos déchets dans votre référentiel (par exemple en utilisant git repack -d ou git gc, mais notez que le garbage collection peut également se faire automatiquement), alors votre commit est toujours là - il n'est tout simplement plus accessible via HEAD.

Vous pouvez essayer de trouver votre commit en regardant à travers la sortie de git fsck --lost-found.

Les nouvelles versions de Git ont quelque chose appelé "reflog", qui est un journal de toutes les modifications apportées aux références (par opposition aux modifications apportées au contenu du référentiel). Ainsi, par exemple, chaque fois que vous changez votre HEAD (c'est-à-dire chaque fois que vous faites un git checkout pour changer de branche) qui seront enregistrés. Et, bien sûr, votre git reset également manipulé la tête, donc il a également été connecté. Vous pouvez accéder aux anciens états de vos références de la même manière que vous pouvez accéder aux anciens états de votre référentiel, en utilisant un @ signe au lieu d'un ~, comme git reset HEAD@{1}.

Il m'a fallu du temps pour comprendre quelle est la différence entre HEAD @ {1} et HEAD ~ 1, alors voici une petite explication:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

Alors, HEAD~1 signifie "aller à la validation avant le commit que pointe actuellement HEAD", tandis que HEAD@{1} signifie "aller au commit que HEAD a pointé avant de pointer vers où il pointe actuellement".

Cela vous permettra facilement de retrouver votre commit perdu et de le récupérer.


20
2017-08-27 03:45



Je sais que c'est un vieux fil ... mais comme beaucoup de gens cherchent des façons de défaire des choses dans Git, je pense toujours que c'est une bonne idée de continuer à donner des conseils ici.

Quand vous faites un "git add" ou déplacez quelque chose du coin supérieur gauche au coin inférieur gauche dans git gui le contenu du fichier est stocké dans un blob et le contenu du fichier est possible de récupérer à partir de ce blob.

Il est donc possible de récupérer un fichier même s'il n'a pas été validé mais il doit avoir été ajouté.

git init  
echo hello >> test.txt  
git add test.txt  

Maintenant, le blob est créé mais il est référencé par l'index donc il ne sera pas listé avec git fsck tant que nous ne l'aurons pas réinitialisé. Donc nous réinitialisons ...

git reset --hard  
git fsck  

vous obtiendrez une blob pendante ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

vous donnera le contenu du fichier "bonjour" retour

Pour trouver des commits non référencés, j'ai trouvé un conseil quelque part suggérant cela.

gitk --all $(git log -g --pretty=format:%h)  

Je l'ai comme un outil dans git gui et c'est très pratique.


10
2018-01-20 06:27