GIT, ¿Cómo se llena el directory de trabajo?

Me pregunto cómo se completa el directory de trabajo de GIT "tree de trabajo".

¿Los files se extrapolan de alguna manera a través de la relación tipo arbol que existe a partir del compromiso al que se refiere HEAD y trabajando "hacia atrás" hacia la raíz del tree?

Tal vez si alguien pudiera proporcionar algún tipo de process de alto nivel que ocurra … es decir,

1.) Agregue todos los files contenidos en la confirmación referida por HEAD al tree de trabajo.

2.) Recursivamente, para cada file al que hace reference el compromiso principal de HEAD, también los adhiere al tree de trabajo.

Tengo curiosidad por cómo funciona esto, ¿hay un modo detallado para algo así como git checkout donde una function hipotética llamada build_working_tree () daría salida a sus acciones?

Ignore por el momento exactamente cómo un repository crea treees de files y apunta a files individuales. Solo atengámonos al hecho de que crean references a estos objects. El punto importante es que si el object es exactamente el mismo (incluyendo tener exactamente las mismas carpetas y los mismos files exactos para una carpeta), entonces git solo apuntará al mismo object en una futura confirmación.

Suponer que commit c1 tiene una confirmación inicial con solo file1.txt

 c1 -> file1 

entonces se realiza commit c2 , que tiene el mismo file1 , por lo que crea una reference al object antiguo para eso (el mismo object que c1 ). También agrega una carpeta dir1 y un file2 dentro de dir1 , por lo que crea enlaces a esos.

 c2 ----> dir1 -> file2 \ c1 -> file1 

Ahora agregue una confirmación c3 , y nuevamente, file1 que el file1 sea ​​el mismo, así que c3 aún puede señalar el mismo object, y el file2 es el mismo pero se agrega un nuevo dir1 a dir1 . Esto significa que dir1 tiene que cambiar (lo muestro como dir1* , pero aún puede apuntar al object file2 . También se agrega un nuevo dir1* a dir1* .

 c3 -> dir1* ------> new file3 \ \ c2 -\ -> dir1 -> file2 \ c1 -> file1 

El punto es que no necesita saber nada sobre c1 , c2 o incluso dir1 para recrear el directory de trabajo de c3 . Está apuntando a dir1* , dir1* , file2 y file3 , y puede encontrarlos en el repository de objects sin necesidad de conocer otros objects.

Ahora, hay algo más, por supuesto, porque a veces Git solo almacena las diferencias entre los files, si los files son grandes y la diferencia es pequeña (entre otras optimizaciones), pero esta concepción de alto nivel cubre la idea básica.

En cuanto a los commands de plomería de nivel inferior, sí existen, y Git realmente los usa cuando lo hace. Estos se describen en el enlace que Chris dio en su comentario: Git Internals: Git Objects . Esto le mostrará cómo seguir el hash de confirmación en los objects almacenados en el repository y mostrar el text en cada uno, tanto el hash que apunta a cada object como el object real.