Je me sens comme un enfant dans le bureau du directeur expliquant que le chien a mangé mes devoirs la veille de l’échéance, mais je suis en train de regarder un bug de perte de données insensé et je ne peux pas comprendre comment cela s’est passé. Je voudrais savoir comment git pourrait manger mon référentiel entier! J'ai déjà passé plusieurs fois le git à l'essoreuse et elle n'a jamais clignoté. Je l'ai utilisé pour scinder un repo Subversion de 20 gigaoctets en 27 dépôts de git et filtrer le foo par filtrage pour démêler le désordre et il n'a jamais perdu un octet sur moi. Le reflog est toujours là pour se replier. Cette fois, le tapis est parti!
De mon point de vue, tout ce que j'ai fait est exécuté git pull
et cela a détruit tout mon référentiel local. Je ne veux pas dire que "foiré la version extraite" ou "la branche sur laquelle j'étais" ou quelque chose comme ça. Je veux dire que tout est parti .
Voici une capture d'écran de mon terminal lors de l'incident:
Laisse-moi te guider à travers ça. Mon invite de commande inclut des données sur le référentiel git actuel (à l'aide de l'implémentation vcs_info de prezto) afin que vous puissiez voir quand le référentiel git a disparu. La première commande est assez normale:
» caleb » jaguar » ~/p/w/incil.info » ◼ zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Là, vous voyez que j'étais sur la branche 'zend' et que j'ai vérifié master. Jusqu'ici tout va bien. Vous verrez dans l'invite précédant ma prochaine commande qu'il a basculé avec succès:
» caleb » jaguar » ~/p/w/incil.info » ◼ master ★ »
❯❯❯ git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
+ 7412a21...eca4d26 master -> origin/master (forced update)
f03fa5d..c8ea00b devel -> origin/devel
+ 2af282c...009b8ec verse-spinner -> origin/verse-spinner (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s
Et juste comme ça, c'est parti. Le marqueur de temps écoulé est émis avant l'invite suivante si plus de 10 secondes se sont écoulées. Git n'a donné aucun résultat au-delà de la notification qu'il était en train de revenir en arrière. Aucune indication que ce soit fini.
L'invite suivante ne contient aucune donnée sur la branche sur laquelle nous nous trouvons ni sur l'état de git.
Ne remarquant pas que cela avait échoué, j'ai inconsciemment essayé de lancer une autre commande git pour me faire dire que je n'étais pas dans un dépôt git. Notez que la PWD n'a pas changé:
» caleb » jaguar » ~/p/w/incil.info »
❯❯❯ git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Après cela, un coup d’œil a montré que j’étais dans un répertoire complètement vide. Rien. Aucun répertoire '.git', rien. Vide.
Mon git local est à la version 2.0.2. Voici quelques informations de ma config git susceptibles de nous aider à comprendre ce qui s'est passé:
[branch]
autosetuprebase = always
rebase = preserve
[pull]
rebase = true
[rebase]
autosquash = true
autostash = true
[alias]
co = checkout
Par exemple, j'ai git pull
défini de toujours effectuer une refonte au lieu d'une fusion, de sorte qu'une partie de la sortie ci-dessus est normale.
Je peux récupérer les données. Je ne pense pas qu'il y avait d'autres objets git que des cachettes sans importance qui n'avaient pas été placées dans un dépôt, mais j'aimerais savoir ce qui s'est passé .
J'ai vérifié pour:
- Messages dans dmesg ou dans le journal systemd. Rien, même à distance pertinente.
- Il n'y a aucune indication de défaillance du lecteur ou du système de fichiers (LVM + LUKS + EXT4 semblent tous normaux). Il n'y a rien dans perdu + trouvé.
- Je n'ai rien couru d'autre. Il n'y a rien dans l'historique que je ne montre pas ci-dessus, et aucun autre terminal n'a été utilisé pendant cette période. Il n'y a pas de
rm
commande flottante qui aurait pu être exécutée dans le mauvais CWD, etc. - Piquer sur un autre dépôt git dans un autre répertoire ne montre aucune anomalie apparente lors de l'exécution de
git pull
s.
Que devrais-je chercher ici?
la source
.git
n'existe pas. Rien ne se passe - ce qui était auparavant le répertoire racine de git n'a rien du tout.Réponses:
Oui,
git
j'ai mangé mes devoirs. Tout.J'ai créé une
dd
image de ce disque après l'incident et l'ai bousillé plus tard. En reconstruisant la série d’événements à partir de journaux système, j’en déduisais que ce qui s’était passé ressemblait à ceci:pacman -Syu
) avait été émise quelques jours avant cet incident.git checkout
et avant legit pull
.git
binaire a été remplacé après legit pull
début et avant la fin.git
reposé de tous ses travaux. Et supprimé le monde afin que tous les autres devaient se reposer aussi.Je ne sais pas exactement quelle condition de concurrence a provoqué cette situation, mais échanger des fichiers binaires au milieu d'une opération n'est certainement pas agréable, ni une condition vérifiable / répétable. Habituellement, une copie d'un fichier binaire en cours d'exécution est stockée dans la mémoire, mais elle
git
est bizarre et présente un aspect de la façon dont elle reproduit des versions d'elle-même. Je suis sûre qu'elle a conduit à ce désordre. Évidemment, cela aurait dû mourir plutôt que de tout détruire, mais c'est ce qui s'est passé.la source
git-fetch
,git-rebase
ougit-merge
etgit gc
Peut-être en ne définissant pas le chemin du fichier à supprimer.
Votre cas m'a rappelé un beau jour lorsque ma
remove(path)
méthode maison a essayé de supprimer le dossier racine car le paramètre donné était une chaîne vide que le système d'exploitation a corrigée (!) En tant que dossier racine.Cela peut être un bug similaire à Git. Tel que:
remove(project_folder + file_path)
(pseudo-code)file_path
vide à l’époque.remove(project_folder)
la source
Avec de la chance, vous pouvez résoudre ce problème avec la commande suivante:
Lorsque des changements potentiellement dangereux commencent, git bloque votre état actuel dans ORIG_HEAD. Avec cela, vous pouvez annuler une fusion ou une rebase.
Manuel Git: Annulation d'une fusion
la source
On dirait que quelqu'un a couru
git push --force
sur ce dépôt et vous avez annulé ces changements. Essayez de cloner le repo frais, cela devrait vous ramener à l'état de travail propre.la source
.git
répertoire de quelqu'un avec une poussée forcée