Question

J'essaye de récupérer mon travail.J'ai bêtement fait git reset --hard, mais avant cela, je n'ai fait que get add . et je n'ai pas fait git commit.Veuillez aider!Voici mon journal:

MacBookPro:api user$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)

#   modified:   .gitignore
...


MacBookPro:api user$ git reset --hard
HEAD is now at ff546fa added new strucuture for api

Est-il possible d'annuler git reset --hard dans cette situation?

Était-ce utile?

La solution

Vous devriez pouvoir récupérer tous les fichiers que vous avez ajoutés à l'index (par exemple, comme dans votre situation, avec git add .) bien que cela puisse être un peu de travail. Afin d'ajouter un fichier à l'index, git l'ajoute à la base de données d'objets, ce qui signifie qu'il peut être récupéré tant que le garbage collection n'a pas encore eu lieu. Vous trouverez un exemple de procédure à suivre dans La réponse de Jakub Narębski ici:

Cependant, j'ai essayé cela sur un référentiel de test, et il y a eu quelques problèmes - --cached devrait être --cache, et j'ai trouvé qu'il ne créait pas réellement le répertoire .git/lost-found. Cependant, les étapes suivantes ont fonctionné pour moi:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")

Cela devrait afficher tous les objets de la base de données d'objets qui ne sont accessibles par aucune référence, dans l'index ou via le reflog. Le résultat ressemblera à ceci:

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03

... et pour chacun de ces blobs, vous pouvez faire:

git show 907b308

Pour afficher le contenu du fichier.


Trop de sortie?

Mise à jour en réponse au voir le commentaire de ci-dessous:

