Corrigindo cabeçalhos de objeto git

3

Eu tenho um repositório git que não está corrompido (todos os arquivos de objeto permanecem, posso me comprometer com ele e assim por diante).

Recentemente, notei que alguns commits antigos estão quebrados, "error in commit":

git fsck --full
Checking object directories: 100% (256/256), done.
error in commit 1e04e033e642f9310bd7b0e6745f3ef775a15f15: invalid author/committer line - bad email

Eu dei uma olhada no commit individual:

zpipe -d < .git/objects/1e/04e033e642f9310bd7b0e6745f3ef775a15f15
commit 276tree 591e98a0b53880a22f18f5bedefe133166d3e67d
parent 4c33ebce11897dd52528defa41890eabc59135e3
author Martin Lindhe <[email protected]
> 1382869510 +0100
committer Martin Lindhe <[email protected]
> 1382869510 +0100

commit message

Como visto aqui, os e-mails têm uma nova linha à direita (0x0a, conforme mostrado por piping to xxd)

É possível corrigir o cabeçalho do objeto?

    
por Martin Olika 03.09.2014 / 17:54

1 resposta

0

Antes de tudo, faça um backup do seu repositório local.

Suponha que sua confirmação corrompida seja <corrupted> .

Primeiro, crie um novo objeto de confirmação baseado no objeto corrompido:

git commit-tree -m "New message line 1" -m "Line 2" <corrupt>^{tree} -p <corrupt>^1

Nota: adapte seu comando (-p para pais adicionar, -m para linhas de mensagem de commit, etc). Veja a página man do git-commit-tree para lidar com o nome / email do autor, etc.

Você receberá um novo commit SHA-1: <fixed> .

Agora, faça uma substituição de commit (enxerto):

git replace <corrupted> <fixed>

Isto fará um "enxerto" que irá alterar artificialmente o seu commit corrompido com o fixo.

Esta modificação é reversível: você pode removê-la ou mostrá-la através do comando git-replace (veja a man page!) ou procurando no diretório .git/refs/replace/ .

Para torná-lo permanente, use git filter-branch , mas toda a parte alterada será feita de novos objetos de confirmação (ou seja, novos SHA-1s) .

# HEAD should point to the most recent commit (certainly master)...
git filter-branch <fixed>~1..HEAD

Por fim, delate seu substituto (agora permanente em seu histórico):

git replace -d <corrupted>

Isso funciona bem com uma ramificação mestre, mas se você tiver várias ramificações ativas (criadas depois de < corrompido >), você terá que rebase todas elas assim:

git rebase --onto <new-root-branch> <old-root-branch> <branch>

Onde:

  • <new-root-branch> é o commit do qual o branch deve iniciar agora (nova base SHA-1);
  • <old-root-branch> é o commit do qual a ramificação foi iniciada antes da chamada da ramificação do filtro;
  • <branch> é o ramo para rebase.

Encontre estes SHA-1s com comandos de log como:

git log --graph --decorate --all --pretty=oneline

Quando você checou que tudo está OK (ramificações, etc.) e quando todo mundo vinculado ao seu repositório git está completamente ciente do que está acontecendo, você pode git push --force suas modificações. / p>     

por 22.10.2016 / 15:04

Tags