Git
Chapters ▾ 2nd Edition

2.3 Noções Básicas do Git - Veja o Histórico de Confirmação

Veja o Histórico de Confirmação

 Depois de teres feito várias confirmações, ou se clonaste um repositório que já tinha um histórico de confirmações, provavelmente vais querer voltar a ver quais as modificações que foram feitas.
A ferramenta mais básica e poderosa para fazer isto é o comando `git log`.

Estes exemplos usam um projeto muito simples chamado “simplegit”. Para clonar o projeto, executa:

$ git clone https://github.com/schacon/simplegit-progit

Quando executas git log neste projeto, deves ver uma saída semelhante a esta:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

Por defeito, se não passares em nenhum parâmetro, git log enumera as confirmações feitas neste repositório em ordem cronológica inversa. Ou seja, as confirmações mais recentes são mostradas no início. Como podes ver, este comando lista cada confirmação com a sua soma de verificação SHA-1, o nome e o endereço de e-mail do autor, a data e a mensagem de confirmação.

O comando git log fornece uma grande quantidade de opções para mostrar exatamente o que tu estás a procurar. Aqui vamos ver alguns dos mais utilizados.

Uma das opções mais úteis é -p ou --patch, que mostra as diferenças introduzidas em cada confirmação. Tu também podes usar a opção -2, que mostra apenas as duas últimas entradas no histórico:

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end

Esta opção mostra a mesma informação, mas adicionando as diferenças que correspondem a ele após cada entrada. Isto é muito útil para revisões de código, ou para visualizar rapidamente o que aconteceu nas confirmações enviadas por um colaborador. Tu também podes usar uma série de opções de resumo com git log. Por exemplo, se quiseres ver algumas estatísticas de cada confirmação, podes usar a opção --stat:

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

Como podes ver, a opção --stat imprime após cada confirmação uma lista de arquivos modificados, indicando quantos foram modificados e quantas linhas foram adicionadas e excluídas para cada um deles. Também apresenta um resumo de todas estas informações, no final.

Outra opção realmente útil é --pretty, Esta opção modifica o formato da saída. Tu tens alguns estilos disponíveis. A opção oneline imprime cada confirmação numa única linha, o que pode ser útil se estiveres a analisar muitas confirmações. Outras opções são short, full e fuller, que mostram a saída num formato semelhante, mas adicionando menos ou mais informações, respectivamente:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

A opção mais interessante é format, que te permite especificar o teu próprio formato. Isto é especialmente útil se tu estiveres gerando um resultado a ser analisado por outro programa — como tu especificas o formato explicitamente, tu sabes que não irá mudar nas futuras atualizações do Git:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit

Opções uteis para o git log --pretty=format lista algumas das opções mais úteis aceitas pelo ‘formato’.

Table 1. Opções uteis para o git log --pretty=format
Option Descrição da saída

%H

Hash de confirmação

%h

Hash de confirmação abreviado

%T

Hash de árvore

%t

Abbreviated tree hash

%P

Hashes de confirmação de pai

%p

Hash de árvore abreviado

%an

Nome do autor

%ae

Email do autor

%ad

Data do autor (o formato respeita a opção --date)

%ar

Data de autor, relativa

%cn

nome do confirmador

%ce

Email do confirmador

%cd

Date do confirmador

%cr

Date do confirmador, relativa

%s

Assunto

Podes estar a perguntar-te qual a diferença entre autor (author) e confirmador (committer). O autor é a pessoa que originalmente escreveu o trabalho, enquanto que o confirmador é aquele que o aplicou. Portanto, se enviares um patch para um projeto, e um dos seus membros o aplicará, ambos receberão reconhecimento — tu como autor e o membro do projeto como um confirmador. Veremos esta distinção mais aprofundada em Git Distribuído.

As opções oneline e format são especialmente úteis em combinação com outra opção chamada --graph. Isto adiciona um pequeno gráfico ASCII mostrando o teu histórico de filiais e junções:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

Este tipo de passeios será mais interessante quando começarmos a falar de ramificações e combinações no próximo capítulo.

Estas são apenas algumas das opções para formatar a saída do git log — há muitos mais. Common options to git log lista as opções vistas até agora, e algumas outras opções de formatação que podem ser úteis, bem como o efeito delas na saída.

Table 2. Common options to git log
Option Descrição

-p

Mostra o patch introduzido em cada confirmação.

--stat

Mostra estatísticas dos arquivos modificados em cada confirmação.

