git: “pacote tem objeto ruim” ao empurrar para remoto

3

Eu tenho um repositório git simples no meu Raspberry Pi que só eu uso. Ao enviar para ele hoje, recebi esta mensagem de erro:

Counting objects: 460, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (367/367), done.
remote: fatal: pack has bad object at offset 1641: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

Como você pode ver, o repositório é acessado via ssh. (Eu mudei o endereço IP.)

Eu tentei várias vezes, mas recebi o mesmo erro (mesmo com os mesmos números). Então decidi criar um novo repositório, apagando a pasta do antigo, criando uma pasta com o mesmo nome e executando git init --bare dentro dele.

Agora recebo este erro ao enviar para ele:

Counting objects: 3129, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2265/2265), done.
remote: fatal: pack has bad object at offset 426983445: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

Qual é o problema e como faço para que ele funcione novamente?

Eu rodei a versão 1.9.1 do git em uma máquina Linux kernel de 64 bits de 64 bits.

Atualizando com saída extra:

laptop-14-04:~/Documents Container$ GIT_TRACE=1 git push --porcelain --progress --recurse-submodules=check origin refs/heads/master:refs/heads/master
trace: built-in: git 'push' '--porcelain' '--progress' '--recurse-submodules=check' 'origin' 'refs/heads/master:refs/heads/master'
trace: run_command: 'ssh' '[email protected]' 'git-receive-pack '\''/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'\'''
[email protected]'s password: 
trace: run_command: 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
trace: exec: 'git' 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
trace: built-in: git 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
Counting objects: 3383, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2257/2257), done.
remote: fatal: pack has bad object at offset 426983770: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

laptop-14-04:~/Documents Container$ git count-objects -Hv
count: 0
size: 0 bytes
in-pack: 3452
packs: 1
size-pack: 13.03 GiB
prune-packable: 0
garbage: 0
size-garbage: 0 bytes

laptop-14-04:~/Documents Container$ git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3452/3452), done.
laptop-14-04:~/Documents Container$ git gc
Counting objects: 3452, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2254/2254), done.
Writing objects: 100% (3452/3452), done.
Total 3452 (delta 915), reused 3452 (delta 915)

laptop-14-04:~/Documents Container$ git push --porcelain --progress --recurse-submodules=check origin refs/heads/master:refs/heads/master
[email protected]'s password: 
Counting objects: 3383, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2257/2257), done.
remote: fatal: pack has bad object at offset 426983770: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

Eu agora instalei um novo sistema operacional (Ubuntu 16.04 64 bit rodando o kernel 4.4.0-21-generic) e o git agora é a versão 2.7.4. Eu não copiei o repositório antigo para o novo sistema, mas copiei apenas o conteúdo dele e criei um novo repositório. Além disso, eu deletei o repo no meu Raspberry Pi e criei um novo repositório nu. Eu agora usei o SmartGit para adicionar os arquivos ao repositório e para tentar empurrá-lo. No entanto, o problema ainda existe:

Funciona se eu criar um repositório vazio localmente, incluí-lo como controle remoto e, em seguida, pressioná-lo. Eu posso transferir o diretório do repositório para o Raspberry Pi e usá-lo como um controle remoto via ssh. Então, parece que o problema só ocorre quando se empurra um monte de dados (ou possivelmente grandes commits) através de uma rede.

    
por UTF-8 19.04.2016 / 23:11

1 resposta

2

O pack-objects (man git-pack-objects ) morreu do sinal 13 ( canal quebrado ), porque git não conseguiu inflar (descompactar) o objeto e falhou com o erro (o código de erro -5 pode significar fora de -mem ou overwrite / overlap error ).

Explicação

De acordo com o manual do zlib , os erros são definidos da seguinte forma:

#define Z_OK            0
#define Z_STREAM_END    1
#define Z_NEED_DICT     2
#define Z_ERRNO        (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR   (-3)
#define Z_MEM_ERROR    (-4)
#define Z_BUF_ERROR    (-5)
#define Z_VERSION_ERROR (-6)

onde -5 significa que nenhum progresso é possível ou se não havia espaço suficiente no buffer de saída.

Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing.

Aqui está o que podemos ler em zlib FAQ :

Before making the call, make sure that avail_in and avail_out are not zero. When setting the parameter flush equal to Z_FINISH, also make sure that avail_out is big enough to allow processing all pending input. Note that a Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be made with more input or output space. A Z_BUF_ERROR may in fact be unavoidable depending on how the functions are used, since it is not possible to tell whether or not there is more output pending when strm.avail_out returns with zero. See zlib Usage Example for a heavily annotated example.

Solução

Isso pode estar relacionado a poucas coisas:

  • o objeto que está sendo empurrado é muito grande, então o zlib é de memória, então você precisa de mais espaço no buffer zlib de saída,

    Nesse caso, tente aumentar http.postBuffer , por exemplo

    git config http.postBuffer 134217728 # =~ 128MB
    

    Como alternativa, use bfg para remover bolhas maiores, por exemplo

    java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
    
  • seu objeto está corrompido, então execute git fsck --full e git gc

    O motivo potencial pode estar corrompido na memória ou no dispositivo de armazenamento, portanto, tente novamente em um repositório limpo ou em um computador diferente.

  • pode ser um bug git, pois não deve abortar em Z_BUF_ERROR , mas para fornecer mais espaço de saída ou mais entrada, consulte: zLib infate () trava ao descompactar o buffer

    Você pode relatar um relatório de bug git para a lista de discussão .

  • poderia ser um problema de inflar do gzip (por exemplo, Isso é um bug nesse método de inflar do gzip? )

  • pode ser um bug antigo do kernel (< = 2.6.32-rc4), então atualize seu kernel

    Veja: Bug # 547503: git-core: "git clone" falha no armel

    The only possibly relevant kernel change I could find was commit 5a3a29f (ARM: 5691/1: fix cache aliasing issues between kmap() and kmap_atomic() with highmem, commit 7929eb9 upstream) from 2.6.31.1. So though I also have my doubts, we could be lucky.msg00049

Outros comandos úteis a serem considerados:

Veja também:

Aqui está a falha do código Git relevante ( builtin/index-pack.c ):

git_inflate_init(&stream);
stream.next_out = buf;
stream.avail_out = buf == fixed_buf ? sizeof(fixed_buf) : size;

do {
    unsigned char *last_out = stream.next_out;
    stream.next_in = fill(1);
    stream.avail_in = input_len;
    status = git_inflate(&stream, 0);
    use(input_len - stream.avail_in);
    if (sha1)
        git_SHA1_Update(&c, last_out, stream.next_out - last_out);
    if (buf == fixed_buf) {
        stream.next_out = buf;
        stream.avail_out = sizeof(fixed_buf);
    }
} while (status == Z_OK);
if (stream.total_out != size || status != Z_STREAM_END)
    bad_object(offset, _("inflate returned %d"), status);
git_inflate_end(&stream);

e git_inflate () do zlib.c

status = inflate(&strm->z,
         (strm->z.avail_in != strm->avail_in)
         ? 0 : flush);
    
por 20.04.2016 / 01:23