Estrategia de locking de git para lograr la concurrency?

Así que he estado leyendo últimamente sobre cómo configurar un server de git, y al encontrar que no se necesita ningún daemon específico (solo un server SSH con un sistema de files), comencé a search más información sobre cómo gestiona los files bajo git la capucha.

La estrategia de cómo se representa cada compromiso dentro de la carpeta .objects y cómo encaja todo es bastante ingeniosa, pero no parece mencionarse explícitamente que este enfoque realmente hace que git logre la concurrency de una manera muy simple sin la necesidad de un server de señalización

No obstante, hay situaciones en las que no se puede garantizar la concurrency, que es básicamente cuando se reescribe la historia (impulsos forzados). En este caso, ¿hay alguna estrategia de locking utilizada en el tree para evitar problemas de concurrency? ¿Hay más documentation sobre este tema?

(Se dice algo sobre este tema en esta respuesta SO , pero solo muy brevemente).

Las estructuras de datos de git son inmutables, excepto los refs (es decir, branches / tags / etc), y "rewriting history" no es un término muy correcto, más apropiado es "crear un historial alternativo". El repository tendrá todos los objects, nuevos y antiguos. Además, todos los cambios creados en un repository local, durante los objects "push" simplemente se transfieren. Luego lo presionas, envía todos los objects primero (y debido a que los objects están definidos por su contenido, son únicos, no hay problemas de concurrency). Después de enviar todos los objects, una reference está cambiando. Es solo un pequeño file único ( refs/heads/<branchName> ) para anular con 40 bytes de key sha1. Como sé, el cambio atómico Compare-and-Set cambia el file. Lee el antiguo valor de reference, crea un file de locking, comtesting si el valor anterior no se modifica, reemplaza con el nuevo sha1 y elimina el locking. Si falla, el impulso falla y debe volver a intentarlo (es decir, locking optimista). Puede encontrar más detalles del código fuente , function update_ref.

Después del empuje forzado, podrían aparecer algunos "objects sueltos" (es decir, objects a los que no se hace reference desde ningún ref existente), por lo que estos objects se recolectarán después.

Muy inteligente y orderado.

Se crean varios files donde sea necesario para actuar como lockings. Git crea un file llamado .git/index.lock para bloquear el índice. git index-pack puede crear un file .keep para evitar una condición de carrera. Puede haber más ejemplos.