git interno para informáticos

Git Internal Computer Scientists

http://eagain.net/articles/git-for-computer-scientists/

el almacenamiento de objetos git es solo un DÍA de objetos, hay varios tipos de objetos. Todos están comprimidos, guardados y marcados con hash SHA-1.

Blob: el objeto más simple es solo una pila de bytes. A menudo es solo un archivo, pero también puede ser un enlace simbólico o cualquier otra cosa. Apunte al objeto del blob para especificar la semántica específica del blob.





árbol: el directorio está marcado por un objeto de árbol. Hacen referencia a blobs relacionados que contienen contenido de archivos y árboles que apuntan a otros subdirectorios.



Cuando un nodo apunta a otro nodo en el DAG, dependerá del nodo apuntado: es decir, este nodo no puede existir sin el nodo apuntado. El nodo sin ningún otro nodo apuntando a él será recuperado por el comando git gc, o restaurado como el comando de rescate de emergencia de inodos sin ningún nombre de archivo que apunte al sistema de archivos: git fsck --lost-found

compromiso: un compromiso se refiere a un objeto de árbol que refleja el estado del conjunto de archivos cuando se ejecuta el compromiso. También cita 0..n confirma como padre. Más de una confirmación principal significa que se trata de una confirmación de fusión, y una confirmación sin un padre significa que es una confirmación inicial. Por supuesto, puede haber más de un compromiso inicial: esto generalmente significa que dos proyectos independientes se fusionan. El contenido del objeto de confirmación es el mensaje de confirmación.



refs: referencias, cabezas o ramas son como notas adhesivas en un nodo en DAG. A diferencia de la función de DAG, que solo permite agregar nodos y no permite cambios, este memo puede moverse arbitrariamente. No se registran en la historia, no se pasan directamente entre repositorios, son como un marcador que anuncia 'estoy trabajando aquí'.

El comando git commit agregará un nodo al DAG y moverá la nota desde la rama actual hacia este nuevo nodo.

HEAD ref es especial porque en realidad apunta a otra ref. Por lo general, apunta a la rama actualmente activa. Las referencias comunes están en realidad en el espacio de nombres de heads / xxx, pero tiende a ignorar las cabezas / parte

referencias remotas: la referencia remota está marcada con otro color, también es una nota adhesiva. La diferencia con las referencias normales es el espacio de nombres diferente, y el hecho es que las referencias remotas generalmente están controladas por el servidor remoto, y se actualizarán durante las operaciones de búsqueda de git.

etiqueta: una etiqueta no es solo un nodo en el DAG, sino también una nota adhesiva. Una etiqueta apunta a una confirmación y contiene un mensaje opcional y una firma GPG

La nota adhesiva en sí solo proporciona una forma rápida de acceder a la etiqueta. Una vez que se pierde, también se puede recuperar a través de git fsck --lost-found

Los nodos en DAG se pueden mover de un repositorio a otro repositorio, se pueden almacenar de una manera más eficiente (paquetes), y los nodos que ya no se utilizan se limpiarán como basura.

Pero al final, un repositorio de git siempre es un DAG y una colección de notas correspondientes

Historia:

Con el conocimiento anterior sobre cómo git guarda el historial de versiones, ¿cómo podemos visualizar acciones como fusiones? Es mejor usar gráficos para expresar:

El anterior es el repositorio más simple, clonamos un repositorio remoto y el repositorio solo tiene una confirmación.

Arriba hemos obtenido el control remoto, la recuperación contiene una confirmación de otra persona y la confirmación no se ha fusionado

La figura anterior muestra la situación después de ejecutar git merge remotes / myserver / master. Dado que la fusión es un avance rápido (es decir, no tenemos ningún cambio nuevo en la sucursal local de Shanghai, por lo que podemos avanzar directamente), después de la fusión, el único cambio: movimos nuestras notas al nuevo nodo, Y correspondientemente cambió el contenido del directorio de trabajo

En la imagen de arriba, tenemos una confirmación local e hicimos una acción de búsqueda de git, seguimos teniendo una nueva confirmación localmente y también una nueva confirmación remota, en este caso es necesaria una fusión.

El resultado de la ejecución de git merge remotes / myserver / master es como se muestra arriba. Dado que tenemos nuevas confirmaciones locales, ya no es un avance rápido en este momento, sino que debe indicar la fusión creando un nuevo nodo de confirmación en el DAG. En este momento, tenga en cuenta que la confirmación de fusión tiene dos confirmaciones principales.

En la imagen de arriba, hemos realizado varias confirmaciones nuevas y una nueva combinación. git DAG registra el historial de cualquier acción que haya ocurrido

El patrón 'cosido' anterior a veces puede parecer molesto. Si aún no ha publicado su rama, o ha comunicado claramente que otros no deben basar su trabajo en ella, tiene otra opción: puede volver a basar su rama en lugar de fusionarla. La ventaja de esto es: su compromiso será. Otro compromiso con un padre diferente lo reemplaza, y su rama se moverá allí. (Esta confirmación utilizará la última confirmación de la rama remota como la confirmación principal)

Su antigua confirmación aún se almacenará en el DAG hasta que el mecanismo de recolección de basura de git funcione para eliminarla. Por supuesto, si tiene notas adhesivas adicionales que apuntan a la confirmación anterior, siempre lo señalarán, y solo porque alguien señale la confirmación no utilizada, esto guardará la confirmación anterior y no se limpiará con basura.

No reemplace las ramas sobre las que otros han creado nuevas confirmaciones.

La situación después de la recolección de basura es como se muestra en la figura de arriba (o confirmación simplemente o ligeramente inalcanzable), y se crea una nueva confirmación en la rama rebasada

Rebase también sabe cómo reajustar múltiples confirmaciones en una sola confirmación