Si vous constatez que de nombreux commits et arborescences sont répertoriés dans la sortie de cette commande, vous pouvez supprimer de la sortie tous les objets référencés à partir de validations non référencées. (En général, vous pouvez revenir à ces commits via le reflog de toute façon - nous sommes simplement intéressés par les objets qui ont été ajoutés à l'index mais qui ne peuvent jamais être trouvés via un commit.)

Tout d'abord, enregistrez la sortie de la commande, avec:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all

Les noms d'objet de ces commits inaccessibles peuvent maintenant être trouvés avec:

egrep commit all | cut -d ' ' -f 3

Vous pouvez donc trouver uniquement les arbres et objets qui ont été ajoutés à l'index, mais qui ne sont validés à aucun moment, avec:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
  $(egrep commit all | cut -d ' ' -f 3)

Cela réduit énormément le nombre d'objets que vous devrez prendre en compte.


Mise à jour: Philip Oakley ci-dessous suggère une autre façon de réduire le nombre de objets à prendre en compte, qui consiste simplement à considérer les fichiers les plus récemment modifiés sous .git/objects. Vous pouvez les trouver avec:

find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

(J'ai trouvé cet appel de find ici .) La fin de cette liste pourrait sembler comme:

2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a

Dans ce cas, vous pouvez voir ces objets avec:

git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a

(Notez que vous devez supprimer le / à la fin du chemin pour obtenir le nom de l'objet.)

Autres conseils

Je viens de faire une réinitialisation git --hard et j'ai perdu un commit.Mais je connaissais le hachage de commit, donc j'ai pu faire git cherry-pick COMMIT_HASH pour le restaurer.

Je l'ai fait quelques minutes après avoir perdu le commit, cela peut donc fonctionner pour certains d'entre vous.

Grâce à Mark Longair, j'ai récupéré mes affaires!

J'ai d'abord enregistré tous les hachages dans un fichier:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > allhashes

Ensuite, je les mets tous (en supprimant le "blob inaccessible") dans une liste et je mets les données dans de nouveaux fichiers ... vous devez choisir vos fichiers et les renommer à nouveau dont vous avez besoin ... mais moi seulementbesoin de quelques fichiers ... j'espère que cela aide quelqu'un ...

commits = ["c2520e04839c05505ef17f985a49ffd42809f",
    "41901be74651829d97f29934f190055ae4e93",
    "50f078c937f07b508a1a73d3566a822927a57",
    "51077d43a3ed6333c8a3616412c9b3b0fb6d4",
    "56e290dc0aaa20e64702357b340d397213cb",
    "5b731d988cfb24500842ec5df84d3e1950c87",
    "9c438e09cf759bf84e109a2f0c18520",
    ...
    ]

from subprocess import call
filename = "file"
i = 1
for c in commits:
    f = open(filename + str(i),"wb")
    call(["git", "show", c],stdout=f)
    i+=1

La solution d'Ajedi32 dans les commentaires a fonctionné pour moi exactement dans cette situation.

git reset --hard @{1}

Notez que toutes ces solutions reposent sur l'absence de git gc, et certaines d'entre elles pourraient en causer un, donc je compresserais le contenu de votre répertoire .git avant d'essayer quoi que ce soit afin que vous ayez un instantané auquel revenirsi l'un ne fonctionne pas pour vous.

Ran dans le même problème, mais n'a pas ajouté les modifications à l'index.Donc, toutes les commandes ci-dessus ne m'ont pas apporté les modifications souhaitées.

En désespoir de cause, j'ai essayé d'appuyer sur CTRL-Z dans mon éditeur (LightTable), une fois dans chaque onglet ouvert - cela a heureusement récupéré le fichier dans cet onglet, à son dernier état avant le git reset --hard.HTH.

Mon Dieu, je me suis tiré les cheveux jusqu'à ce que je tombe sur cette question et ses réponses.Je pense que la réponse correcte et succincte à la question posée n'est disponible que si vous rassemblez deux des commentaires ci-dessus, donc ici, tout est au même endroit:

  1. Comme mentionné par chilicuil, lancez 'git reflog' pour y identifier le commit le hachage auquel vous souhaitez revenir

  2. Comme mentionné par akimsko, vous ne voudrez probablement PAS choisir à moins que vous n'ayez perdu qu'un seul commit, vous devriez donc lancer 'git reset - dur

Remarque pour les utilisateurs d'egit Eclipse: je n'ai pas trouvé de moyen de faire ces étapes dans Eclipse avec egit.Fermer Eclipse, exécuter les commandes ci-dessus à partir d'une fenêtre de terminal, puis rouvrir Eclipse a très bien fonctionné pour moi.

C'est probablement évident pour les professionnels git, mais je voulais le mettre en place car dans ma recherche effrénée, je n'ai pas vu cela évoqué.

J'ai mis en scène certains fichiers et j'ai fait une réinitialisation git --hard, j'ai un peu paniqué, puis j'ai remarqué que mon statut montrait tous mes fichiers toujours en cours ainsi que toutes leurs suppressions non mises en scène.

À ce stade, vous pouvez valider ces modifications par étapes, tant que vous ne procédez pas à leurs suppressions. Après cela, il vous suffit de trouver le courage de faire "git reset --hard" une fois de plus, ce qui vous ramènera aux changements que vous aviez mis en scène et que vous venez de valider.

Encore une fois, ce n'est probablement rien de nouveau pour la plupart, mais j'espère que puisque cela m'a aidé et que je n'ai rien trouvé suggérant cela, cela pourrait aider quelqu'un d'autre.

Les solutions ci-dessus peuvent fonctionner, cependant, il existe des moyens plus simples de récupérer ceci au lieu de passer par l'annulation complexe de git-s. Je suppose que le plus git-resets se produisent sur un petit nombre de fichiers, et si vous utilisez déjà VIM, cela pourrait être la solution la plus rapide. La mise en garde est que vous devez déjà utiliser ViM's persistent-undo, que vous devriez utiliser de toute façon, car il vous offre la possibilité d'annuler un nombre illimité de modifications.

Voici les étapes:

  1. Dans vim, appuyez sur : et tapez la commande set undodir. Si vous avez activé persistent undo dans votre .vimrc, il affichera un résultat similaire à undodir=~/.vim_runtime/temp_dirs/undodir.

  2. Dans votre dépôt, utilisez git log pour connaître la dernière date / heure de la dernière commettre

  3. Dans votre shell, accédez à votre code générique en utilisant undodir.

  4. Dans ce répertoire, utilisez cette commande pour trouver tous les fichiers que vous avez changé depuis le dernier commit

    cd ~/.vim_runtime/temp_dirs/undodir

    Ici "2018-03-20 11:24:44" est la date et l'heure du dernier commit. Si la la date à laquelle vous avez fait le find . -newermt "2018-03-20 11:24:44" \! -newermt "2018-03-23" \( -type f -regextype posix-extended -regex '.*' \) \-not -path "*/env/*" -not -path "*/.git/*" est "2018-03-22", puis utilisez "2018-03-22", puis utilisez "2018-03-23". C'est à cause d'une bizarrerie de trouver, où la limite inférieure est inclusive et la limite supérieure est exclusive. https://unix.stackexchange.com/a/70404/242983

  5. Ensuite, allez à chacun des fichiers, ouvrez-les dans vim, et faites un "20m plus tôt". Vous pouvez trouver plus de détails sur «plus tôt» en utilisant «h plus tôt». Ici git reset --hard signifie revenir à l'état du fichier 20 minutes en arrière, en supposant que vous ayez fait le earlier 20m, 20 minutes en arrière. Répétez ceci tous les fichiers crachés par la commande git hard --reset. je suis sûr quelqu'un peut écrire un script qui combinera ces choses.

J'utilise IntelliJ et j'ai pu simplement parcourir chaque fichier et faire:

Edit -> reload from disk

Heureusement, je venais de créer un git status juste avant d'effacer mes modifications de travail, donc je savais exactement ce que je devais recharger.

Se souvenir de votre hiérarchie de fichiers et utiliser la technique de Mark Longair avec la modification de Phil Oakley donne des résultats spectaculaires.

Essentiellement, si vous avez au moins ajouté les fichiers au référentiel mais que vous ne les avez pas validés, vous pouvez restaurer en utilisant de manière interactive 'git show', inspecter le journal et utiliser la redirection shell pour créer chaque fichier (en vous souvenant de votre chemin d'intérêt).

/ p>

HTH!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top