git reflog

Esta página apresenta informações sobre o comando git reflog. O Git monitora as atualizações das pontas das ramificações com um mecanismo chamado logs de referência ou "reflogs." Muitos comandos do Git aceitam um parâmetro para especificar uma referência ou "ref", que é um indicador de um commit. Exemplos comuns incluem:

  • git checkout
  • git reset
  • git merge

Os reflogs monitoram quando referências do Git são atualizadas no repositório local. Além de reflogs de pontas de ramificações, é mantido um reflog especial para o Git stash. Os reflogs são armazenados em diretórios sob o diretório .git do repositório local. Os diretórios do git reflog podem ser encontrados em .git/logs/refs/heads/., .git/logs/HEAD e também .git/logs/refs/stash se o git stash tiver sido usado no repositório.

Falamos bastante sobre o git reflog na página Como reescrever o histórico. Este documento cobre: opções de configuração aprofundadas do git reflog, funções comuns e armadilhas do git reflog, como desfazer alterações com o git reflog e mais.

Função básica

A função mais básica do Reflog é a invocação:

 git reflog 

Em resumo, é um atalho equivalente a:

 git reflog show HEAD 

Esse comando vai emitir o reflog do HEAD. Você vai visualizar algo como:

 eff544f HEAD@{0}: commit: migrar conteúdo existente bf871fd HEAD@{1}: commit: Adicionar definição do Git Reflog 9a4491f HEAD@{2}: confirmação: mover da principal para o git_reflog 9a4491f HEAD@{3}: confirmação: mover do Git_Config para a principal 39b159a HEAD@{4}: commit: expandir no git context 9b3aa71 HEAD@{5}: commit: mais definição de cor f34388b HEAD@{6}: commit: expandir no suporte de cor 9962aed HEAD@{7}: commit: um editor do git -> o editor do Git 

Visite a página Como escrever o histórico para ver outro exemplo de acessos comuns do reflog.

Referências do reflog

Por padrão, o git reflog vai gerar o reflog da referência do HEAD. O HEAD é uma referência simbólica à ramificação ativa no momento. Os reflogs também estão disponíveis para outras referências. A sintaxe para acessar uma referência do git é nome@{qualificador}. Além de referências do HEAD, outras ramificações, tags, remotos e o Git stash também podem ser referenciados.

Você pode obter um reflog completo de todas as referências ao executar:

  git reflog show --all 

Para ver o reflog de uma ramificação específica, transfira o nome dessa ramificação para git reflog show

 git reflog show otherbranch 9a4491f otherbranch@{0}: commit: seperate articles into branch PRs 35aee4a otherbranch{1}: commit (initial): initial commit add git-init and setting-up-a-repo docs 

A execução desse exemplo vai mostrar um reflog para a ramificação otherbranch. O exemplo a seguir presume que você já fez stash de algumas alterações com o comando git stash.

 git reflog stash 0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro 

Essa ação vai gerar um reflog do Git stash. Os indicadores de referência que retornaram podem ser transmitidos a outros comandos do Git:

 git diff stash@{0} otherbranch@{0} 

Quando executado, esse código de exemplo vai exibir os resultados do Git diff comparando as alterações de stash@{0} em relação à referência da otherbranch@{0}.

Reflogs temporizados

Todas as entradas de reflog têm um registro de tempo anexado. Esses registros podem ser aproveitados como o código qualificador da sintaxe do indicador de referência do Git. Ele permite que os reflogs do Git sejam filtrados pelo tempo. Os exemplos a seguir mostram qualificadores temporais disponíveis:

  • 1.minuto.atrás
  • 1.hora.atrás
  • 1.dia.atrás
  • ontem
  • 1.semana.atrás
  • 1.mês.atrás
  • 1.ano.atrás
  • 17-05-2011.09:00:00

Os qualificadores temporais podem ser combinados (e.g. 1.day.2.hours.ago), Formas no plural também são aceitas (e.g. 5.minutes.ago).

Referências de qualificadores temporais podem ser transmitidas a outros comandos do git.

  git diff master@{0} master@{1.day.ago} 

Esse exemplo diferencia a branch principal atual da branch principal de 1 dia atrás. É muito útil se você quiser saber quais alterações ocorreram dentro de certo período.

Subcomandos e opções de configuração

O git reflog aceita alguns argumentos adicionais que são considerados subcomandos.

Show — git reflog show

A transmissão de show é implícita por padrão. Por exemplo, o comando:

 git reflog master@{0} 

equivale ao comando:

 git reflog show master@{0} 

Ainda, o git reflog show é um alias para git log -g --abbrev-commit --pretty=oneline. A execução do git reflog show vai exibir o log para o transmitido.

