AJUDA!

Se você acabou de perder algum trabalho no Git e você está tentando recuperar seus commits perdidos, esta página é para você. Talvez você tenha tentado um rebase, ou se perdeu numa porção de conflitos de merge, e o Git não fez o que você achou que ira fazer, e agora você não consegue ver o commit que contém suas últimas horas de trabalho.

Não Entre em Pânico.

Provavelmente você não fez nada exótico. Seu commit provavelmente ainda está lá no disco e você somente não consegue vê-lo.

Descubra onde você está neste momento

Eu vou assumir que você está num branch. Você pode confirmar isso digitando git status no seu repositório. A primeira linha deve dizer "On branch master" (ou "On branch branch-muito-importante" ou seja lá qual for o nome do branch em que você está). Se não, por favor faça um backup do seu diretório antes de continuar e tente conseguir ajuda de algum especialista! Eu não tenho como cobrir todas as possibilidades num documento como este e detestaria piorar a sua situação neste momento.

Se a segunda linha não diz "nothing to commit (working directory clean)", você tem alterações que ainda não foram salvas. Você pode ser capaz de salvá-las usando 'git stash', ou você pode copiar alguns arquivos para outro diretório se for muito paranóico. Ou talvez você nem ligue...

Se você estava no meio de um rebase e alguma coisa esquisita aconteceu, talvez você possa digitar git rebase --abort e voltar para uma situação anterior ao problema. Primeiro, porém, tente navegar no seu histórico do console; o Git imprime uma mensagem dizendo o que você deve fazer toda vez que ele para durante um rebase.

Se você tentou um merge e ficou preso resolvendo conflitos de merge horrorosos, git status pode incluir uma mensagem como "Unmerged paths:" seguida por uma lista de arquivos. Se você só quer desfazer o merge, você provavelmente pode usar git reset para fazer isso. Se você realmente tem certeza de que não precisa das alterações atuais (ou seja, você começou o merge a partir de um estado de trabalho limpo), git reset --hard pode ser o que você quer.

Se você fez um merge e parece que deu certo, mas agora quer desfazê-lo, simplesmente use git reset --hard para apontar o seu branch de volta para o commit em que ele estava logo antes de você fazer o merge. (Você deve poder ver isso na saída do git log ou seu visalizador, mas se não conseguir, continue lendo.)

Procurando seu commit perdido

Em qualquer branch que você esteja, essa é a boa notícia: o Git guarda todo commit para o qual aquele branch tenha apontado em qualquer momento. Ele faz isso no que é chamado de 'reflog' (uma abreviação de "reference log", ou histórico de referências) para seu branch, que fica no seguinte arquivo texto: [repository-root]/.git/logs/refs/heads/[branch-name]. O reflog para o branch master está em .git/logs/refs/heads/master, e o reflog para branch-muito-importante está em .git/logs/refs/heads/branch-muito-importante, e assim por diante.

Então... Respire fundo, va até a raiz do seu repositório na linha de comando, e digite isso: cat .git/logs/refs/heads/master

Você deve ver uma porção de linhas no formato:

[SHA1 antigo] [SHA1 novo] [Autor] [Data/hora] [Mensagem de commit]

As linhas mais novas estão no final. A partir daqui, você deve ser capaz de achar a linha contendo a mensagem de commit para o commit que você quer tanto recuperar. A segunda coluna nessa linha é o SHA1 que você quer. Selecione esse sem vergonha e copie para sua área de transferência.

Pegando seu trabalho de volta

Isso vai ser um pouco decepcionante, mas é isso que você fará:

git checkout deadbeef # onde 'deadbeef' é o SHA1 que você acabou de encontrar e copiar git branch eu_quero_o_codigo_de_volta

Se você está usando um visualizador como GitX ou gitk, volte para ele e atualize a visualização. (Você pode precisar forçá-lo a mostrar todos os branches locais). Ou, faça git log --pretty=oneline --abbrev-commit --branches=* --graph --decorate se você é raiz. Seu commit deve estar visível de novo, com um branch 'eu_quero_o_codigo_de_volta' ao lado dele.

Resumindo

Eu espero que isso tenha sido útil. De qualquer forma, por favor me escreva por email ou Twitter e me avise se houver maneiras de melhorar este guia.

Depois que a sua frequência cardíaca baixar um pouco, você pode dar uma passeada neste site. Não deve levar mais de uma hora para lera a coisa toda, mas se você estiver com pressa, dê uma olhada na página TL;DR.

No resto da Internéte, veja o The Illustrated Guide to Recovering Lost Commits With Git quando tiver uma meia hora para estudar os exemplos.

Bom hacking!
-Sam