Qual é a diferença entre um Git SHA-1 e um compromisso?
Jon Seymour deu a maior parte da resposta que eu teria dado. eu só tenho algumas coisas a acrescentar.
Jon fala do SHA-1 como um "nome" para um objeto. Eu prefiro considerar isso para denotar a "identidade" do objeto.
A razão desta pequena distinção é importante, é que ela permite que você identifique de forma única um commit específico (ou árvore, blob, ou tag(), não importa quais mudanças possam ser feitas no repo. Tags poderiam ser movidas (substituídas), ramos adicionados, rebasing poderiam substituir um commit por um commit completamente diferente, que alguém poderia então forçar-push para o repo, codificando coisas para todos - e que o SHA-1 ainda se referiria exatamente a esse mesmo commit.
Um commit é na verdade um objeto muito simples. Você pode até mesmo construí-lo manualmente. Ele tem as informações sobre o committer e o autor e as datas. Ele tem a mensagem de submissão. Ele tem o SHA-1 de um ou mais pais. E tem o SHA-1 da árvore.
A árvore também é um objeto simples, basicamente consistindo de uma lista de blobs (arquivos ou links) por nome, ou sub-árvores (diretórios). E um hack especial para submódulos.
Se você alterar QUALQUER dessas informações, o SHA-1 muda - ele se torna um novo objeto.
Se você alterar o conteúdo da árvore - qualquer arquivo (blob), qualquer diretório (também uma árvore), o SHA-1 da árvore mudará.
Se você alterar qualquer um desses para qualquer commit dos pais, esse SHA-1 mudará. Isso então mudará essa submissão. Ad infinitum.
Então o SHA-1 de um commit não apenas denota um conteúdo particular da árvore - ele denota uma história inteira de como a árvore chegou lá.
Conhecendo o SHA-1 de um commit, você pode se recuperar de todos os tipos de problemas. Eu usei a informação para me recuperar depois de um mau force-pushes, e para reparar repositórios corrompidos (por exclusão parcial acidental), reconstruindo-os com commits e outros objetos de outros repositórios.
Mas saber o SHA-1 de um commit também lhe diz que a árvore e todo o histórico não foram adulterados. Eu poderia te dar um SHA-1 de um commit, empurrar meu repo para algum lugar não confiável, deixá-los fazer as mudanças que quiserem, e você ainda saberia, que o commit que eu te dei não mudou.
Eles podem *danos*, removendo objetos, mas não podem mudá-lo.
É uma forte garantia de segurança!
Não importa quantos atores não confiáveis estejam envolvidos em um projeto, quando alguém te dá um pedido de puxar, você pode ter certeza de que o commit deles não está construído sobre alguma história alternativa. A menos, claro, que seja, o que em breve será óbvio, porque a fusão falhará.
Então é por isso que eu vejo isso como mais do que apenas um nome para um commit, mas mais fortemente ligado à própria identidade de um commit.
Footnote: Eu lavei aqui, a possibilidade muito remota de uma colisão de hashes com o SHA-1. O SHA-1 não é tão seguro quanto o mais moderno SHA-256 ou SHA-512, mas ainda está na ordem de 1/2^69 para um atacante malicioso usando fraquezas do SHA-1, ou 1/2^80 sem, assumindo distribuição igual. É difícil imaginar quão grande é 2^69.
Se construíssemos uma cadeia de carbono muito longa, entre aqui e alfa centauri, e usássemos SHA-1 para selecionar um átomo de carbono nesta mudança, então 2^69 baldes estariam a menos de 0.1 mm de distância, mas os 2^80 hashes SHA-1 diferentes estariam a cerca de 275 átomos de distância.
Para todos os efeitos práticos, podemos ignorar a possibilidade de que dois objetos diferentes teriam o mesmo SHA-1.