Nesta página

git log

Em resumo: git log é a principal ferramenta do Git para auditar o histórico de um projeto. Ele percorre o Grafo Acíclico Direcionado (DAG) de commits, começando no ponto atual do checkout (HEAD), lendo os hashes dos pais e caminhando recursivamente para trás no tempo até o commit raiz inicial. É uma ferramenta poderosa de pesquisa e análise, não apenas uma lista simples baseada em texto.

Uma observação sobre os hashes abaixo: os IDs de commit e de árvore nesta lição são representativos. Um hash de commit é calculado a partir da árvore, dos pais, das identidades do autor/committer e do timestamp do commit — portanto, ao executar os mesmos comandos, você obterá a mesma estrutura de grafo com IDs diferentes. Os timestamps exibidos são segundos desde a época Unix, com deslocamento +0000 (UTC).


O que git log realmente faz?

Para entender como git log gera seu histórico, você precisa observar como o Git organiza os commits. O Git não armazena seus commits em uma lista ou matriz plana. Em vez disso, ele os estrutura como um Grafo Acíclico Direcionado (DAG).

Nesse grafo:

  • Nós: são seus objetos de commit.
  • Arestas: são ponteiros de um commit filho para seu(s) commit(s) pai(s). Elas são direcionadas (apontam para trás no tempo) e acíclicas (o histórico não pode voltar a um ponto anterior formando um ciclo).
graph RL
    C3[Commit 3<br>HEAD / main] -->|parent| C2[Commit 2]
    C2 -->|parent| C1[Commit 1<br>Root Commit]

Quando você invoca git log, o Git não varre todo o seu disco. Em vez disso, ele executa uma travessia do grafo a partir de um ponto de entrada definido — por padrão, o commit apontado por HEAD (sua localização atual, link git-checkout).

O algoritmo de travessia

  1. O Git lê o arquivo .git/HEAD para determinar seu branch ativo (por exemplo, ref: refs/heads/main).
  2. Ele resolve a referência do branch para seu hash de commit de 40 caracteres lendo .git/refs/heads/main (por exemplo, 8a4c10...).
  3. Ele carrega o objeto de commit 8a4c10... do banco de objetos (.git/objects/) e extrai os metadados: autor, committer, timestamp, mensagem e o hash parent.
  4. O Git exibe os detalhes desse commit no console.
  5. O Git coloca o hash do pai (por exemplo, 55a420...) em uma fila de travessia.
  6. O ciclo se repete: o Git retira da fila o próximo hash de commit, lê o objeto, exibe suas informações e coloca seus pais na fila.
  7. A travessia para quando um commit não tem o campo parent, o que indica o primeiro commit do repositório (o commit raiz).

No caso de um commit de merge, o objeto de commit lista várias linhas parent. O Git lida com isso adicionando todos os hashes dos pais à fila. Dependendo das configurações de ordenação (por exemplo, cronológica, topológica ou por data), ele intercala os commits dos branches mescladas para reconstruir uma linha do tempo unificada.


O que acontece dentro de .git/ (exploração prática)

Vamos criar um repositório com vários commits e branches e, em seguida, acompanhar exatamente como o Git analisa seus arquivos para gerar a saída de git log.

Etapa 1: configurar um repositório com vários commits

Vamos inicializar um repositório e fazer dois commits rápidos no branch main.

$ mkdir git-log-demo && cd git-log-demo
$ git init
Initialized empty Git repository in /git-log-demo/.git/

$ echo "v1" > file.txt
$ git add file.txt
$ git commit -m "First commit"
[main (root-commit) 5be36ab] First commit

$ echo "v2" > file.txt
$ git add file.txt
$ git commit -m "Second commit"
[main ae39f81] Second commit

Etapa 2: criar um branch e um commit de merge

Agora, vamos criar um branch chamado feature (link git-branch), fazer um commit, voltar para o branch anterior e fazer o merge.

$ git checkout -b feature
Switched to a new branch 'feature'

$ echo "feature-work" > feature.txt
$ git add feature.txt
$ git commit -m "Feature commit"
[feature c4f8101] Feature commit

$ git checkout main
Switched to branch 'main'

$ git merge feature -m "Merge feature branch"
Merge made by the 'ort' strategy.
 feature.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 feature.txt

Etapa 3: resolver refs e catalogar os commits

Vamos ver para onde HEAD aponta agora:

$ cat .git/HEAD
ref: refs/heads/main

Agora vamos ver para qual commit main aponta:

$ cat .git/refs/heads/main
6df8d0354178de3d038fa61dfb63e8a157580b33

