I was actually assuming that something will break at the next push or pull, but to my surprise, everything appeared to work fine. More commits, more pushing and pulling, no problems.
Cada objeto - arquivo, confirmação, etc. - é nomeado após o hash SHA1 de seu conteúdo (mais um cabeçalho pequeno). Sempre que um objeto individual é lido na memória para uso, os dados são criptografados e comparados com o nome do objeto; qualquer incompatibilidade fará com que um erro seja mostrado.
No entanto, a maioria das operações não precisa para ler todo o repositório na memória. Em geral, todos os comandos apenas lêem o mínimo necessário - claro, você teria notado o problema se você tentasse verificar um commit ou diff quebrado, mas operações como criar um commit não se importam com objetos anteriores. Mesmo empurrando precisa de apenas uma pequena seleção de objetos (como a base delta para pacotes 'finos') porque ambos os pares sabem o que o outro lado já tem.
(Essa otimização é um resultado direto do layout baseado em instantâneo. Por exemplo, git add não precisa delta em relação aos arquivos antigos, porque ele simplesmente cria um novo instantâneo Então, o git commit transforma este instantâneo em objetos commit / tree sem conhecer qualquer coisa sobre o commit anterior, exceto seu ID.
Em primeiro lugar, lembre-se de que um clone do mesmo sistema de arquivos do mesmo computador não compacta e transfere objetos - ele simplesmente vincula os arquivos para os arquivos, a fim de economizar espaço e tempo. Você tem que explicitamente desativar isso clonando a partir de uma URLThis happens not only when I start with a corrupted file in the bare repository, it is also possible to introduce a corrupted file from a working repository in a bare one this way.
file://
em vez de um caminho simples.
No entanto, um clone sobre SSH ou HTTPS (ou o arquivo acima: // URLs) realmente lê e grava os dados do objeto para criar o pacote de transferência, portanto, qualquer objeto corrompido que deveria fazer parte da transferência irá abortar o processo.
Se você, de alguma forma, conseguir empurrar um objeto corrompido para um servidor remoto - deslizando através do empacotamento local e da descompactação remota - isso é um pouco incomum (especialmente após o 2013 história do git.kde.org ) e eu levantaria essa preocupação na lista de discussão do Git.
(Não se preocupe que a documentação fale sobre transfer.fsckObjects
estar desabilitado por padrão, - ele apenas desativa a validação da estrutura e sintaxe do objeto, não a verificação de hash.)
Shouldn't there be checks against this, somewhere, somehow?
Uma verificação completa pode ser feita manualmente usando o comando git fsck
. É uma boa ideia fazer um cronjob em seus repositórios 'centrais'. A verificação completa não é automatizada porque levaria um tempo excessivo para verificar novamente o repositório completo em cada commit / push / pull / whatever para todos, exceto os menores repositórios Git.
Uma verificação parcial acontece implicitamente sempre que o git decide executar o processo de manutenção em segundo plano git gc --auto
. Essa manutenção lê todos os objetos 'soltos' recentemente criados e os arquiva em um arquivo .pack, portanto a verificação desses objetos é feita gratuitamente. (No entanto, em vez de executar em um agendamento predefinido, ele é executado sempre que você tiver mais objetos soltos do que o limite definido.)