2012-07-09 19 views
7

Estamos ejecutando un repositorio git central (gforge) que todos extraen y presiona. Desafortunadamente, algunos compañeros de trabajo ineptos han decidido empujar varios archivos jar de 10-100Mb en el repositorio era una buena idea. Como consecuencia de esto, nuestro servidor que usamos mucho se ha quedado sin espacio en disco.Eliminar commits grandes de git

Solo nos dimos cuenta de esto cuando ya era demasiado tarde y la mayoría de la gente había sacado el nuevo gran repositorio. Si el problema no se hubiera solucionado, podríamos simplemente hacer una rebase para recortar esos grandes commits y solucionarlo, pero ahora todos han sacado de allí, ¿cuál es la mejor manera de eliminar esa confirmación (o hacer una rebase solo eliminar los archivos grandes) y luego tener este no causa caos cuando todo el mundo quiere tirar/empujar desde/hacia el repositorio?

Se supone que es una pequeña cesión temporal de guiones, pero es ahora de unos 700M de tamaño :-(

Respuesta

6

mira esto https://help.github.com/articles/remove-sensitive-data. Aquí se escriba sobre la eliminación de datos sensibles de su repositorio Git, pero se puede utilizar muy bien para la eliminación de los archivos de gran tamaño de sus confirmaciones.

+1

He leído esta guía con anterioridad, pero ¿qué sucede después de que he destruido las confirmaciones? La gente ya ha retirado el compromiso del monstruo. Lo que es probable que ocurra es que alguien haga un compromiso local y luego un empujón, se quejará de que necesita una fusión, por lo que se fusionarán y presionarán y la confirmación del monstruo volverá. ¿Cómo me aseguro de que esto no ocurra? (Enviarlos por correo electrónico para preguntar es poco probable que funcione) – agentgonzo

+0

Una vez que elimine los archivos que no desea, siempre se recomienda que los agregue al archivo .gitignore. De esa forma, Git dejará de rastrear esos archivos y evitará que se vuelva a presionar. –

+0

Sanhka, no impide que sean empujados, ya que evita que se comprometan. Entonces, como ya se han comprometido, un empujón los retrasaría. – agentgonzo

8

la forma más fácil de evitar el caos es dar el servidor más disco.

Esta es una pregunta difícil. la eliminación de los archivos requiere sacarlos de la historia, también, que solo se puede hacer con git filter-branch. Este comando, por ejemplo, wo ULD eliminar <file> de la historia:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch <file>' \ 
--prune-empty --tag-name-filter cat -- --all 

El problema es el siguiente reescribe SHA1 hashes, lo que significa que todo el equipo tendrá que restablecer a la nueva versión de la rama o el riesgo de algunos dolores de cabeza graves. Eso está bien y bien si nadie tiene trabajo en progreso y todos usan ramas de temas. Si estás más centralizado, tu equipo es grande o muchos de ellos mantienen directorios de trabajo sucios mientras trabajan, no hay forma de hacerlo sin un poco de caos y discordia. Podría pasar bastante tiempo haciendo que todos los locales trabajen correctamente. Eso escrito, git filter-branch es probablemente la mejor solución. Solo asegúrate de tener un plan, tu equipo lo comprende y asegúrate de hacer una copia de seguridad de sus repositorios locales en caso de que algún trabajo vital en progreso se pierda o se lo mate.

Uno de los planes posible sería:

  1. a que el equipo para generar parches de su trabajo en progreso, algo así como git diff > ~/my_wip.
  2. Haga que el equipo genere parches para su trabajo comprometido pero no compartido: git format-patch <branch>
  3. Ejecute git filter-branch. Asegúrese de que el equipo sepa que no debe tirar mientras esto está sucediendo.
  4. Solicite al equipo que emita git fetch && git reset --hard origin/<branch> o haga que vuelvan a clonar el depósito.
  5. Aplicar su trabajo previamente comprometido con git am <patch>.
  6. Aplicar su trabajo en progreso con git apply, p. git apply ~/my_wip.
+0

Darle al servidor más espacio en disco no es realmente una solución ideal, ya que las personas que trabajan desde casa aún tendrán que extraer varios cientos de MB a través de su conexión de banda ancha cuando deberían ser varios cientos de KB. Puede que tenga que hacer una filial y enviar un correo electrónico masivo que diga "tus cosas fallarán: esconde tus cambios locales, exporta como parches y luego borra tu repositorio local" y reprende " – agentgonzo

+0

Sí, miré hacia abajo un problema similar al esto hace unos meses. Tu idea es más o menos exactamente lo que hice, excepto que mis compañeros de trabajo estaban un poco asustadizos con los parches. Terminé haciéndolo por ellos. Tomó una tarde. Edité la respuesta para incorporar su plan, y agregué algunos comandos en caso de que alguien se topa con esto más tarde. – Christopher

4

Además de las otras respuestas, es posible que desee considerar la adición de algún tipo de protección preventiva contra futuros archivos jar gigantes, en forma de un pre-recibir el gancho en el repositorio que prohíbe a los usuarios (o por lo menos " usuarios no administradores ") al presionar archivos muy grandes, o archivos llamados *.jar, o lo que parezca mejor.

Hemos hecho este tipo de cosas antes, incluyendo la prohibición de identificaciones de confirmación específicas debido a ciertos usuarios que simplemente no podían entender cómo "guardar su trabajo en una rama temporal, restablecer y extraer, y volver a aplicar su trabajo, menos el archivo gigante ".

Tenga en cuenta que el gancho de pre-recepción se ejecuta en un contexto bastante interesante: los archivos han sido cargados, es solo que las referencias (generalmente cabezas de ramas) no han cambiado todavía. Puede evitar que los cabezales de bifurcación cambien, pero aún estará utilizando (temporalmente, hasta gc'ed) espacio en disco y ancho de banda de red.

0

Use filter-branch!

git filter-branch --tree-filter 'find . -name "*.jar" -exec rm {} \;' 

A continuación, sólo purgar todas las confirmaciones que no tienen ningún archivo en ellos con:

git filter-branch -f --prune-empty -- --all 
+0

'--index-filter' puede hacer básicamente lo mismo que' --tree-filter', pero más rápido. –

-1

GForge tipo aquí. Incluso considera que es principalmente una cuestión de git, me gustaría ofrecer dos cosas:

  1. Starting in GForge 6.3, los administradores del sitio pueden identificar los proyectos que ocupan demasiada disco, así como los proyectos antiguos y huérfanos. Esto puede ayudarlo a evitar situaciones de disco completo, especialmente si tiene muchos equipos y proyectos por separado.
  2. La implementación de ganchos git (ganchos SCM en general) es fácil de hacer en GForge. Los administradores del sitio pueden configurar cualquier número de comandos de enlace, y las personas a nivel de proyecto pueden luego seleccionar qué enlaces desean para su proyecto. Agregar un gancho que impide ciertos tipos (o tamaños) de archivos sería una buena opción para esta función.
Cuestiones relacionadas