Ontem me deparei com um problema de corrupção em um repositório git, e depois de apanhar um pouco, consegui resolver o problema. Estou documentando o passo a passo para referencia futura.
A seguinte mensagem de erro aparecia ao tentar clonar um repositório bare (com outros comandos também ocorria, como ”git gc”):
Counting objects: 119213, done. Delta compression using up to 2 threads. Compressing objects: 100% (22370/22370), done. error: bad packed object CRC for ca94d22d6c8cee73c2901b396183f5c8cebdb37a error: bad packed object CRC for ca94d22d6c8cee73c2901b396183f5c8cebdb37a error: failed to read object ca94d22d6c8cee73c2901b396183f5c8cebdb37a at offset 116202510 from /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack fatal: object ca94d22d6c8cee73c2901b396183f5c8cebdb37a is corrupted error: failed to run repack
A interpretação final foi que o objeto com SHA1 ca94d22d6c8ce…, que neste repositório já havia sido empacotado no arquivo pack-87aa0cf7ddb97fe5482cb…, estava corrompido. (Este empacotamento é feito por um ”git gc”, ”git repack”, ou automaticamente durante o merge, se habilitado, para melhorar o desempenho do repositório)
Algo muito bom num repositório distribuído é que cada clone funciona como um backup. Cada cópia de trabalho contem todo o histórico e todos os objetos existentes no repositório clonado desde a última atualização (fetch). De forma que, se este mesmo objeto (blob) existe em algum repositório clonado e não está corrompido, pode ser utilizado para substituir o arquivo corrompido no repositório com problema.
O objeto pode ser encontrado e extraído em algum repositório cópia com o seguinte comando:
git show -p ca94d22d6c8cee73c2901b396183f5c8cebdb37a > blob.bin
Este comando gera o arquivo blob.bin, que contém o conteúdo do objeto ca94d22d6c8ce. O mesmo deve ser copiado (ssh, scp) para o computador/repositório corrompido, ex:
scp blob.bin gitadmin@ip.com:~/
No repositório corrompido, executar:
git hash-object -w ~/blob.bin
Isso irá re-escrever o blob no repositório e um ”git gc” deve mostrar que o problema foi solucionado.
Pode ser necessário um passo adicional no repositório corrompido: desempacotar o pack onde o blob está contido e removê-lo da pasta packs. O nome e caminho do arquivo foi exibido na mensagem original pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack:
git unpack-objects /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack mv /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.* ~/ git hash-object -w ~/blob.bin
Esta solução pode ainda ser aplicada para blob”s faltantes, mensagens exibidas por ”git fsck” similares a:
error: ca94d22d6c8cee73c2901b396183f5c8cebdb37a: object corrupt or missing missing blob ca94d22d6c8cee73c2901b396183f5c8cebdb37a