Me siento como un niño en la oficina del director explicando que el perro se comió mi tarea la noche antes de la fecha de vencimiento, pero estoy mirando un error de pérdida de datos en la cara y no puedo entender cómo sucedió. ¡Me gustaría saber cómo git podría comer todo mi repositorio! He puesto git a través del escurridor muchas veces y nunca parpadea. Lo usé para dividir un repositorio de 20 Gig Subversion en 27 repositorios de git y filté el foo fuera de ellos para desenredar el desastre y nunca me perdió un byte. El reflog siempre está ahí para recurrir. ¡Esta vez la alfombra se ha ido!
Desde mi punto de vista, todo lo que hice fue ejecutar git pull
y destruyó todo mi repositorio local. No quiero decir que "estropeó la versión extraída" o "la rama en la que estaba" ni nada de eso. Quiero decir que todo se fue .
Aquí hay una captura de pantalla de mi terminal en el incidente:
Déjame guiarte a través de eso. Mi símbolo del sistema incluye datos sobre el repositorio git actual (usando la implementación vcs_info de prezto) para que pueda ver cuándo desapareció el repositorio git. El primer comando es lo suficientemente normal:
» caleb » jaguar » ~/p/w/incil.info » ◼ zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Allí puedes ver que estaba en la rama 'zend', y comprobé el maestro. Hasta aquí todo bien. Verá en el indicador antes de mi próximo comando que cambió de rama con éxito:
» 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
Y así como así se fue. El marcador de tiempo transcurrido sale antes del siguiente mensaje si han transcurrido más de 10 segundos. Git no dio ningún resultado más allá del aviso de que se estaba rebobinando para reproducir. No hay indicios de que haya terminado.
El siguiente mensaje no incluye datos sobre en qué rama estamos o el estado de git.
Sin darme cuenta de que había fallado, intenté ejecutar inconscientemente otro comando git solo para decirme que no estaba en un repositorio git. Tenga en cuenta que el PWD no ha cambiado:
» 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).
Después de esto, un vistazo mostró que estaba en un directorio completamente vacío. Nada. No hay directorio '.git', nada. Vacío.
Mi git local está en la versión 2.0.2. Aquí hay un par de cositas de mi configuración de git que podrían ser relevantes para entender lo que sucedió:
[branch]
autosetuprebase = always
rebase = preserve
[pull]
rebase = true
[rebase]
autosquash = true
autostash = true
[alias]
co = checkout
Por ejemplo, he git pull
configurado hacer siempre un rebase en lugar de una fusión, de modo que parte de la salida anterior sea normal.
Puedo recuperar los datos. No creo que haya ningún objeto git que no sea un alijo sin importancia que no haya sido empujado a otros repositorios, pero me gustaría saber qué sucedió .
He verificado por:
- Mensajes en dmesg o el diario systemd. Nada ni remotamente relevante.
- No hay indicios de falla de la unidad o del sistema de archivos (LVM + LUKS + EXT4 parecen normales). No hay nada en perdido + encontrado.
- No corrí nada más. No hay nada en la historia que no esté mostrando arriba, y no se usaron otras terminales durante este tiempo. No hay
rm
comandos flotando que puedan haberse ejecutado en el CWD incorrecto, etc. - Poking en otro repositorio de git en otro directorio no muestra ninguna anormalidad aparente en la ejecución de
git pull
s.
¿Qué más debería estar buscando aquí?
fuente
.git
no no existe. Nada funciona: lo que solía ser el directorio raíz de git no tiene nada en absoluto.Respuestas:
Sí,
git
comí mi tarea. Todo ello.Hice una
dd
imagen de este disco después del incidente y lo jugué más tarde. Al reconstruir la serie de eventos a partir de los registros del sistema, deduzco que lo que sucedió fue algo como esto:pacman -Syu
había emitido un comando de actualización del sistema ( ) días antes de este incidente.git checkout
y antes delgit pull
.git
binario se reemplazó después delgit pull
inicio y antes de que terminara.git
descansó de todas sus labores. Y borró el mundo para que todos los demás tuvieran que descansar también.No sé exactamente qué condición de carrera ocurrió que hizo que esto sucediera, pero intercambiar binarios en medio de una operación ciertamente no es agradable ni una condición comprobable / repetible. Por lo general, una copia de un binario en ejecución se almacena en la memoria, pero
git
es extraño y algo sobre la forma en que vuelve a generar versiones de sí mismo, estoy seguro de que condujo a este desastre. Obviamente debería haber muerto en lugar de destruir todo, pero eso fue lo que sucedió.fuente
git-fetch
,git-rebase
ogit-merge
ygit gc
Posiblemente al no definir la ruta del archivo que se va a eliminar.
Su caso me recordó un hermoso día cuando mi
remove(path)
método casero intentó eliminar la carpeta raíz porque el parámetro dado era una cadena vacía que el sistema operativo corrigió (!) Como la carpeta raíz.Esto puede ser un error git similar. Tal que:
remove(project_folder + file_path)
(pseudocódigo)file_path
estaba vacío en ese momento.remove(project_folder)
fuente
Con suerte, puede solucionar esto con el siguiente comando:
Cuando comienzan los posibles cambios peligrosos, git oculta su estado actual en ORIG_HEAD. Con él puedes deshacer una fusión o un rebase.
Manual de Git: Deshacer una fusión
fuente
Parece que alguien corrió
git push --force
en este repositorio, y usted eliminó esos cambios. Intente clonar el repositorio fresco, eso debería volver a ponerlo en un estado de trabajo limpio nuevamente.fuente
.git
directorio de alguien con un empuje forzado