Por que o git usa hashes em vez de números de revisão?

80

Eu sempre me perguntei por que o git prefere hashes sobre números de revisão. Os números de revisão são muito mais claros e fáceis de consultar (na minha opinião): Há uma diferença entre dizer a alguém para dar uma olhada na revisão 1200 ou confirmar 92ba93e! (Apenas para dar um exemplo).

Então, existe alguma razão para esse design?

Max Beikirch
fonte
3
Você pode marcar uma confirmação com "v1.0" e, em seguida, consultar a confirmação por essa marca. Veja git-scm.com/book/en/v2/Git-Basics-Tagging
Michael Durrant

Respostas:

114

Um único número de revisão monotonicamente crescente só faz sentido para um sistema de controle de versão centralizado, onde todas as revisões fluem para um único local que pode rastrear e atribuir números. Quando você entra no mundo do DVCS, onde existem inúmeras cópias do repositório e as alterações são extraídas e enviadas a eles em fluxos de trabalho arbitrários, o conceito simplesmente não se aplica. (Por exemplo, não há um lugar para atribuir números de revisão - se eu bifurcar seu repositório e você decidir, um ano depois, fazer minhas alterações, como um sistema poderia garantir que nossos números de revisão não entrem em conflito?)

Josh Kelley
fonte
11
Você pode querer ver o caminho do Bazaar - um DVCS que ainda mantém os números das revisões. A única garantia é que os números de revisão são únicos dentro de uma filial.
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..."- Se bem me lembro, o Mercurial tem um problema semelhante. Por outro lado, se eles estivessem usando git, todos teriam referências idênticas para cada commit.
Izkata
1
@Izkata: P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"... Bazaar ainda tem GUIDs ...
krlmlr
5
@ Izkata Mercurial não tem um problema semelhante. Eles usam hashes, assim como git. Eles também fornecem um número de rev somente local para facilitar a digitação.
Hank Gay
1
com o git, os 5 primeiros caracteres do hash geralmente são únicos o suficiente para usar uma abreviação para o ID completo da revisão.
Mendota
40

Você precisa de hashes em um sistema distribuído. Digamos que você e um colega estejam trabalhando no mesmo repositório e que ambos realizem uma alteração localmente e depois enviem. Quem passa a ser a revisão número 1200 e quem é a revisão número 1201, dado que nenhuma das partes tem conhecimento um do outro? A única solução técnica realista é criar um hash das alterações usando um método conhecido e vincular as coisas com base nisso.

Curiosamente, o HG suporta números de versão, mas eles são explicitamente um recurso apenas local - seu repositório tem um conjunto, o repositório do seu colega de trabalho terá um conjunto diferente, dependendo de como eles foram empurrados e puxados. Isso torna o uso da linha de comando um pouco mais amigável do que o Git.

Wyatt Barnett
fonte
34

Integridade de dados.

Discordo respeitosamente das respostas atuais. Hashes não são necessários para um DVCS, veja o caminho do Bazar . Você poderia fazer o mesmo com qualquer outro tipo de identificador globalmente exclusivo. Os hashes são uma medida para garantir a integridade dos dados: eles representam um resumo das informações contidas no objeto (confirmação, árvores, ...) referido pelo hash. Acredita-se que alterar o conteúdo sem alterar o hash (isto é, um ataque de pré - imagem ou ataque de colisão ) seja difícil, embora não impossível. (Se você realmente gosta, dê uma olhada no artigo de 2011 de Marc Stevens ).

Portanto, a referência aos objetos por seu hash SHA permite verificar se o conteúdo foi violado. E, desde que eles sejam (quase) garantidos exclusivos, eles também podem ser usados ​​como identificadores de revisão - convenientemente.

Veja o Capítulo 9 do livro Git para mais detalhes.

krlmlr
fonte
8
Não é uma medida de segurança, pois o hash pode ser facilmente recalculado para uma confirmação modificada. É usado apenas para integridade, para verificar o conteúdo em relação ao hash calculado - veja este comentário de Linus Torvalds sobre o uso do SHA-1 no Git.
19413 Lee
@ Lee: Se o repositório de Chuck for diferente daquele que Alice e Bob têm em termos de hashes de revisão, é garantido que Chuck também tenha conteúdo diferente. Por outro lado, é muito difícil para Chuck fabricar um repositório com conteúdos diferentes que parecem idênticos em seus hashes de revisão.
krlmlr
@ Lee: Perdeu o seu link. Vamos chamá-lo de "integridade dos dados", então ...
krlmlr
deve ser a resposta correta
SuperUberDuper
8

Nas palavras dos leigos:

  • Os hashes devem ser quase universalmente únicos. NÃO é garantido, mas é extremamente improvável que os mesmos SHAs sejam gerados para conteúdo diferente. Em termos práticos, para um determinado projeto, você pode tratá-lo como único.
  • Com os números de revisão, você precisaria usar um espaço para nome para se referir especificamente à revisão 1200.
  • O Git pode trabalhar distribuído e / ou centralizado. Então, como você obtém os números de revisão corretos e exclusivos?
  • O uso de números de revisão também criaria uma falsa percepção de que as revisões mais recentes deveriam ter números mais altos, o que não seria verdade por causa de ramificações, mesclagens, rebatizações etc.
  • Você sempre tem a opção de colocar tags em confirmações.
Tulains Córdova
fonte
32
Não é garantido que seja único, apenas incrivelmente provável que seja único. :)
dsw88
@ mustang2009cobra Isso é verdade.
Tulains Córdova
1
É possível que minha alteração não seja aceita porque o hash é inalterado. É muito mais provável que dois meteoros atinjam meu computador e o computador com o repositório no mesmo segundo, destruindo os computadores e matando todos os envolvidos.
Gnasher729
1

Hash não é a solução exclusiva para VCS distribuído. Porém, quando lidamos com um sistema distribuído, apenas a ordem parcial dos eventos pode ser registrada. (Para o VCS, o evento pode ser um commit.) É por isso que é impossível manter um número de revisão monotonicamente crescente. Geralmente adotamos algo como relógio vetorial (ou carimbo de data e hora do vetor) para registrar essa relação de ordem parcial. Esta é a solução usada no Bazaar .

Mas por que o Git não usa relógio de vetor, mas hash? Eu acho que a causa raiz é a escolha da cereja . Quando executamos a seleção de cereja em um repositório, a ordem parcial de confirmações está mudando. Alguns relógios vetoriais de consolidação devem ser redesignados para representar a nova ordem parcial. No entanto, essa reatribuição no sistema distribuído induziria relógios vetoriais inconsistentes. Esse é o problema real com o qual os hashes lidam.

Che-Sheng Lin
fonte