Expire — git reflog expire

O subcomando expire limpa entradas de reflog antigas ou inacessíveis. Ele pode acarretar perda de dados e não é usado com frequência pelos usuários finais, apenas pelo git de forma interna. A execução de uma opção -n ou --dry-run para o git reflog expire vai realizar um "dry run" que vai exibir quais entradas de reflog estão marcadas para limpeza, mas não vai realizar a ação de fato.

Por padrão, o prazo de validade dos reflogs é de 90 dias. O prazo de validade pode ser definido pela transmissão de um argumento de linha de comando --expire=time para o git reflog expire ou pela definição de um nome de configuração do git para gc.reflogExpire.

Delete - git reflog delete

O subcomando delete é autoexplicativo e vai excluir uma entrada de reflog que foi transmitida. Assim como o expire, o delete pode acarretar perda de dados e não é invocado com frequência por usuários finais.

Como recuperar commits perdidos

O Git jamais perde algo, mesmo durante operações de reescrita de histórico como rebase ou correção de commits. Em relação ao próximo exemplo, faz de conta que a gente alterou algumas coisas no repositório. O git log --pretty=oneline está mais ou menos assim:

 338fbcb41de10f7f2e54095f5649426cb4bf2458 conteúdo expandido 1e63ceab309da94256db8fb1f35b1678fb74abd4 grupo de conteúdos c49257493a95185997c87e0bc3a9481715270086 definir intro eff544f986d270d7f97c77618314a06f024c7916 migrar conteúdo existente bf871fd762d8ef2e146d7f0226e81a92f91975ad Adicionar definição do Git Reflog 35aee4a4404c42128bee8468a9517418ed0eb3dc commit inicial adicionar git-inic e documentos de configuração-de-um-repo 

Depois, a gente dá commit nessas alterações e executa o seguinte:

 #fazer alterações no HEAD git commit -am "algumas alterações de WIP" 

É mais ou menos assim que o log fica após a adição do commit novo:

 37656e19d4e4f1a9b419f57850c8f1974f871b07 algumas alterações de WIP 338fbcb41de10f7f2e54095f5649426cb4bf2458 conteúdo expandido 1e63ceab309da94256db8fb1f35b1678fb74abd4 grupo de conteúdos c49257493a95185997c87e0bc3a9481715270086 definir intro eff544f986d270d7f97c77618314a06f024c7916 migrar conteúdo existente bf871fd762d8ef2e146d7f0226e81a92f91975ad Adicionar definição do Git Reflog 35aee4a4404c42128bee8468a9517418ed0eb3dc commit inicial adicionar git-inic e documentos de configuração-de-um-repo 

Nesse ponto, vamos realizar um rebase interativo na branch principal através da execução de...

 git rebase -i origin/master 

Durante o rebase, os commits são marcados para squash com o subcomando s de rebase. Nesse processo, alguns commits passam por squash para o commit "algumas alterações de WIP" mais recente.

Devido ao squash dos commits, a definição do git log fica mais ou menos assim:

 40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs algumas alterações de WIP 35aee4a4404c42128bee8468a9517418ed0eb3dc commit inicial adicionar git-inic e documentos de configuração-de-um-repo 

Analisando o git log nesse ponto, parece que os commits marcados para squash não existem mais. E se a gente quiser operar em um dos commits que passaram por squash? Talvez para excluir as alterações do histórico? É uma oportunidade para usar o reflog.

 git reflog 37656e1 HEAD@{0}: rebase -i (finalizar): retornando para refs/heads/git_reflog 37656e1 HEAD@{1}: rebase -i (iniciar): confirmar origem/principal 37656e1 HEAD@{2}: commit: algumas alterações de WIP 

É possível ver que existem entradas de reflog para o início e o fim do rebase e o commit "algumas alterações de WIP" antes deles. É possível transferir a referência do reflog para o git reset e redefinir para um commit que existia antes do rebase.

 git reset HEAD@{2} 

A execução desse comando de redefinição vai transferir o HEAD para o commit a que o "algumas alterações de WIP" foi adicionado, restaurando, em essência, os outros commits que passaram por squash.

Resumo

Neste tutorial, a gente falou sobre o comando git reflog. Alguns dos principais pontos apresentados foram:

  • Como visualizar o reflog de ramificações específicas
  • Como desfazer um rebase do git com o reflog
  • Como definir e visualizar entradas de reflog temporizadas

A gente mencionou que o git reflog pode ser usados com outros comandos do git, como o git checkout, git reset e o git merge. Saiba mais nas respectivas páginas. Para ver mais informações sobre referências e reflog, saiba mais aqui.

Pronto para aprender sobre o Git?

Experimente este tutorial interativo.

Comece agora mesmo