--shortstat

Exibir apenas a linha alterada/inserções/eliminações do comando --stat.

--name-only

Mostra a lista de arquivos modificados após as informações de confirmação.

--name-status

Mostra também a lista de arquivos afetados com informações adicionadas/modificadas/excluídas..

--abbrev-commit

Mostra apenas os primeiros caracteres da soma de verificação SHA-1 em vez de todos os 40.

--relative-date

Mostra a data em formato relativo (por exemplo, “2 semanas atrás”) em vez do formato completo.

--graph

Mostra um gráfico ASCII com o histórico de ramos e junções.

--pretty

Mostre as confirmações usando um formato alternativo. Possíveis opções são oneline, short, full, fuller e format (através do qual podes especificar o teu próprio formato).

--oneline

Estenografia para --pretty=oneline --abbrev-commit usada em conjunto.

Limitar a saída do registro

Além das opções de formatação, git log aceita uma série de opções para limitar a sua saída — ou seja, opções que permitem que tu exibas apenas uma parte das confirmações.

Tu já viste um deles, a opção -2, que mostra apenas as duas últimas confirmações. Na verdade, tu podes fazer -<n>, onde n é qualquer número inteiro, para mostrar as últimas confirmações 'n`. Na verdade, é improvável que uses isto com freqüência, uma vez que o Git por defeito a sua saída para que possas ver cada página do registro de saída separadamente.

No entanto, as opções temporárias como --desde e --até são muito úteis. Por exemplo, este comando lista todas as confirmações feitas durante as últimas duas semanas:

$ git log --since=2.weeks

Este comando aceita muitos formatos. Podes indicar uma data específica "2008-01-15", ou relativa, como "2 anos 1 dia e 3 minutos atrás". Também podes filtrar a lista para se comprometer com alguns critérios de pesquisa. A opção --author permite que filtres por um autor específico e --grep permite pesquisar palavras-chave entre as mensagens de confirmação.

Podes especificar mais de uma instância de ambos os critérios de pesquisa --author e --grep, que limitará a saída de confirmação para comprometer-se que correspondem a qualquer um dos padrões --author e any dos padrões --grep; no entanto, adicionar a opção --all-match ainda limita a saída para apenas aqueles compromissos que combinam com os padrões all --grep.

Outro filtro realmente útil é a opção -S (coloquialmente conhecido por “pickaxe” do Git), que leva uma string e mostra apenas aquelas cpmfirmações que mudaram o número de ocorrências desta string. Por exemplo, se quisesses encontrar a última confirmação que adicionaste ou removeste uma referência a uma função específica, tu poderias chamar:

$ git log -S function_name

A última opção verdadeiramente útil para filtrar a saída do git log é especificar uma rota. Se especificares o caminho de um diretório ou arquivo, podes limitar a saída para as confirmações que introduziram uma alteração nestes arquivos. Esta deve ser sempre a última opção, e geralmente é precedida por dois traços (--) para separar a rota do restante das opções.

Em << limit_options >>, estas opções estão listadas, e outras são bastante comuns, como uma referência.

Table 3. Opções para limitar a saída git log
Option Descrição

-<n>

Mostra apenas as últimas confirmações

--since, --after

Mostra as confirmações realizadas após a data especificada.

--until, --before

Limita os compromissos com aqueles feitos antes da data especificada.

--author

Mostra apenas as confirmações cujo autor corresponde à cadeia especificada.

--committer

Mostra apenas as confirmações cujo comitente corresponde à cadeia especificada.

--grep

Mostra apenas confirmações com uma mensagem de confirmação contendo a string

-S

Mostra apenas as confirmações que adicionam ou excluem o código que corresponde à cadeia especificada.

Por exemplo, se quiseres ver quais as confirmações feitas sobre os arquivos de teste do código fonte Git foram enviadas por June Hamano no mês de outubro de 2008 e não são confirmações fusão, tu podes executar algo como isto:

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

Das quase 40.000 confirmações na história do código fonte Git, este comando mostra os 6 que atendem a estas condições.

Example 1. Prevenção da exibição de compromissos de fusão

Dependendo do fluxo de trabalho usado no teu repositório, é possível que uma percentagem considerável dos compromissos no teu histórico de logs sejam apenas compromissos de mesclagem, que tipicamente não são muito informativos. Para evitar que a exibição da mesclagem comece a agasalhar o teu histórico de log, simplesmente adiciona a opção de logon --no-merges.