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
- O Git lê o arquivo
.git/HEADpara determinar seu branch ativo (por exemplo,ref: refs/heads/main). - Ele resolve a referência do branch para seu hash de commit de 40 caracteres lendo
.git/refs/heads/main(por exemplo,8a4c10...). - Ele carrega o objeto de commit
8a4c10...do banco de objetos (.git/objects/) e extrai os metadados: autor, committer, timestamp, mensagem e o hashparent. - O Git exibe os detalhes desse commit no console.
- O Git coloca o hash do pai (por exemplo,
55a420...) em uma fila de travessia. - 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.
- 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 emmainantes do merge).parent c4f8101...(o commit do branchfeature).
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
qpara sair do pager. - Dica: se quiser que o Git imprima a saída diretamente no terminal sem abrir um pager, defina o pager como
catna 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
--allpara 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 logpercorre apenas ponteiros ativos. - A correção: use
git reflog. O log de referências acompanha todas as alterações feitas no ponteiroHEADna 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
| Comando | Ação |
|---|---|
git log | Exibe o histórico completo de commits (hashes, autor, data, mensagem). |
git log --oneline | Exibe um resumo compacto de uma linha por commit. |
git log --graph --oneline --all | Exibe uma árvore visual de todas os branches e merges. |
git log -p | Exibe 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-merges | Exclui 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:
- Verificação do staging: você executou
git addantes de fazer o commit? Caso contrário, o commit pode ter sido rejeitado porque nada estava no staging. - 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. Executegit reflogpara 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 logexibe a data do autor. Para ver a data do committer, usegit 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…