¿Cuáles son los límites de archivo en Git (número y tamaño)?

175

¿Alguien sabe cuáles son los límites de Git para el número de archivos y el tamaño de los archivos?

Alexandre Rademaker
fuente
En Windows, el tamaño máximo de archivo es de 4 GB (a partir de julio de 2020), debido a un error: github.com/git-for-windows/git/issues/1063
cowlinator hace

Respuestas:

161

Este mensaje del propio Linus puede ayudarte con otros límites.

[...] CVS, es decir, termina realmente orientado a un modelo de "un archivo a la vez".

Lo cual es bueno, ya que puede tener un millón de archivos, y luego ver solo algunos de ellos; nunca verá el impacto de los otros 999,995 archivos.

Git fundamentalmente nunca mira menos que todo el repositorio. Incluso si limita un poco las cosas (es decir, revise solo una parte, o haga que la historia retroceda solo un poco), git termina siempre preocupándose por todo el asunto y transmitiendo el conocimiento.

Entonces git escala realmente mal si lo obligas a mirar todo como un gran repositorio. No creo que esa parte sea realmente reparable, aunque probablemente podamos mejorarla.

Y sí, luego están los problemas del "gran archivo". Realmente no sé qué hacer con los archivos grandes. Los apestamos, lo sé.

Vea más en mi otra respuesta : el límite con Git es que cada repositorio debe representar un " conjunto coherente de archivos ", el "todo el sistema" en sí mismo (no puede etiquetar "parte de un repositorio").
Si su sistema está hecho de partes autónomas (pero interdependientes), debe usar submódulos .

Como lo ilustra la respuesta de Talljoe , el límite puede ser uno del sistema (gran cantidad de archivos), pero si comprende la naturaleza de Git (sobre la coherencia de datos representada por sus claves SHA-1), se dará cuenta del verdadero "límite" es uno de uso : es decir, no debe intentar almacenar todo en un repositorio de Git, a menos que esté preparado para recuperar o etiquetar siempre todo. Para algunos proyectos grandes, no tendría sentido.


Para una visión más profunda de los límites de git, consulte " git con archivos grandes "
(que menciona git-lfs : una solución para almacenar archivos grandes fuera del repositorio de git. GitHub, abril de 2015)

Los tres problemas que limitan un repositorio git:

  • archivos de gran tamaño ( xdelta para packfile está solo en memoria, lo que no es bueno con archivos de gran tamaño)
  • gran cantidad de archivos , lo que significa, un archivo por blob, y git gc lento para generar un paquete a la vez.
  • grandes paquetes de archivos , con un índice de paquete ineficiente para recuperar datos del (enorme) paquete de archivos.

Un hilo más reciente (febrero de 2015) ilustra los factores limitantes para un repositorio de Git :

¿Algunos clones simultáneos del servidor central también ralentizarán otras operaciones concurrentes para otros usuarios?

No hay bloqueos en el servidor cuando se clona, ​​por lo que, en teoría, la clonación no afecta a otras operaciones. Sin embargo, la clonación puede usar mucha memoria (y mucha CPU a menos que active la función de mapa de bits de accesibilidad, que debería).

¿ git pullSerá lento?

Si excluimos el lado del servidor, el tamaño de su árbol es el factor principal , pero sus archivos de 25k deberían estar bien (Linux tiene 48k archivos).

' git push'?

Este no se ve afectado por la profundidad de la historia de su repositorio ni por el ancho de su árbol, por lo que debe ser rápido.

Ah, el número de referencias puede afectar a ambos git-pushy git-pull.
Creo que Stefan sabe mejor que yo en esta área.

' git commit'? (Está listado como lento en la referencia 3 ) git status. (Slow nuevo en referencia 3 aunque no veo.)
(También git-add)

De nuevo, el tamaño de tu árbol. Al tamaño de su repositorio, no creo que deba preocuparse por eso.

Puede parecer que algunas operaciones no son cotidianas, pero si el front-end web las llama con frecuencia a GitLab / Stash / GitHub, etc., pueden convertirse en cuellos de botella. (por ejemplo, ' git branch --contains' parece terriblemente afectado negativamente por un gran número de ramas).

git-blame podría ser lento cuando un archivo se modifica mucho.

VonC
fuente
44
@ Thr4wn: consulte también stackoverflow.com/questions/1979167/git-submodule-update/… para obtener más información sobre la página de submódulos de GitPro. Para una versión más corta: stackoverflow.com/questions/2065559/…
VonC
1
Enlace actualizado para la documentación de git submoules = git-scm.com/book/en/Git-Tools-Submodules
JHowIX
Realmente me pregunto, con tanta sqlite y muchas alternativas de bases de datos disponibles en Linux, por qué no podrían simplemente usar una base de datos que es fácil de respaldar, replicar y escalar.
Akash Kava
"git escala realmente mal si lo obligas a mirar todo como un gran depósito" ¿qué dice esto sobre la escalabilidad de los monorepos?
Ephemer
@ephemer Lo que se dice es ... que la cita es de hace 10 años. Desde entonces, en 2017, Microsoft tiene su propio monorepo ( devblogs.microsoft.com/bharry/… : 300GB +) y las mejoras aún están por llegar en 2019: stackoverflow.com/a/57129687/6309
VonC
36

