¿Por qué git usa hashes en lugar de números de revisión?

80

Siempre me pregunté por qué git prefiere los hashes sobre los números de revisión. Los números de revisión son mucho más claros y fáciles de consultar (en mi opinión): ¡Hay una diferencia entre decirle a alguien que eche un vistazo a la revisión 1200 o cometa 92ba93e! (Solo para dar un ejemplo).

Entonces, ¿hay alguna razón para este diseño?

Max Beikirch
fuente
3
Puede etiquetar una confirmación con "v1.0" y luego consultar la confirmación con esa etiqueta. Ver git-scm.com/book/en/v2/Git-Basics-Tagging
Michael Durrant

Respuestas:

114

Un solo número de revisión, que aumenta monotónicamente, solo tiene sentido para un sistema de control de versiones centralizado, donde todas las revisiones fluyen a un solo lugar que puede rastrear y asignar números. Una vez que ingresa al mundo DVCS, donde existen numerosas copias del repositorio y los cambios se extraen y se envían a ellos en flujos de trabajo arbitrarios, el concepto simplemente no se aplica. (Por ejemplo, no hay un solo lugar para asignar números de revisión; si bifurco su repositorio y decide un año después retirar mis cambios, ¿cómo podría un sistema garantizar que nuestros números de revisión no entren en conflicto?)

Josh Kelley
fuente
11
Es posible que desee ver el estilo Bazar : un DVCS que aún mantiene números de revisión. La única garantía es que los números de revisión son únicos dentro de una sucursal.
krlmlr
3
@krlmlr Person 1: "Hey, <P2>, what was revision 12345 for?" P2: "Revision 12345 was commited by <P3>." P3: "I don't have a revision 12345...": si no recuerdo mal , Mercurial tiene un problema similar. Por otro lado, si estuvieran usando git, todos tendrían referencias idénticas para cada commit.
Izkata
1
@Izkata: P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"... Bazar todavía tiene GUID ...
krlmlr
55
@Izkata Mercurial no tiene un problema similar. Usan hashes, al igual que git. También proporcionan un número de revoluciones solo local para facilitar la escritura.
Hank Gay
1
con git, los primeros 5 caracteres del hash suelen ser lo suficientemente únicos como para usar una abreviatura para la ID de revisión completa.
mendota
40

Necesita hashes en un sistema distribuido. Digamos que usted y un colega están trabajando en el mismo repositorio y que ambos realizan un cambio localmente y luego lo presionan. ¿Quién será el número de revisión 1200 y quién es el número de revisión 1201 dado que ninguna de las partes tiene conocimiento el uno del otro? La única solución técnica realista es crear un hash de los cambios utilizando un método conocido y vincular las cosas en función de eso.

Curiosamente, HG admite números de versión, pero son explícitamente una característica solo local: su repositorio tiene un conjunto, el repositorio de su compañero de trabajo tendrá un conjunto diferente dependiendo de cómo lo empujaron y lo que tiraron. Sin embargo, hace que el uso de la línea de comandos sea un poco más amigable que Git.

Wyatt Barnett
fuente
34

Integridad de los datos.

Respetuosamente estoy en desacuerdo con las respuestas actuales. Los hashes no son necesarios para un DVCS, vea el camino del Bazar . Podría hacerlo también con cualquier otro tipo de identificador único global. Los hash son una medida para garantizar la integridad de los datos: representan un resumen de la información contenida en el objeto (commit, árboles, ...) al que hace referencia el hash. Se cree que alterar el contenido sin alterar el hash (es decir, un ataque de preimagen o un ataque de colisión ) es difícil, aunque no imposible. (Si realmente te gusta, mira el artículo de 2011 de Marc Stevens ).

Por lo tanto, hacer referencia a los objetos por su hash SHA permite verificar si el contenido ha sido manipulado. Y, dado que están (casi) garantizados como únicos, también se pueden usar como identificadores de revisión, convenientemente.

Vea el Capítulo 9 del libro de Git para más detalles.

krlmlr
fuente
8
No es una medida de seguridad, ya que el hash se puede volver a calcular fácilmente para una confirmación modificada. Solo se usa por integridad, para verificar el contenido contra el hash calculado: vea este comentario de Linus Torvalds sobre el uso de SHA-1 en Git.
Lee
@Lee: Si el repositorio de Chuck es diferente del que tienen Alice y Bob en términos de hashes de revisión, se garantiza que Chuck también tiene diferentes contenidos. Por otro lado, es muy difícil para Chuck fabricar un repositorio con diferentes contenidos que se ve idéntico con sus hashes de revisión.
krlmlr
@Lee: te perdiste tu enlace. Llamémoslo "integridad de datos" entonces ...
krlmlr
debería ser la respuesta correcta
SuperUberDuper
8

En palabras simples:

  • Los hashes están destinados a ser casi universalmente únicos. NO está garantizado, pero es extremadamente improbable que se generen los mismos SHA para contenido diferente. En términos prácticos para un proyecto dado, puede tratarlo como único.
  • Con los números de revisión, tendría que usar un espacio de nombres para referirse específicamente a la revisión 1200.
  • Git puede funcionar tanto distribuido como centralizado. Entonces, ¿cómo se obtienen los números de revisión correctos y únicos?
  • También el uso de números de revisión crearía la falsa expectativa de que las revisiones más recientes deberían tener números más altos, y eso no sería cierto debido a la ramificación, fusión, rebase, etc.
  • Siempre tienes la opción de poner etiquetas a los commits.
Tulains Córdova
fuente
32
No se garantiza que sea único, simplemente increíblemente probable que sea único. :)
dsw88
@ mustang2009cobra Eso es cierto.
Tulains Córdova
1
Es posible que mi cambio no sea aceptado porque el hash no ha cambiado. Es mucho más probable que dos meteoritos golpeen mi computadora y la computadora con el repositorio en el mismo segundo, destruyendo las computadoras y matando a todos los involucrados.
gnasher729
1

Hash no es la solución única para VCS distribuido. Pero cuando se trata con un sistema distribuido, solo se puede registrar el orden parcial de los eventos. (Para VCS, el evento puede ser una confirmación). Es por eso que es imposible mantener un número de revisión que aumente monotónicamente. Por lo general, adoptamos algo como el reloj vectorial (o la marca de tiempo del vector) para registrar dicha relación de orden parcial. Esta es la solución utilizada en Bazar .

Pero, ¿por qué Git no usa el reloj vectorial sino el hash? Creo que la causa raíz es la selección de cerezas . Cuando realizamos una selección de cereza en un repositorio, el orden parcial de las confirmaciones está cambiando. Los relojes vectoriales de algunos commits deben reasignarse para representar el nuevo orden parcial. Sin embargo, tal reasignación en el sistema distribuido induciría relojes vectoriales inconsistentes. Ese es el verdadero problema con el que lidian los hashes.

Che-Sheng Lin
fuente