¿Qué puede causar la pérdida de datos en git?

No quiero tener que dar vueltas en git, me gustaría "moverme rápido y romper cosas" como dicen en FaceBook. En realidad, ese es casi todo el punto del Control de versiones, creo. ¿De qué necesito realmente tener cuidado?

Supongo que git rm, especialmente con -r puede ser peligroso.

¿Qué pasa cuando se bifurca, qué conduce a sobreescribir?

En general, es muy difícil causar pérdida de datos en git. Git casi nunca borra realmente nada que haya sido registrado en el repository, incluso cuando ejecuta commands que eliminan confirmaciones del historial o borran twigs.

De lo único que realmente tienes que preocuparte es de los commands que eliminan los files que no se han registrado en git. En general, git requerirá los indicadores --force ( -f ) o --hard para esos commands.

Aquí hay una list rápida de commands potencialmente peligrosos y de qué preocuparse cuando los usa:

Puede eliminar permanentemente datos no comprometidos con git:

  • git rm -f : puede eliminar files que aún no ha marcado
  • git reset --hard – Eliminará los cambios que aún no se han registrado en git
  • git clean -f – Eliminará files no rastreados por git
  • git checkout /path/to/file – Puede revertir cambios que no están registrados en git
  • git checkout <rev> -f – Puede sobrescribir cambios que no están registrados en git
  • rm -rf .git – ¡No elimine su directory .git ! Eso es lo que almacena toda tu historia local.

Puede eliminar datos en repositorys remotos (reversible, pero es posible que no tenga el nivel de acceso necesario para recuperar confirmaciones en repositorys remotos):

  • git push -f – Elimina el historial de las sucursales en repositorys remotos
  • git push <remote> :<branch> -O- git push <remote> --delete <branch> – Elimina twigs remotas

Puede eliminar permanentemente los datos ya eliminados que de otro modo serían recuperables (similar a vaciar la basura en su sistema operativo):

  • git prunegit prune permanentemente las confirmaciones que no son accesibles desde ninguna twig
  • git gcgit gc permanentemente los commits antiguos que no son accesibles desde ninguna twig

Puede eliminar confirmaciones locales (son bastante fáciles de recuperar):

  • git reset <revision> – Puede eliminar el historial de una twig (aunque es localmente recuperable por aproximadamente dos semanas más o less, a less que ejecute git prune )
  • git branch -D <branch> – Elimina una twig que aún no se ha fusionado (recuperable localmente)
  • git branch -f <branch> <rev> – Puede eliminar el historial de una twig (recuperable localmente)

Lo más importante para aprender git fue comprometerme temprano y comprometerme a menudo. Si tiene un logging de sus cambios en el control de versiones, hay una manera de restaurarlo si lo arruina. Tuve muchos momentos en el último año en los que pensé que perdí datos, pero search en Stack Overflow me enseñó algunos trucos. Mantenga sus datos alojados en un server remoto (como GitHub o BitBucket), de modo que si destruye completamente su repository, todavía está en algún lugar. Si haces una git branch -D <branch> y borras una twig, todas las confirmaciones en esa twig se eliminarán del repository.

De lo único que puedo advertirte es que nunca reescribas la historia si no sabes exactamente lo que estás haciendo. Las cosas que pueden hacer esto son git-reset y git-rebase . Nunca haga un git push <remote> <branch> -f less que sepa lo que está haciendo, ya que eso forzará a sobrescribir todas las confirmaciones con su repository local. Si ha cambiado el historial de sucursales localmente o si alguien más ha contribuido al repository, esto podría causar problemas importantes.

@meager también hizo una buena observación: si elimina un file que aún no ha sido rastreado / confirmado por git, no tendrá forma de recuperarlo.

