Hola Habr! Les presento la traducción del artículo "Git para informáticos" de Tommi Virtanen.
GIT Inside Out: una introducción
De mí mismo: leo periódicamente artículos sobre cómo se organizan varias tecnologías populares bajo el capó, me encontré con este material . El artículo parecía interesante por la presencia de esquemas simples y comprensibles, que se perciben mucho mejor que las hojas de un texto aburrido. Decidí traducir al ruso. Imágenes tomadas del original.
Quiénes estarán interesados y posiblemente útiles: personas que trabajan con Git todos los días (es decir, cada segundo, si no el primer desarrollador de software), y que desean comprender mejor el mecanismo de su trabajo.
Nota: para una mejor comprensión del artículo, uno debe tener una idea de una bestia como un gráfico acíclico dirigido (DAG) .
Almacenamiento de objetos
El repositorio de objetos Git es, en términos generales, un DAG que contiene varios tipos de objetos. Los objetos se almacenan en forma comprimida y se identifican mediante hashes SHA-1 (esto NO es un hash del contenido del archivo que representa el objeto, sino su presentación en Git).
Blob

Blob es un objeto simple, solo una colección de bytes. Puede ser un archivo, un enlace simbólico o lo que sea. La semántica está determinada por el objeto que apunta a este blob.
Arbol

Los objetos del tipo "árbol" describen directorios (directorios). Pueden apuntar a blobs que almacenan el contenido de los archivos, así como a otros árboles, creando así una estructura de subdirectorio.
Si un nodo apunta a otro nodo en el DAG, dicen que depende de ese nodo, es decir No puede existir sin él. No se puede eliminar a nadie con la recolección de elementos no utilizados (comando git gc ) ni restaurar con el comando git fsck --lost-found .
Comprometerse

Confirmar se refiere a un árbol que representa el estado de los archivos en Git en el momento en que se creó la confirmación. Además, commit puede referirse a otros commits que son sus padres:
- Si el commit tiene más de 1 padre, esto significa que describe la operación de fusión (fusión)
- Si el commit no tiene padres, este es el llamado commit inicial (inicial) (es decir, el primero en el repositorio)
- También puede haber casos en los que haya más de 1 confirmación inicial en el repositorio; esto generalmente significa fusionar dos repositorios separados
El cuerpo del objeto de confirmación es el mensaje de confirmación .
Refs (enlaces)

Los enlaces (o encabezados o ramas) son similares a las etiquetas adhesivas con notas pegadas en los nodos DAG, algún tipo de notas o marcadores: "Yo trabajo aquí". A diferencia de los nodos DAG, que no se pueden cambiar y solo se pueden agregar, los enlaces se pueden mover a su gusto. No se almacenan en el historial y no se transfieren directamente entre repositorios.
El comando git commit agrega un nuevo nodo al DAG y mueve un marcador para la rama actual.
Los enlaces están en el espacio de nombres de cabezas / nombre de sucursal , pero se pueden omitir parte de las cabezas .
El enlace HEAD se distingue, no apunta a un nodo, sino a otro enlace, esto es un puntero a la rama activa actual.
Refs remotos

Estos son, en términos generales, pegatinas de un color diferente. La diferencia es que los enlaces remotos están en un espacio de nombres diferente y también son administrados por un servidor remoto. Para actualizarlos, use el comando git fetch .
Etiqueta

Una etiqueta es una combinación de un nodo DAG y una pegatina (otro color). La etiqueta apunta a confirmar e incluye un mensaje opcional y una firma GPG. Una pegatina (enlace) es una forma sencilla de acceder a la etiqueta y, en caso de pérdida, se puede restaurar con el comando git fsck --lost-found .
Por lo tanto, un repositorio de Git es una combinación de DAG y enlaces.
La historia
Ahora, sabiendo cómo Git almacena el historial de versiones, intentemos representar varias operaciones, así como comprender cómo Git difiere de los sistemas que representan el historial como cambios lineales para cada rama.

El repositorio más simple. Simplemente copiamos ( git clone ) el repositorio remoto con un solo commit.

Aquí leemos ( git fetch ) el repositorio remoto y obtuvimos 1 nueva confirmación, pero aún no la hemos fusionado con nuestra rama.

Esto es lo que sucede después de ejecutar el comando git merge remotes / MYSERVER / master . Como la fusión se realizó como avance rápido (no hubo confirmaciones locales en nuestra rama local), sucedió lo siguiente: los archivos de nuestra copia de trabajo cambiaron y el puntero a la rama también se movió.

Ejecute git commit localmente y luego git fetch . Ahora tenemos confirmación local y remota. Obviamente, necesitas una fusión .

Este es el resultado del comando git merge remotes / MYSERVER / master . Como teníamos un compromiso local, esto no es un avance rápido, y se crea un compromiso separado para la fusión en el DAG. Aviso: tiene 2 padres comprometidos.

Así es como nuestro árbol se verá después de varios commit-s, en ambas ramas (local y remota) + fusión. Puedes ver claramente cómo Git DAG captura toda la historia de nuestras acciones.

Sin embargo, tal historia es difícil de leer. Si aún no ha publicado su sucursal, o ha acordado con otros miembros del equipo que no deberían construir sobre ella en su trabajo, tiene una alternativa: puede cambiar el nombre de su sucursal. En este caso, su confirmación se reemplaza por otra confirmación, con un padre diferente, al que también se mueve el enlace a la rama.
En este caso, sus antiguos commit-s permanecerán en el DAG hasta la recolección de basura. En principio, este es un tipo de seguro, en caso de que algo salga mal. Si todavía tiene enlaces a una confirmación anterior, se guardarán mientras existan los enlaces.
NO debe cambiar el nombre de las ramas sobre las cuales otras personas han creado commit. Puede restaurarlos (y ni siquiera es muy difícil), pero esto agrega confusión y mucho trabajo inútil.

Así es como se ve después de la recolección de basura (o ignorando los commits inaccesibles), y creando un nuevo commit sobre la rama a la que se aplicó el rebase.

Además, con rebase, puede mover varias confirmaciones al mismo tiempo.
Eso es todo. Espero que el material sea útil.