git reflog
Saiba como usar o git reflog para recuperar commits perdidos, explorar referências e subcomandos, filtrar por tempo e ver exemplos práticos.
O comando git reflog é a sua rede de segurança. Ele registra todas as alterações feitas em referências locais — branches, HEAD e stashes — para que você possa recuperar commits que parecem ter desaparecido após um reset, rebase, amend ou exclusão de branch. Esta página explica o que o reflog armazena, como ler sua sintaxe name@{n}, como filtrar entradas por tempo, os subcomandos disponíveis e um passo a passo completo para recuperar commits "perdidos".
O que é o reflog
Uma referência (ou "ref") é um ponteiro para um commit — HEAD, a ponta de um branch como main, ou uma entrada de stash. Muitas operações do Git movem esses ponteiros: cada git commit, checkout, merge, rebase ou reset atualiza para onde uma ref aponta. O reflog ("reference log") registra esse histórico de movimentos.
Isso é importante porque o Git quase nunca exclui commits imediatamente. Quando uma operação como um hard reset ou um rebase torna um commit inacessível a partir de qualquer branch ou tag, o objeto de commit ainda existe no repositório e o reflog ainda mantém um ponteiro para ele. Enquanto essa entrada do reflog existir, você pode recuperar o commit.

O reflog é estritamente local e por clone. Ele nunca é enviado via push ou recebido via fetch, portanto um clone recente tem um reflog vazio. Se você reescrever o histórico e perder um commit, só é possível recuperá-lo na máquina onde o trabalho foi realizado.
Uso básico
A forma mais simples não recebe argumentos:
git reflogIsso é um atalho para exibir o reflog de HEAD:
git reflog show HEADA saída lista cada posição que HEAD ocupou, da mais recente para a mais antiga:
a32556a HEAD@{0}: commit: migrating content
ab371fd HEAD@{1}: commit: adding git reflog outline
23a491a HEAD@{2}: checkout: moving from stage to feature/solver
7b119cb HEAD@{3}: checkout: moving from feature/solver to stage
56a183a HEAD@{4}: commit: changing color scheme
7a2aa71 HEAD@{5}: commit: adding more color palettes
a56322b HEAD@{6}: commit: adding color tool packageLeia cada linha como três partes:
a32556a— o hash abreviado do commit para o qualHEADapontava.HEAD@{0}— o seletor do reflog.@{0}é a posição mais recente,@{1}a anterior, e assim por diante, contando de trás para frente no tempo.commit: migrating content— a ação que moveu a ref, junto com sua mensagem.
O rótulo da ação informa como a ref foi movida (commit, checkout, merge, rebase -i, reset), o que torna o reflog legível como um histórico passo a passo do que você fez localmente.
Referências do reflog
Por padrão, o git reflog exibe o reflog de HEAD, que acompanha qualquer branch que esteja atualmente em checkout. Mas toda ref mantém seu próprio reflog, e você acessa qualquer um deles com a sintaxe name@{qualifier}.
Para ver o reflog de todas as referências de uma vez:
git reflog show --allPasse um nome de branch para inspecionar apenas o histórico daquele branch. Abaixo, o reflog para test_branch:
git reflog show test_branch
32a591f test_branch@{0}: commit: add snippets
23bae4a test_branch@{1}: commit (initial): initial commitObserve a diferença: HEAD@{1} significa "onde HEAD estava um movimento atrás," enquanto test_branch@{1} significa "onde o próprio test_branch estava um movimento atrás." Essa distinção é o que permite recuperar a ponta de um branch que um hard reset ou uma atualização forçada moveu.
Você também pode ler o reflog do git stash:
git reflog stash
0d44de3 stash@{0}: WIP on git_reflog: a567574 adding Vue.jsReflogs com filtro de tempo
Cada entrada do reflog possui um timestamp associado. Eles podem ser usados como qualificadores na sintaxe de ponteiro de ref do Git, permitindo filtrar os reflogs por tempo. Veja alguns exemplos de qualificadores de tempo:
- 1.minute.ago
- 1.hour.ago
- 1.day.ago
- yesterday
- 1.week.ago
- 1.month.ago
- 1.year.ago
- 2011-05-17.09:00:00
Você pode combinar qualificadores (por exemplo, 1.week.3.hours.ago) e usar formas no plural (por exemplo, 5.hours.ago). Uma ref qualificada por tempo pode ser passada para outros comandos do Git, não apenas para o git reflog:
git diff master@{0} master@{1.week.ago}Isso exibe um diff do master atual em relação a onde master apontava há uma semana.
Um qualificador de tempo é resolvido em relação ao reflog, não às datas de commit. master@{1.week.ago} significa "o commit ao qual master fazia referência há uma semana nesta máquina," o que pode ser diferente de "o commit criado há uma semana." Em um clone recente sem histórico de reflog, o Git usa a ponta atual como fallback e pode avisar que o log é curto demais.
Subcomandos do git reflog
O git reflog aceita vários argumentos que funcionam como subcomandos. Eles são descritos abaixo.
git reflog show
git reflog show é o comportamento padrão e é um alias para git log -g --abbrev-commit --pretty=oneline. Esses dois comandos são equivalentes:
git reflog master@{0}
git reflog show master@{0}git reflog expire
git reflog expire remove entradas antigas ou inacessíveis do reflog. Como a remoção de entradas pode tornar commits genuinamente irrecuperáveis, raramente se executa esse comando manualmente — o Git o executa automaticamente durante o git gc. Por padrão, entradas acessíveis expiram após 90 dias (gc.reflogExpire) e as inacessíveis após 30 dias (gc.reflogExpireUnreachable). Para forçar uma expiração personalizada:
git reflog expire --expire=1.day.ago --allgit reflog delete
git reflog delete remove uma entrada específica do reflog pelo seu seletor. Assim como o expire, ele apresenta um risco real de perda de recuperabilidade e raramente é necessário no trabalho cotidiano:
git reflog delete HEAD@{1}Assim que uma entrada do reflog expirar ou for excluída, o commit ao qual ela apontava torna-se verdadeiramente inacessível e será removido na próxima vez que git gc for executado. Trate expire e delete como ferramentas de limpeza, não como ferramentas de desfazer.
Recuperando commits perdidos
Os commits nunca são verdadeiramente perdidos no Git, mesmo durante operações de reescrita de histórico — e o reflog é a maneira de recuperá-los. Suponha que git log --pretty=oneline exiba o seguinte:
2b43ceab309da94256db8fb1f35b1678fb74abd4 changes in content
c32557493a95185997c87e0bc3a9481715279351 adding Vue.js
abc234f986d270d7f97c77618314a06f024c4563 migrating content
a5673cd762d8ef2e146d7f0226e81a92f91956b1 adding git reflog outline
2bce4a4404c42128bee8468a9517418ed0ea412 initial commitAgora suponha que fazemos o commit de algumas alterações novas neste repositório:
# make changes to HEAD
git commit -am "API changes"O log agora tem a seguinte aparência:
37656e19d4e4f1a9b419f57850c8f1974f871b07 API changes
2b43ceab309da94256db8fb1f35b1678fb74abd4 changes in content
c32557493a95185997c87e0bc3a9481715279351 adding Vue.js
abc234f986d270d7f97c77618314a06f024c4563 migrating content
a5673cd762d8ef2e146d7f0226e81a92f91956b1 adding git reflog outline
2bce4a4404c42128bee8468a9517418ed0ea412 initial commitEm seguida, iniciamos um rebase interativo em relação ao master:
git rebase -i origin/masterDurante o rebase, marcamos os commits com a ação s (squash) para mesclá-los ao commit mais recente de "API changes". Após isso, a saída do git log fica reduzida a:
40d8a1237656e19d4e4f1a9b419f57850c8f1974 API changes
35aee4a4404c42128bee8468a9517418ed0eb3dc initial commitOs commits mesclados parecem ter desaparecido. Mas o reflog ainda registra cada posição que HEAD ocupou durante o rebase:
git reflog
37656e1 HEAD@{0}: rebase -i (finish): returning to refs/heads/git_reflog
37656e1 HEAD@{1}: rebase -i (start): checkout origin/master
37656e1 HEAD@{2}: commit: API changesHEAD@{2} é o estado imediatamente antes do rebase começar. Passe esse seletor para o git reset para retornar a ele:
git reset --hard HEAD@{2}Isso move HEAD de volta para o commit "API changes" anterior ao rebase e restaura todos os commits mesclados. Use --hard para também redefinir a árvore de trabalho para esse estado, ou omita-o (git reset HEAD@{2}) para mover apenas o ponteiro do branch mantendo os arquivos atuais.
Quando usar o git reflog
Recorra ao reflog sempre que uma ref tiver sido movida e você quiser recuperá-la:
- Após um
git reset --hardque descartou commits que você realmente precisava. - Para recuperar commits órfãos por um rebase interativo, amend ou squash.
- Para restaurar um branch excluído com
git branch -D(encontre sua última ponta no reflog e depois executegit branch <name> <hash>). - Para descobrir onde
HEADestava antes de uma série confusa de checkouts ou merges.
Se o commit for mais recente do que a janela de expiração do reflog (90 dias para entradas acessíveis por padrão), ele é recuperável.
Páginas relacionadas
- git reset — mova refs para uma entrada do reflog para desfazer alterações.
- git rebase — a operação de reescrita que o reflog mais frequentemente resgata.
- git stash — os stashes têm seu próprio reflog em
stash@{n}. - git log — a visualização de histórico padrão;
git log -glê o reflog.