Est-il possible d'annuler les modifications provoquées par la commande suivante? Si c'est le cas, comment?
git reset --hard HEAD~1
git
version-control
git-reset
Paul Wicks
la source
la source
--hard
rejette les modifications non validées. Étant donné que ceux-ci ne sont pas suivis par git, il n'y a aucun moyen de les restaurer via git.Réponses:
Pat Notz a raison. Vous pouvez récupérer le commit tant qu'il a été effectué en quelques jours. git ne récupère que les ordures après environ un mois, sauf si vous lui demandez explicitement de supprimer les nouveaux blobs.
Vous pouvez voir dans l'exemple que le fichier2 a été supprimé à la suite de la réinitialisation matérielle, mais a été remis en place lorsque je réinitialise via le reflog.
la source
git log -g
peut être un moyen un peu plus agréable de visualiser le reflog quegit reflog
.git reflog
plusgit log -g
simplement parce que vous obtenez toutes les informations sur une ligne avec SHA1, informations HEAD et commits tous alignés. Beaucoup plus facile à lire.Ce que vous voulez faire, c'est spécifier le sha1 du commit sur lequel vous souhaitez restaurer. Vous pouvez obtenir le sha1 en examinant le reflog (
git reflog
) puis en faisantgit reset --hard <sha1 of desired commit>
Mais n'attendez pas trop longtemps ... après quelques semaines, git verra finalement ce commit comme non référencé et supprimera tous les blobs.
la source
La réponse est cachée dans la réponse détaillée ci-dessus, vous pouvez simplement faire:
(Voir la sortie de git reflog show )
la source
Il est possible de le récupérer si Git n'a pas encore récupéré les ordures.
Obtenez un aperçu des commissions pendantes avec
fsck
:Récupérez le commit pendant avec rebase:
la source
Si vous êtes vraiment chanceux, comme je l'ai été, vous pouvez retourner 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 épargné une demi-journée de travail, alors j'espère que cela fera la même chose pour quelqu'un d'autre!
la source
autant que je sache,
--hard
rejettera les modifications non validées. Puisque ceux-ci ne sont pas suivis par git. mais vous pouvez annuler lediscarded commit
.répertorie:
où
4bac331
est lediscarded commit
.Maintenant, déplacez simplement la tête vers ce commit ::
la source
Exemple de cas IRL:
$ git fsck --lost-found
$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a
$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a
la source
Dans la plupart des cas, oui.
Selon l'état dans lequel se trouvait votre référentiel lorsque vous avez exécuté la commande, les effets de
git reset --hard
peuvent varier de triviaux à annuler, voire fondamentalement impossibles.Ci-dessous, j'ai énuméré une gamme de différents scénarios possibles et comment vous pouvez en récupérer.
Tous mes changements ont été validés, mais maintenant les validations ont disparu!
Cette situation se produit généralement lorsque vous exécutez
git reset
avec un argument, comme dansgit reset --hard HEAD~
. Ne vous inquiétez pas, c'est facile à récupérer!Si vous venez de courir
git reset
et n'avez rien fait d'autre depuis, vous pouvez revenir où vous étiez avec ce one-liner: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 avez apporté d'autres modifications à votre branche depuis la réinitialisation, le one-liner ci-dessus ne fonctionnera pas. Au lieu de cela, vous devez exécuter pour voir une liste de toutes les modifications récentes apportées à votre branche (y compris les réinitialisations). Cette liste ressemblera à ceci:
git reflog
<branchname>
Recherchez l'opération dans cette liste que vous souhaitez "annuler". Dans l'exemple ci-dessus, ce serait la première ligne, celle qui dit "reset: passer à HEAD ~". Copiez ensuite la représentation du commit avant (ci-dessous) cette opération. Dans notre cas, ce serait
master@{1}
(ou3ae5027
, ils représentent tous deux le même commit), et exécutezgit reset --hard <commit>
pour réinitialiser votre branche actuelle sur ce commit.J'ai organisé mes changements avec
git add
, mais jamais engagé. Maintenant, mes changements ont disparu!C'est un peu plus difficile à récupérer. git possède 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 d'un coup. 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 la réinitialisation de git --hard avec des fichiers non validés dans la zone de transfert .
J'ai eu des modifications de fichiers dans mon répertoire de travail avec lesquelles je n'ai jamais mis en scène
git add
et jamais commis. Maintenant, mes changements ont disparu!Euh oh. Je déteste te dire ça, mais tu n'as probablement pas de chance. git ne stocke pas les modifications que vous n'y ajoutez pas ou ne vous engagez pas, et selon la documentation de
git reset
:Il est possible que vous puissiez 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 ne vaut.
la source
Si vous n'avez pas encore récupéré votre mémoire (par exemple en utilisant
git repack -d
ougit gc
, mais notez que le nettoyage peut également se produire automatiquement), alors votre commit est toujours là - il n'est tout simplement plus accessible via HEAD.Vous pouvez essayer de trouver votre commit en parcourant la sortie de
git fsck --lost-found
.Les versions plus récentes de Git ont quelque chose appelé le «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 de HEAD (c'est-à-dire chaque fois que vous faites un
git checkout
pour changer de branche) qui sera enregistré. Et, bien sûr, vous avezgit reset
également manipulé le HEAD, il était donc également enregistré. 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~
, commegit reset HEAD@{1}
.Il m'a fallu un certain temps pour comprendre la différence entre HEAD @ {1} et HEAD ~ 1, voici donc une petite explication:
Donc,
HEAD~1
signifie "aller au commit avant le commit auquel HEAD pointe actuellement", tandis queHEAD@{1}
signifie "aller au commit sur lequel HEAD a pointé avant qu'il pointe vers l'endroit où il pointe actuellement".Cela vous permettra facilement de retrouver votre commit perdu et de le récupérer.
la source
Avant de répondre, ajoutons quelques informations, expliquant ce que c'est
HEAD
.First of all what is HEAD?
HEAD
est simplement une référence au commit actuel (le plus récent) sur la branche courante.Il ne peut y en avoir qu'un seul
HEAD
à un moment donné. (à l'exclusiongit worktree
)Le contenu de
HEAD
est stocké à l'intérieur.git/HEAD
et contient les 40 octets SHA-1 de la validation en cours.detached HEAD
Si vous n'êtes pas sur le dernier commit - ce qui signifie qu'il
HEAD
pointe vers un commit antérieur dans l'historique, c'est appelédetached HEAD
.Sur la ligne de commande, cela ressemblera à ceci - SHA-1 au lieu du nom de la branche car le
HEAD
ne pointe pas vers la pointe de la branche actuelleQuelques options sur la façon de récupérer à partir d'une tête détachée:
git checkout
Cela va extraire une nouvelle branche pointant vers le commit souhaité.
Cette commande extrait un commit donné.
À ce stade, vous pouvez créer une branche et commencer à travailler à partir de ce point.
git reflog
Vous pouvez également toujours utiliser le
reflog
.git reflog
affichera tout changement qui a mis à jour leHEAD
et vérifier l'entrée de reflog souhaitée mettra leHEAD
dos à ce commit.Chaque fois que le HEAD est modifié, il y aura une nouvelle entrée dans le
reflog
Cela vous ramènera à votre engagement souhaité
git reset HEAD --hard <commit_id>
"Déplacer" votre tête vers le commit souhaité.
vous pouvez également utiliser le
git rebase --no-autostash
.git revert <sha-1>
"Annuler" la validation ou la plage de validation donnée.
La commande de réinitialisation "annulera" toutes les modifications apportées au commit donné.
Un nouveau commit avec le patch d'annulation sera validé tandis que le commit d'origine restera également dans l'historique.
Ce schéma illustre quelle commande fait quoi.
Comme vous pouvez le voir,
reset && checkout
modifiez leHEAD
.la source
git reset HEAD --hard <commit_id>
exemple soit tiré de stackoverflow.com/questions/4114095/… - Si tel est le cas, pourriez-vous modifier dans l'attribution?git reflog
git cherry-pick <the sha>
la source
Je sais que c'est un vieux fil de discussion ... mais comme beaucoup de gens cherchent des moyens d'annuler des choses dans Git, je pense toujours que ce serait une bonne idée de continuer à donner des conseils ici.
Lorsque vous faites un "git add" ou déplacez quoi que ce soit du haut à gauche vers le bas à 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é.
Maintenant, le blob est créé, mais il est référencé par l'index, il ne sera donc pas répertorié avec git fsck jusqu'à ce que nous le réinitialisions. Nous avons donc réinitialisé ...
vous obtiendrez une goutte pendante ce013625030ba8dba906f756967f9e9ca394464a
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.
Je l'ai comme outil dans git gui et c'est très pratique.
la source
git fsck --lost-found
peut vous aider.Si vous utilisez un IDE JetBrains (tout ce qui est basé sur IntelliJ), vous pouvez récupérer même vos modifications non validées via leur fonctionnalité "Historique local".
Faites un clic droit sur votre répertoire de niveau supérieur dans votre arborescence de fichiers, recherchez "Historique local" dans le menu contextuel et choisissez "Afficher l'historique". Cela ouvrira une vue où vos modifications récentes peuvent être trouvées, et une fois que vous avez trouvé la révision à laquelle vous souhaitez revenir, faites un clic droit dessus et cliquez sur "Revenir".
la source
Je viens de faire une réinitialisation matérielle sur un mauvais projet. Ce qui m'a sauvé la vie, c'est l'histoire locale d'Eclipse. IntelliJ Idea en aurait également un, et votre éditeur aussi, il vaut la peine de le vérifier:
la source
Création d'un petit script pour faciliter la recherche du commit recherché:
git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'
Oui, cela peut être rendu beaucoup plus joli avec awk ou quelque chose comme ça, mais c'est simple et j'en avais juste besoin. Pourrait sauver quelqu'un d'autre 30 secondes.
la source
Mon problème est presque similaire. J'ai des fichiers non validés avant d'entrer
git reset --hard
.Heureusement. J'ai réussi à ignorer toutes ces ressources. Après avoir remarqué que je pouvais juste annuler (
ctrl-z
). 😊 Je veux juste ajouter ceci à toutes les réponses ci-dessus.Remarque. Il n'est pas possible d'
ctrl-z
ouvrir des fichiers.la source
Cela m'a sauvé la vie:
https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c
Fondamentalement, vous devez exécuter:
Ensuite, passez manuellement à travers la douleur pour réorganiser vos fichiers dans la bonne structure.
À emporter: ne jamais utiliser
git reset --hard
si vous ne comprenez pas à 100% comment cela fonctionne, mieux vaut ne pas l'utiliser.la source