Fundamentos de Programação/02 - Código que Presta/Semana 08 - Git Além do Básico4 min
Reflog
- 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.
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ê fez — commit, 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 gcagressivo encurta a janela. Não rodegit gc --prune=nowquando 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-branchmostra 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. Bisect —
git 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