trilha

Fundamentos de Programação/02 - Código que Presta/Semana 08 - Git Além do Básico4 min

Reflog

Perguntas-guia
  • O que o reflog registra que o log não registra?
  • Como recuperar um commit "perdido" depois de reset --hard?
  • Por quanto tempo uma entrada sobrevive antes do garbage collector?
  • Reflog é local — o que isso implica para quem tenta te ajudar remotamente?

Conceito

O reflog registra todo movimento de referência — cada mudança de onde HEAD e cada branch apontaram, com timestamp e motivo.

A diferença que faz o reflog ser salvação

git log mostra o histórico alcançável. O reflog mostra onde as referências estiveram.

Quando você faz reset --hard, o commit não é apagado — ele fica órfão: ainda existe no banco de objetos, mas nenhuma referência aponta para ele, então o log não o encontra. O reflog guarda o endereço.

É por isso que quase nada em git local é irreversível enquanto o commit existir.

Expiração — e é isso que define a janela de recuperação:

Tipo de entrada Prazo padrão Config
alcançável 90 dias gc.reflogExpire
inalcançável (órfã) 30 dias gc.reflogExpireUnreachable

Passado o prazo, git gc pode remover o objeto de verdade. Trinta dias é bastante — e não é infinito.

O reflog é local e por clone. Ele não é empurrado, não é clonado, não existe no servidor. Duas consequências práticas:

  • um clone novo não tem o seu reflog
  • "me ajuda a recuperar" exige acesso à sua máquina; ninguém recupera remotamente

Na prática

Cenário verificado: comitei algo importante e destruí com reset --hard.

$ git reset --hard HEAD~1
$ git log --oneline | wc -l
1                                  # só um commit
$ git log --oneline | grep -c IMPORTANTE
0                                  # o log NÃO encontra

$ git reflog
3477743 HEAD@{0} reset: moving to HEAD~1
981e18a HEAD@{1} commit: commit 2 IMPORTANTE      <- está aqui
3477743 HEAD@{2} commit (initial): commit 1

$ git reset --hard 981e18a
  recuperado? 1 | conteúdo: a b

Leia a segunda coluna do reflog: ela é a narrativa do que você fezcommit, reset, rebase, checkout, merge. Quando você não sabe o que aconteceu, o reflog é o histórico das suas ações, não do projeto.

Respostas às perguntas-guia

1. O que o reflog registra que o log não registra?

Movimentos de referência, incluindo os que tornam commits inalcançáveis. O log só percorre o que é alcançável a partir das refs atuais; o reflog guarda onde as refs estiveram.

2. Como recuperar um commit "perdido" depois de reset --hard?

git reflog                      # ache a linha anterior ao reset
git reset --hard <sha>          # volta a branch para lá
# ou, sem mexer na branch atual:
git branch recuperado <sha>

git branch recuperado <sha> é mais seguro: cria um ponto de referência sem alterar onde você está.

3. Por quanto tempo uma entrada sobrevive antes do garbage collector?

90 dias se alcançável, 30 dias se órfã. Depois disso, git gc pode remover o objeto. Para aumentar num repo crítico:

git config gc.reflogExpireUnreachable 365.days

4. Reflog é local — o que isso implica para quem tenta te ajudar remotamente?

Que não dá. O reflog não é empurrado nem clonado. Se você perdeu trabalho e o commit nunca foi empurrado, a única cópia está na sua máquina — e ela expira. Recupere antes de rodar git gc, e não clone de novo esperando resolver.

Armadilhas

  • git gc agressivo encurta a janela. Não rode git gc --prune=now quando estiver procurando algo perdido.
  • Clone novo não tem reflog. Perdeu e clonou de novo? A janela fechou.
  • Reflog de branch é separado do de HEAD. git reflog show minha-branch mostra o histórico daquela ref, que às vezes é o que você quer.
  • Stash descartado também está lá — mas em refs/stash, ou órfão. git fsck --unreachable é o último recurso.
  • Reflog não recupera o que nunca foi comitado. Mudança só no diretório de trabalho, destruída por checkout --, está perdida. Reflog cobre commits, não rascunhos.

Comandos essenciais

git reflog                          # movimentos de HEAD
git reflog show minha-branch        # movimentos daquela branch
git reflog --date=iso               # com data legível
git show HEAD@{2}                   # dois movimentos atrás
git diff HEAD@{yesterday} HEAD      # o que mudou desde ontem
git reset --hard HEAD@{1}           # desfaz o último movimento de HEAD
git branch resgate <sha>            # cria ref sem mexer na branch atual
git fsck --unreachable --no-reflogs # objetos órfãos que o reflog nem lista
git config gc.reflogExpireUnreachable 365.days

Relacionado

  • 1. Rebase vs Merge — o que recupera os commits que o rebase abandonou
  • 3. Stash — stash descartado também é recuperável por aqui
  • 5. Bisectgit bisect log é um registro parecido, do processo de busca

Parte de Semana 08 - Git Além do Básico · 00 - MOC Fundamentos de Programação

Buscar

Busca por título, seção e texto das notas