O Git é o sistema de controle de versão mais usado atualmente e acompanha as alterações de várias maneiras para garantir que você nunca perca uma alteração confirmada. Além disso, o controle que ele oferece sobre os fluxos de trabalho de desenvolvimento significa que você pode determinar exatamente como será o histórico do seu projeto. O Git tem vários mecanismos para reescrever o histórico de commits para ajudar nisso, incluindo git commit --amend
, git rebase
e git reflog
.
Neste artigo, você aprenderá como utilizar o git reflog
para reorganizar e reescrever seu histórico de commits do Git de maneira fácil e eficaz, ao mesmo tempo em que mitiga o risco que a reescrita do histórico de commits costuma trazer.
O Git usa um sistema chamado log de referência , ou simplesmente " reflog ", para acompanhar as modificações nas pontas dos branches. Uma referência, geralmente conhecida como " ref ", é um ponteiro para um commit ou branch que muitos comandos do Git aceitam como parâmetro. git checkout
, git reset
e git merge
são exemplos de alguns comandos git comuns que aceitam refs como parâmetros.
Por padrão, os reflogs rastreiam cada posição HEAD
nos últimos 90 dias. Além disso, o histórico do reflog é exclusivo do repositório e não pode ser acessado remotamente. Além dos reflogs de ponta de ramificação, há um reflog separado para o Git stash .
Os reflogs são armazenados em diretórios específicos sob o diretório .git
do repositório local. Esses diretórios 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.
Os comandos reflog básicos são os seguintes:
# To see activity on HEAD git reflog show
A saída do comando acima é semelhante à seguinte:
0a2e358 HEAD@{0}: reset: moving to HEAD~2 0254ea7 HEAD@{1}: checkout: moving from 2.2 to main c10f740 HEAD@{2}: checkout: moving from main to 2.2
Outros usos comuns são os seguintes:
# To see activity on HEAD, including timestamp git reflog show --date=relative #or git reflog --relative-date # same, on some_branch git reflog show --date=relative some_branch
Por padrão, git reflog
gera o reflog HEAD
reflog. O símbolo HEAD
denota o ramo atualmente ativo. Também existem reflogs disponíveis para outras referências. A sintaxe usada para acessar um git ref é name@{qualifier}
, por exemplo - otherbranch@{0}
. Além das referências HEAD
, outras ramificações, tags, controles remotos e Git stash também podem ser referenciados.
Para ver o reflog completo de todas as referências, você pode executar:
git reflog show --all
Além dos índices ordenados, cada entrada de reflog tem um carimbo de data/hora anexado a ela que também pode ser aproveitado como um token qualificador para a sintaxe do ponteiro de referência do Git. Isso é o que permite a filtragem dessas entradas de reflog por tempo. Exemplos de qualificadores de tempo comumente usados incluem:
@{0}
@{6.minutes.ago}
@{2.hour.ago}
@{3.day.ago}
@{5.weeks.ago}
@{8.years.ago}
@{today}
@{2022-01-23.08:30:00}
@{1.day.10.hours.ago}
Esses qualificadores de tempo podem ser combinados (por exemplo 1.day.3.hours.ago
). Formas plurais desses qualificadores de tempo também são aceitas (por exemplo 5.minutes.ago
). Eles podem ser usados junto com o comando git reflog
da seguinte forma:
git reflog show develop@{3.days.ago}
git reflog
aceita alguns argumentos adicionais que são considerados como subcomandos, como show
, expire
e delete
. Vamos discutir esses subcomandos em detalhes.
Conforme discutido anteriormente, show
é passado implicitamente por padrão. A execução git reflog show
exibirá o log dos argumentos passados.
Por exemplo:
git reflog develop@{0}
é o mesmo que
git reflog show develop@{0}
Além disso, git reflog show
é um alias para git log -g --abbrev-commit --pretty=oneline
.
O subcomando expire
ajuda na limpeza de entradas de reflog antigas ou inacessíveis.
O subcomando
expire
tem o potencial de causar perda de dados.
No entanto, esse subcomando normalmente não é usado pelos usuários finais, mas pelo git internamente.
Um “dry run” pode ser executado passando uma opção -n
ou --dry-run
para git reflog expire
para a saída cujas entradas de reflog são marcadas para serem removidas, de modo que elas não sejam realmente removidas. Isso pode ajudar como uma rede de segurança ao limpar as entradas reflog expiradas.
Além disso, o tempo de expiração pode ser especificado passando um argumento de linha de comando --expire=time
para git reflog expire
ou definindo um nome de configuração git de gc.reflogExpire
.
O subcomando delete, como o próprio nome indica, exclui a entrada reflog passada. Excluir, como expirar, pode causar perda de dados e não é usado com frequência pelos usuários finais.
git reflog
e git log
são os dois componentes com nomes semelhantes fornecidos pelo Git que nos permitem entrar no histórico de commits, logs e reflogs do repositório. O fato de que os dois componentes geralmente exibem o mesmo histórico, especialmente quando um desenvolvedor conclui uma série de confirmações locais sem buscar ou puxar, é uma das razões para a confusão Git reflog vs. log.
No entanto, eles são essencialmente diferentes e têm casos de uso diferentes.
Vamos entender as diferenças subjacentes, bem como as semelhanças dos dois comandos acima.
A diferença mais notável entre Git reflog e log é que o log é um registro público do histórico de commits do repositório, enquanto o reflog é um registro privado específico do espaço de trabalho dos commits locais do repositório.
Após um push, fetch ou pull, o log Git é replicado como parte do repositório Git. O reflog do Git, por outro lado, não está incluído no repositório duplicado. Sem acesso físico ao computador onde o repositório local é mantido, um desenvolvedor não pode examinar o reflog.
O reflog é um arquivo encontrado em .git\logs\refs\heads
que rastreia o histórico de commits locais para uma ramificação específica e exclui quaisquer commits que possam ter sido eliminados pelos processos de coleta de lixo do Git. O log do Git, por outro lado, fornece uma travessia de commit histórico de um branch que começa com o commit mais recente e termina com o primeiro commit no histórico do branch.
O Git reflog pode ser usado como uma rede de segurança durante o desenvolvimento, pois você não pode perder dados do seu repositório depois de confirmado se entender o conceito de reflog corretamente. Você pode usar o reflog para ver onde estava antes e git reset --hard
para voltar a esse ref para restaurar seu estado anterior se você redefinir sem querer para um commit mais antigo, rebase incorretamente ou executar qualquer outra operação que visivelmente "remova" comete.
Lembre-se de que refs referem-se ao histórico completo do commit, não apenas ao próprio commit.
Neste artigo, discutimos as opções de configuração estendidas do git reflog
, casos de uso comuns e armadilhas do git reflog
.
Para resumir, o Git mantém um reflog, que é um log de onde suas referências HEAD
e branch estiveram nos últimos meses (90 dias), em segundo plano enquanto você está trabalhando. O Git salva informações neste histórico temporário toda vez que sua ponta de ramificação é modificada por qualquer motivo.
O comando reflog também pode ser usado para excluir ou expirar entradas muito antigas do reflog. O subcomando expire
the é usado para remover entradas reflog desatualizadas e o subcomando delete
é usado para excluir e especificar a entrada específica a ser excluída do reflog.