No hay límite real: todo se nombra con un nombre de 160 bits. El tamaño del archivo debe ser representable en un número de 64 bits para que tampoco haya un límite real.

Sin embargo, hay un límite práctico. Tengo un repositorio de ~ 8GB con> 880,000 archivos y git gc lleva un tiempo. El árbol de trabajo es bastante grande, por lo que las operaciones que inspeccionan todo el directorio de trabajo llevan bastante tiempo. Sin embargo, este repositorio solo se usa para el almacenamiento de datos, por lo que son solo un montón de herramientas automatizadas las que lo manejan. Sacar los cambios del repositorio es mucho, mucho más rápido que sincronizar los mismos datos.

%find . -type f | wc -l
791887
%time git add .
git add .  6.48s user 13.53s system 55% cpu 36.121 total
%time git status
# On branch master
nothing to commit (working directory clean)
git status  0.00s user 0.01s system 0% cpu 47.169 total
%du -sh .
29G     .
%cd .git
%du -sh .
7.9G    .
Talljoe
fuente
2
Aunque hay una respuesta "más correcta" arriba hablando de las limitaciones teóricas, esta respuesta me parece más útil ya que permite comparar la propia situación con la suya. Gracias.
Bananeweizen
1
Muy interesante. ¿Cómo es posible que la copia de trabajo sea más grande que el .gitdirectorio? Mi ingenua suposición fue que .gitcontiene una copia del directorio de trabajo más el historial, por lo que debe ser más grande. ¿Alguien puede señalarme un recurso que comprenda cómo se relacionan estos tamaños?
bluenote10
1
@ bluenote10 El contenido del .gitdirectorio está comprimido. Por lo tanto, es probable que un repositorio con relativamente pocas confirmaciones tenga un historial comprimido más pequeño que el directorio de trabajo sin comprimir. Mi experiencia muestra que, en la práctica, con el código C ++, el historial completo suele ser aproximadamente del mismo tamaño que el directorio de trabajo.
prapin
28

Si agrega archivos que son demasiado grandes (GB en mi caso, Cygwin, XP, 3 GB de RAM), espere esto.

fatal: sin memoria, malloc falló

Más detalles aquí

Actualización 3/2/11: Vi similar en Windows 7 x64 con Tortoise Git. Toneladas de memoria utilizadas, respuesta del sistema muy muy lenta.

Brian Carlton
fuente
17

En febrero de 2012, había un hilo muy interesante en la lista de correo de Git de Joshua Redstone, un ingeniero de software de Facebook que probaba a Git en un enorme repositorio de pruebas:

El repositorio de prueba tiene 4 millones de confirmaciones, historial lineal y aproximadamente 1.3 millones de archivos.

Las pruebas que se ejecutaron muestran que, para tal repositorio, Git no se puede usar (la operación en frío dura minutos), pero esto puede cambiar en el futuro. Básicamente, el rendimiento se ve penalizado por la cantidad de stat()llamadas al módulo FS del núcleo, por lo que dependerá de la cantidad de archivos en el repositorio y la eficiencia del almacenamiento en caché de FS. Vea también este Gist para más discusión.

CharlesB
fuente
2
+1 Interesante. Eso se hace eco de mis propias respuestas sobre los límites de git que detallan las limitaciones en archivos enormes / número de archivos / paquetes.
VonC
2

Depende de cuál sea tu significado. Hay límites de tamaño prácticos (si tiene muchos archivos grandes, puede ser aburrido). Si tiene muchos archivos, los escaneos también pueden ser lentos.

Sin embargo, no hay límites inherentes al modelo. Ciertamente puedes usarlo mal y ser miserable.

Dustin
fuente
1

Creo que es bueno tratar de evitar confirmaciones de archivos grandes como parte del repositorio (por ejemplo, un volcado de la base de datos podría ser mejor en otro lugar), pero si uno considera el tamaño del núcleo en su repositorio, probablemente pueda esperar trabajar cómodamente con algo más pequeño y menos complejo que eso.

Kzqai
fuente
1

Tengo una cantidad generosa de datos almacenados en mi repositorio como fragmentos JSON individuales. Hay alrededor de 75,000 archivos en algunos directorios y no es realmente perjudicial para el rendimiento.

Revisarlos la primera vez fue, obviamente, un poco lento.

divertirse
fuente
1

Encontré esto tratando de almacenar una gran cantidad de archivos (350k +) en un repositorio. Si, tienda. Risas

$ time git add . 
git add . 333.67s user 244.26s system 14% cpu 1:06:48.63 total

Los siguientes extractos de la documentación de Bitbucket son bastante interesantes.

Cuando trabaja con un repositorio de DVCS clonando, empujando, está trabajando con todo el repositorio y toda su historia. En la práctica, una vez que su repositorio supera los 500 MB, puede comenzar a ver problemas.

... 94% de los clientes de Bitbucket tienen repositorios de menos de 500 MB. Tanto el kernel de Linux como Android tienen menos de 900 MB.

La solución recomendada en esa página es dividir su proyecto en trozos más pequeños.

Kasisnu
fuente
Supongo que esto está bastante desactualizado. En este momento, parece que no hay nada sobre el repositorio de Android (ni Linux) en el sitio al que se está vinculando. Pero me pregunto si no fue inexacto incluso en ese entonces. Por ejemplo, compara esta respuesta . ¿Quizás querían decir algo más?
jjj