remove - ¿Cómo almacena git los archivos?
git tag commits (3)
Acabo de empezar a aprender git y para hacerlo empecé a leer el libro de comunidad de Git , y en este libro dicen que SVN y CVS almacenan la diferencia entre los archivos y que git almacena una instantánea de todos los archivos.
Pero realmente no entiendo lo que quieren decir con una instantánea. ¿Git realmente hace una copia de todos los archivos en cada confirmación porque eso es lo que entendí de su explicación?
PD: Si alguien tiene una mejor fuente para aprender git, lo agradecería.
Git almacena lógicamente cada archivo en su SHA1. Lo que esto significa es que si tiene dos archivos con exactamente el mismo contenido en un repositorio (o si cambia el nombre de un archivo), solo se almacena una copia.
Pero esto también significa que cuando modifica una pequeña parte de un archivo y confirma, se almacena otra copia del archivo. La forma en que git resuelve esto es usando archivos de paquete. De vez en cuando, todos los archivos "sueltos" (en realidad, no solo archivos, sino también objetos que contienen información de compromiso y de directorio) de un repositorio se recopilan y comprimen en un archivo de paquete. El archivo del paquete está comprimido usando zlib. Y los archivos similares también están comprimidos delta.
El mismo formato también se usa al tirar o empujar (al menos con algunos protocolos), por lo que no es necesario recomprimir nuevamente esos archivos.
El resultado de esto es que un repositorio de git, que contiene toda la copia de trabajo sin comprimir, los archivos recientes sin comprimir y los archivos comprimidos más antiguos suele ser relativamente pequeño, más pequeño que el doble del tamaño de la copia de trabajo. Y esto significa que es más pequeño que el repositorio SVN con los mismos archivos, aunque SVN no almacena el historial localmente.
Git almacena para cada commit una copia completa de todos los archivos, excepto que, para el contenido ya presente en el repositorio de Git, la instantánea simplemente apuntará a dicho contenido en lugar de duplicarlo.
Eso también significa que varios archivos con el mismo contenido se almacenan solo una vez.
Entonces, una instantánea es básicamente una confirmación, refiriéndose al contenido de una estructura de directorio.
Algunas buenas referencias son:
Le dices a Git que quieres guardar una instantánea de tu proyecto con el comando git commit y básicamente registra un manifiesto de cómo son todos los archivos en tu proyecto en ese momento
El laboratorio 12 ilustra cómo obtener instantáneas anteriores
El libro de progit tiene la descripción más completa de una instantánea:
La principal diferencia entre Git y cualquier otro VCS (Subversion y amigos incluidos) es la forma en que Git piensa sobre sus datos.
Conceptualmente, la mayoría de los otros sistemas almacenan información como una lista de cambios basados en archivos. Estos sistemas (CVS, Subversion, Perforce, Bazaar, etc.) piensan en la información que guardan como un conjunto de archivos y los cambios realizados en cada archivo a lo largo del tiempo.
Git no piensa ni almacena sus datos de esta manera. En cambio, Git piensa que sus datos se parecen más a un conjunto de instantáneas de un mini sistema de archivos.
Cada vez que se compromete o guarda el estado de su proyecto en Git, básicamente toma una imagen de cómo se ven todos los archivos en ese momento y almacena una referencia a esa instantánea.
Para ser eficiente, si los archivos no han cambiado, Git no almacena el archivo nuevamente, solo un enlace al archivo idéntico anterior que ya ha almacenado.
Git piensa en sus datos más como sigue:
Esta es una distinción importante entre Git y casi todos los demás VCS. Hace que Git reconsidere casi todos los aspectos del control de versiones que la mayoría de los demás sistemas copiaron de la generación anterior. Esto hace que Git se parezca más a un mini sistema de archivos con algunas herramientas increíblemente potentes creadas encima, en lugar de simplemente un VCS.
Jan Hudec agrega este importante comentario :
Si bien eso es cierto e importante en el nivel conceptual, NO es cierto en el nivel de almacenamiento.
Git usa deltas para el almacenamiento .
No solo eso, sino que es más eficiente que cualquier otro sistema. Debido a que no mantiene el historial por archivo, cuando quiere hacer la compresión delta , toma cada blob, selecciona algunos blobs que probablemente sean similares (utilizando heurística que incluye la aproximación más cercana de la versión anterior y algunos otros), intenta generar los deltas y elige el más pequeño. De esta forma, puede (a menudo, depende de la heurística) aprovechar otros archivos similares o versiones anteriores que son más similares que las anteriores. El parámetro "paquete de ventana" permite el rendimiento comercial para la calidad de compresión delta. El valor predeterminado (10) generalmente arroja resultados decentes, pero cuando el espacio es limitado o para acelerar las transferencias de red,git gc --aggressive
usa el valor 250, lo que lo hace funcionar muy lento, pero proporciona compresión adicional para los datos del historial.
Las respuestas anteriores son bastante interesantes, pero me gustaría agregar un pequeño concepto más pequeño conocido como codificación delta. La eficiencia se guarda hasta que se escribe el archivo del paquete. Los objetos sueltos se escriben en formato comprimido, pero no delta, en el momento de cada confirmación.