Como nota al margen, no tengas miedo de usar git-reset y git-rebase , solo necesitan ser utilizados correctamente. Por ejemplo, a veces uso git-reset para restablecer mi tree de trabajo a la última confirmación (deshacer todos los files modificados) con git reset --hard HEAD o para deshacer el último post de confirmación mientras git reset --soft HEAD^ mi tree de trabajo git reset --soft HEAD^ . La rebase de Git también puede ser útil para aplastar / reescribir múltiples confirmaciones en tu historial. Solo tenga en count que estos methods pueden conducir a la pérdida de datos, y no debe hacerlos si ya ha enviado a un repository remoto (desde entonces tendrá que hacer un git push -f .

git rm no es tan peligroso ya que puedes recuperar tus files después de una confirmación previa.

Como regla general, cuide la opción -f : obliga a Git a hacer algo que no quiere hacer. (ej: branch -f o push -f )

Dependiendo de lo que creas que Git puede o no estar rastreando, Git puede "perder" todo tipo de información que podrías esperar que contenga. Las twigs y las tags se pueden perder fácilmente en la reproducción aleatoria si no se tiene una buena comprensión de las partes internas de Git o cómo se diferencia de otros sistemas.

Vea Cómo usar git para perder datos

Como consejo útil, si crees que has eliminado twigs, tags anotadas o restablecido a una confirmación anterior, no las has perdido, tus cambios locales están todos grabados y puedes verlos con git reflog .

Es interesante mirarlo solo para ver lo que registra.

Enumera los commit shas que puede usar para restaurar twigs a ese estado.

Ninguna de las anteriores. Es muy difícil causar pérdida de datos en Git . Dataloss sucede fuera de Git, cuando elimina files que aún no están rastreando. Cualquier "pérdida de datos" percibida que ocurra dentro de Git es recuperable, siempre que intente recuperarse antes de que ocurra la recolección de basura, que es una window de semanas .

Comience sus cambios con frecuencia, en pequeños pasos. No se preocupe por producir buenos posts de compromiso o un bonito DAG ; Vas a aplastar todo eso antes de fusionar tu twig de características de todos modos. Hasta que hayas cometido tu trabajo, ese trabajo está en peligro de perderse.

Existe un riesgo cuando resuelves conflictos de forma incorrecta: en eclipse tuvimos un problema, al resolver un conflicto de un file. a.txt fue reclamado por conflicto, mientras que b.txt fue retirado / extraído y se muestra en el índice. Si un usuario ahora quita el file b.txt del índice a unstaged – y solo agrega su a.txt resuelto, y confirma y empuja – el commit tendrá el estado de b.txt del commit de los padres de los usuarios – ya no el versión que habría buscado. EL PROBLEMA es que este cambio no se mostrará; el file no figura en la confirmación. No puedes descubrir este problema directamente. (Solo si comtesting el contenido del file, en el caso de un binary, solo puede verificar el BLOB.) Un poco de esfuerzo, necesita dos usuarios, dos repositorys + uno desnudo y dos files. Descubrimos esto en eclipse / egit, no estoy seguro de si también es un problema de la console. Puede verificar los blobs con git ls-tree <commit>

Como meagar, dijo que git rm es una eliminación grabada en una nueva confirmación, por lo que es recuperable y se puede usar sin temor.

git reset --hard puede ser especialmente dañino ya que restablece el "commit actual" ( HEAD en la jerga de Git) a otro. Entonces, si el HEAD anterior no fue referido en una twig o label, prácticamente se pierde (al less sin hechicería). También causa que sus cambios no confirmados se pierdan.

Lo mismo ocurre con la eliminación de la twig y la label: puede hacer que una línea de confirmaciones sea eliminada del repository. En esos casos, donde los commits están ocultos en el repository, puedes recuperarlos pero es técnico y no es muy fácil, así que es mejor que sepas lo que estás haciendo.

Como en cualquier otra situación donde sus datos son preciosos (y el código fuente lo es), es altamente deseable tener un espejo de su repository y presionarlo regularmente. Puede ser otro repository local, un repository privado de GitHub, o simplemente la copy de security de su repository utilizando su sistema de respaldo actual. De esta manera, siempre puedes recuperar cosas.

Como dicen otros aquí, ten cuidado con los files sin seguimiento que son realmente importantes. Los files sin seguimiento / ignorados deben ser solo los que se generan a partir de los files bajo control de versión: ejecutables y demás.