Esse é o nosso commit de merge. Vamos examinar esse objeto de commit usando o comando de baixo nível git cat-file:

$ git cat-file -p 6df8d0354178de3d038fa61dfb63e8a157580b33
tree e7c3909ea1dc725f187e1451f2ad490e5b0213ef
parent ae39f81ca99d45e5b619d854cf78d1f2a36b1d2e
parent c4f810129a8a72cf5a1db5b2f270a2936274b1e2
author Purna Pattela <purna@example.com> 1772960500 +0000
committer Purna Pattela <purna@example.com> 1772960500 +0000

Merge feature branch

Observe que, por ser um commit de merge, ele tem dois pais:

  • parent ae39f81... (o último commit em main antes do merge).
  • parent c4f8101... (o commit do branch feature).

Se executarmos git log, o Git exibirá o commit de merge (6df8d03) e, em seguida, lerá seus pais. Ele percorre os pais ae39f81 e c4f8101 em ordem cronológica. Vamos examinar ae39f81:

$ git cat-file -p ae39f81ca99d45e5b619d854cf78d1f2a36b1d2e
tree b4f93dc52c0dfa6c7f8a9a2a6dfba1d2a36b567d
parent 5be36abc0e9df7f2a7db2e9b0cf2a3d2427a1d1e
author Purna Pattela <purna@example.com> 1772960400 +0000
committer Purna Pattela <purna@example.com> 1772960400 +0000

Second commit

Esse commit aponta para o pai inicial 5be36ab.... Vamos examinar 5be36ab:

$ git cat-file -p 5be36abc0e9df7f2a7db2e9b0cf2a3d2427a1d1e
tree f3b3a3c9e6db5832a875a6c11d2b270a2936274b
author Purna Pattela <purna@example.com> 1772960300 +0000
committer Purna Pattela <purna@example.com> 1772960300 +0000

First commit

Como 5be36ab... não tem uma linha parent, o Git sabe que ele é a raiz da nossa árvore e interrompe a travessia. A saída resultante do log lista os quatro commits em ordem cronológica inversa.


Opções detalhadas de comandos e uso avançado

A saída padrão de git log é detalhada e sequencial. Você pode formatar, filtrar e rastrear o histórico usando flags.

1. Opções avançadas de formatação

--oneline

Condensa cada commit em uma única linha contendo o hash abreviado do commit e a linha de assunto. É ideal para examinar rapidamente os históricos de commits.

$ git log --oneline
6df8d03 Merge feature branch
c4f8101 Feature commit
ae39f81 Second commit
5be36ab First commit

--graph --decorate

Desenha uma representação em arte ASCII dos caminhos de execução dos branches ao lado dos rótulos de branch (HEAD, nomes de branches e tags).

$ git log --graph --oneline --decorate --all
*   6df8d03 (HEAD -> main) Merge feature branch
|\
| * c4f8101 (feature) Feature commit
* | ae39f81 Second commit
|/
* 5be36ab First commit

Formatos personalizados (--pretty=format:)

Você pode criar seus próprios modelos de saída usando marcadores de posição. Por exemplo, para exibir apenas o hash, o nome do autor, a data e a mensagem do commit:

$ git log --pretty=format:"%h - %an (%ar): %s"
6df8d03 - Purna Pattela (2 minutes ago): Merge feature branch
c4f8101 - Purna Pattela (5 minutes ago): Feature commit

Os principais marcadores de posição incluem:

  • %h: hash abreviado do commit.
  • %an: nome do autor.
  • %ar: data do autor (relativa, por exemplo, “3 days ago”).
  • %ad: data do autor (formato absoluto).
  • %s: linha de assunto (primeira linha da mensagem do commit).
  • %d: decorações de refs (por exemplo, (HEAD -> main)).

2. Filtragem forense do histórico

Pesquisa por alterações no código (o Pickaxe -S)

Se você quiser descobrir qual commit introduziu ou removeu uma determinada string de texto (como um nome de função ou endpoint de API) da sua base de código, use a flag -S:

$ git log -S "payment_processor_v2" --oneline

Isso é chamado de Pickaxe. Ele pesquisa o conteúdo dos arquivos em cada estado do commit, em vez de pesquisar apenas o texto das mensagens dos commits.

Pesquisa por mensagem de commit (--grep)

Para pesquisar uma palavra-chave apenas nas mensagens de commit:

$ git log --grep="bugfix"

Filtragem por caminho

Para ver apenas os commits que modificaram um arquivo ou uma pasta específica, acrescente dois hífens seguidos do caminho do arquivo:

$ git log --oneline -- src/utils/helper.js

Cenário do mundo real: depurar uma regressão

Imagine que sua equipe publique uma nova versão de um aplicativo, e os usuários relatem que o aplicativo trava quando clicam no botão “Submit”. Você sabe que o botão funcionava normalmente uma semana atrás.

Para encontrar o responsável, você pode combinar filtros do histórico:

# Step 1: List all commits from the last week that modified the checkout button component
$ git log --since="1 week ago" --oneline -- src/components/SubmitButton.js
a3d5f9c refactor: rewrite submit click handler
54f8b9e chore: update button styling

# Step 2: Show the actual code modifications in the suspicious commit (a3d5f9c)
$ git log -p -1 a3d5f9c

Usando a flag de patch -p, você examina as alterações exatas na função do handler, identifica o parâmetro de evento ausente e escreve um hotfix.


Armadilhas e erros comuns

1. Ficar preso no pager

Por padrão, quando a saída do log é maior que a altura da tela, o Git encaminha a saída para um utilitário pager (normalmente less). Iniciantes muitas vezes não sabem como voltar ao terminal normal.

  • A correção: pressione q para sair do pager.
  • Dica: se quiser que o Git imprima a saída diretamente no terminal sem abrir um pager, defina o pager como cat na configuração:
$ git --no-pager log -n 5

2. Faltar commits de outros branches

Executar git log mostra apenas os commits alcançáveis a partir do histórico do seu branch atual. Se você estiver em main e outra pessoa tiver enviado alterações para feature-b, você não verá os commits dela.

  • A correção: use a flag --all para mostrar todos os commits de todas os branches:
$ git log --oneline --all --graph

3. Confundir git log com git reflog

Se você fizer rebase (link git-rebase) ou resetar commits, esses commits serão removidos do histórico do branch e deixarão de aparecer em git log.

  • Por quê: git log percorre apenas ponteiros ativos.
  • A correção: use git reflog. O log de referências acompanha todas as alterações feitas no ponteiro HEAD na sua máquina local (incluindo trocas de checkout, alterações com amend, resets e rebases). É sua rede de segurança definitiva para recuperar commits “excluídos”.

Referência rápida de comandos

ComandoAção
git logExibe o histórico completo de commits (hashes, autor, data, mensagem).
git log --onelineExibe um resumo compacto de uma linha por commit.
git log --graph --oneline --allExibe uma árvore visual de todas os branches e merges.
git log -pExibe o patch (diff de código) introduzido por cada commit.
git log -n <limit>Limita a saída ao número especificado de commits (por exemplo, -n 5).
git log --author="Name"Filtra o histórico pelo nome do autor.
git log --grep="pattern"Filtra commits por palavras-chave na mensagem.
git log -S "code"Encontra commits que adicionam ou removem uma linha/palavra específica de código.
git log --no-mergesExclui commits de merge do registro do histórico.

FAQ (perguntas frequentes)

Por que meus commits não aparecem em git log?

Se você acabou de executar git commit, mas ele não aparece no log, verifique o seguinte:

  1. Verificação do staging: você executou git add antes de fazer o commit? Caso contrário, o commit pode ter sido rejeitado porque nada estava no staging.
  2. HEAD desanexado: se você estiver em um estado de HEAD desanexado, seus commits não estarão associados a um branch. Se fizer checkout de main, eles parecerão desaparecer do seu log. Execute git reflog para encontrar os hashes ausentes.

Qual é a diferença entre a data do autor e a data do committer?

  • Data do autor: o timestamp de quando o commit foi criado originalmente (por exemplo, usando git commit).
  • Data do committer: o timestamp de quando o commit foi gravado pela última vez no repositório (por exemplo, quando foi aplicado com cherry-pick, sofreu rebase ou foi alterado com amend).
  • Por padrão, git log exibe a data do autor. Para ver a data do committer, use git log --pretty=fuller.

Como vejo quem alterou uma linha específica em um arquivo?

Embora git log -S possa encontrar o commit que introduziu uma string, git blame <file> é a maneira mais rápida de ver a autoria linha a linha. Ele exibe o hash do commit, o autor e o timestamp de cada linha do arquivo.

Como posso pesquisar o histórico de commits por um intervalo de datas?

Você pode combinar as flags --since (ou --after) e --until (ou --before):

$ git log --since="2026-06-01" --until="2026-07-01" --oneline

O Git também interpreta datas humanas relativas, como --since="3 weeks ago" ou --until="yesterday".


Teste seus conhecimentos

Carregando quiz…