Exibir o histórico de alterações de um arquivo usando a versão do Git

3090

Como posso visualizar o histórico de alterações de um arquivo individual no Git, detalhes completos com o que mudou?

Eu cheguei até:

git log -- [filename]

que me mostra o histórico de consolidação do arquivo, mas como faço para obter o conteúdo de cada uma das alterações no arquivo?

Estou tentando fazer a transição do MS SourceSafe e isso costumava ser um simples right-clickshow history.

Richard
fonte
41
O link acima não é mais válido. Este link está funcionando hoje: Git Community Book
chris
1
O link acima (postado por Chris) não é mais válido. Este link está funcionando hoje: git-scm.com/book/en/v2
Cog

Respostas:

2370

Para isso, eu usaria:

gitk [filename]

ou para seguir o nome do arquivo e renomear

gitk --follow [filename]
Claudio Acciaresi
fonte
28
Mas prefiro mesmo ter uma ferramenta que combinou o acima com 'culpa git' que me permite navegar na fonte de um arquivo como ele muda no tempo ...
Egon Willighagen
26
Infelizmente, isso não segue o histórico do nome do arquivo passado.
Dan Molding
146
Eu também estava procurando o histórico de arquivos que foram renomeados anteriormente e encontraram esse segmento primeiro. A solução é usar "git log --follow <filename>", como Phil apontou aqui .
Florian Gutmann
115
O autor estava procurando uma ferramenta de linha de comando. Embora o gitk seja fornecido com o GIT, ele não é um aplicativo de linha de comando nem uma GUI particularmente boa.
Mikemaccana
72
Ele estava procurando uma ferramenta de linha de comando? "clique direito -> mostrar histórico" certamente não implica isso.
Hdgarrood
2235

Você pode usar

git log -p filename

para permitir que o git gere os patches para cada entrada de log.

Vejo

git help log

para mais opções - ele pode realmente fazer muitas coisas legais :) Para obter apenas o diff de um commit específico, você pode

git show HEAD 

ou qualquer outra revisão por identificador. Ou use

gitk

para procurar as alterações visualmente.

VolkA
fonte
8
git show HEAD mostra todos os arquivos, você sabe como rastrear um arquivo individual (como Richard estava pedindo)?
Jonas Byström
5
você usa: git show <revision> - nome do arquivo, que mostrará as diferenças para essa revisão, caso exista uma.
Marcos Oliveira
4
--stat também é útil. Você pode usá-lo junto com -p.
Raffi Khatchadourian
5
Isso é ótimo. O gitk não se comporta bem ao especificar caminhos que não existem mais. Eu usei git log -p - path.
Paulo Casaretto 27/02
6
Além disso, o gitk parece ter sido construído pelo monstro boogie. Essa é uma ótima resposta e é melhor adaptada à pergunta original.
Ghayes
1498

git log --follow -p -- path-to-file

Isso mostrará todo o histórico do arquivo (incluindo o histórico além de renomear e com diffs para cada alteração).

Em outras palavras, se o arquivo nomeado barjá tiver sido nomeado foo, git log -p bar(sem a --followopção) mostrará apenas o histórico do arquivo até o ponto em que foi renomeado - ele não mostrará o histórico do arquivo quando conhecido como foo. O uso git log --follow -p barexibirá o histórico inteiro do arquivo, incluindo quaisquer alterações no arquivo quando ele era conhecido como foo. A -popção garante que as diferenças sejam incluídas para cada alteração.

Dan Moulding
fonte
18
--stat também é útil. Você pode usá-lo junto com -p.
Raffi Khatchadourian
23
Concordo que esta é a resposta REAL. (1.) --followgarante que você veja as renomeações de arquivos (2.) -pgarante que você veja como o arquivo é alterado (3.) é apenas linha de comando.
Trevor Boyd Smith
3
@NHDaly Percebo que o --foi adicionado, mas não sei por que isso o torna melhor? O que é que faz?
Benjohn 27/05
40
@ Benjohn A --opção informa ao Git que chegou ao final das opções e que tudo o que se segue --deve ser tratado como argumento. Pois git logisso só faz diferença se você tiver um nome de caminho que comece com um traço . Digamos que você queira conhecer o histórico de um arquivo com o nome infeliz "--follow":git log --follow -p -- --follow
Dan Molding
10
@ Benjohn: Normalmente, --é útil porque também pode proteger contra revisionnomes que correspondam ao nome do arquivo digitado, o que pode ser assustador. Por exemplo: Se você tivesse uma ramificação e um arquivo nomeados foo, git log -p foomostraria até o histórico do log do git foo, não o histórico do arquivo foo . Mas o @DanMoulding está certo que, como o --followcomando usa apenas um único nome de arquivo como argumento, isso é menos necessário, pois não pode ser a revision. Eu acabei de aprender isso. Talvez você estivesse certo em deixar isso de fora da sua resposta; Não tenho certeza.
NHDaly 30/05
172

Se você preferir ficar com base em texto, convém usar o tig .

Instalação rápida:

  • apt-get :# apt-get install tig
  • Homebrew (OS X) :$ brew install tig

Use-o para visualizar o histórico em um único arquivo: tig [filename]
ou procure o histórico detalhado de repositórios:tig

Semelhante ao gitkmas baseado em texto. Suporta cores no terminal!

Falken
fonte
23
Excelente ferramenta baseada em texto, ótima resposta. Eu surtei quando vi as dependências para a instalação do gitk no meu servidor sem cabeça. Voto a favor novamente A +++
Tom McKenzie
Você pode ver também arquivos específicos com o tig, ietig -- path/to/specific/file
gloriphobia 27/10
110

git whatchanged -p filenametambém é equivalente a git log -p filenameneste caso.

Você também pode ver quando uma linha de código específica dentro de um arquivo foi alterada git blame filename. Isso imprimirá um ID de confirmação curto, o autor, o carimbo de data e hora e a linha de código completa para todas as linhas do arquivo. Isso é muito útil depois que você encontra um bug e deseja saber quando ele foi introduzido (ou quem foi a culpa).

farktronix
fonte
4
+1, mas filenamenão é opcional no comando git blame filename.
rockXrock
7
"Novos usuários são encorajados a usar o git-log. (...) O comando é mantido principalmente por razões históricas;"
Ciastek 18/03/2014
105

Usuários do SourceTree

Se você usar o SourceTree para visualizar seu repositório (é gratuito e bastante bom), clique com o botão direito do mouse em um arquivo e selecione Log Selecionado

insira a descrição da imagem aqui

A exibição (abaixo) é muito mais amigável que o gitk e a maioria das outras opções listadas. Infelizmente (no momento) não há uma maneira fácil de iniciar essa exibição na linha de comando - a CLI do SourceTree atualmente apenas abre repositórios.

insira a descrição da imagem aqui

Mark Fox
fonte
1
Eu particularmente gosto da opção "Seguir arquivos renomeados", que permite ver se um arquivo foi renomeado ou movido.
31515 Chris
mas a menos que eu esteja enganado (por favor me avise!), só é possível comparar duas versões por vez no GUI? Existem clientes que possuem uma interface elegante para diferenciar várias versões diferentes ao mesmo tempo? Possivelmente com uma visão de menos zoom como no texto sublime? Isso seria realmente útil, eu acho.
precisa saber é o seguinte
@SamLewallen Se bem entendi, você deseja comparar três confirmações diferentes? Isso soa semelhante a uma mesclagem de três vias (mina, sua, base) - geralmente essa estratégia é usada para resolver conflitos de mesclagem, não necessariamente comparando três confirmações arbitrárias. Existem muitas ferramentas que o apoio de três vias fusões stackoverflow.com/questions/10998728/... mas o truque está alimentando essas ferramentas as revisões específicas gitready.com/intermediate/2009/02/27/...
Mark Fox
Obrigado Mark Fox, é o que quero dizer. Você conhece algum aplicativo que fará isso?
Sam Lewallen
1
@ MarnenLaibow-Koser Não me lembro por que preciso do SHA naquele momento. Ahaha.
AechoLiu 14/03/19
63

Para mostrar qual revisão e autor modificou pela última vez cada linha de um arquivo:

git blame filename

ou se você quiser usar a poderosa GUI de culpa:

git gui blame filename
yllohy
fonte
49

Resumo de outras respostas depois de ler e tocar um pouco:

O comando de linha de comando usual seria

git log --follow --all -p dir/file.c

Mas você também pode usar o gitk (gui) ou o tig (text-ui) para fornecer maneiras muito mais legíveis para o ser humano.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

Sob debian / ubuntu, o comando de instalação para essas ferramentas encantadoras é o esperado:

sudo apt-get install gitk tig

E atualmente estou usando:

alias gdf='gitk --follow --all -p'

para que eu possa digitar gdf dirpara obter um histórico focado de tudo no subdiretório dir.

John Lawrence Aspden
fonte
2
Eu acho que essa é uma ótima resposta. Talvez você também não esteja sendo votado porque responde a outras formas (IMHO melhor) para ver as mudanças, ou seja, via gitk e tig, além do git.
PopcornKing
Apenas para adicionar a resposta. Localize o caminho (no espaço git, até o que ainda existe no repositório). Em seguida, use o comando descrito acima "git log --follow --all -p <folder_path / file_path>". Pode ser que o arquivo / pasta tenha sido removido ao longo do histórico, localizando o caminho máximo que ainda existe e tente buscar seu histórico. trabalho !
parasrish
2
--allé para todos os ramos, o resto é explicado em @ Dan resposta
cregox
1
Oh, cara, depois de tanto tempo procurando uma boa solução para rastrear arquivos além de renomear, finalmente, encontrei aqui. Funciona como charme! Obrigado!
xZero 8/03/19
25

Adicione este alias ao seu .gitconfig:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

E use o comando como este:

> git lg
> git lg -- filename

A saída será quase exatamente igual à saída do gitk. Aproveitar.

Palesz
fonte
Depois de executar o atalho lg, eu disse (e cito) "Beautiful!". No entanto, observe que o "\ n" após "--graph" é um erro.
Jbeck
3
Também pode ser usado git lg -p filename- ele retorna uma bela diff do arquivo pesquisado.
Egel 27/03
22

Ultimamente eu descobri tig e achei muito útil. Há alguns casos em que eu gostaria que fosse A ou B, mas na maioria das vezes é bem legal.

Para o seu caso, tig <filename>pode ser o que você está procurando.

http://jonas.nitro.dk/tig/

lang2
fonte
em centos yum install tig
zzapper
18

Você pode usar o vscode com o GitLens , é uma ferramenta muito poderosa. Após instalar o GitLens, vá para a guia GitLens, selecione FILE HISTORYe você pode navegar por ele.

insira a descrição da imagem aqui

foxiris
fonte
15

Eu escrevi git-playback para esse propósito exato

pip install git-playback
git playback [filename]

Isso tem o benefício de exibir os resultados na linha de comando (como git log -p) e também permitir que você percorra cada confirmação usando as teclas de seta (como gitk).

Jian
fonte
13

Ou:

gitx -- <path/to/filename>

se você estiver usando gitx

George Anderson
fonte
1
Por alguma razão, meu gitx se abre em branco.
IgorGanapolsky
@IgorGanapolsky você tem que ter certeza que está na raiz de seu repositório git
zdsbs
10

Você também pode tentar isso, listando os commits que alteraram uma parte específica de um arquivo (implementado no Git 1.8.4).

O resultado retornado seria a lista de confirmações que modificaram esta parte específica. Comando:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

em que upperLimit é o número_de_instrução e lowerLimit é o número de linha de término do arquivo.

Mais detalhes em https://www.techpurohit.com/list-some-useful-git-commands

jitendrapurohit
fonte
9

Se você quiser ver todo o histórico de um arquivo, inclusive em todas as outras ramificações, use:

gitk --all <filename>
Adi Shavit
fonte
7

Com as excelentes Git Extensions , você chega a um ponto no histórico em que o arquivo ainda existia (se tiver sido excluído, caso contrário, vá para HEAD), alterne para a File treeguia, clique com o botão direito do mouse no arquivo e escolha File history.

Por padrão, ele segue o arquivo através das renomeações e a Blameguia permite ver o nome em uma determinada revisão.

Ele tem algumas dicas menores, como aparecer fatal: Not a valid object namena Viewguia ao clicar na revisão de exclusão, mas eu posso conviver com isso. :-)

PhiLho
fonte
Vale a pena notar que isso é apenas para Windows.
Evan Hahn
3
@EvanHahn não é preciso, via mono pode-se usar o GitExtension também no Linux, nós o usamos no ubuntu e muito felizes com isso. consulte git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat
7

Se você estiver usando a GUI do git (no Windows) no menu Repositório, poderá usar "Visualizar histórico do mestre". Destaque uma confirmação no painel superior e um arquivo no canto inferior direito e você verá o diff dessa confirmação no canto inferior esquerdo.

cori
fonte
Como isso responde à pergunta?
jmbeck
3
Bem, o OP não especificou a linha de comando e, saindo do SourceSafe (que é uma GUI), pareceu relevante ressaltar que você poderia fazer praticamente a mesma coisa que no VSS na GUI do Git no Windows.
Cori
6

SmartGit :

  1. No menu, habilite para exibir arquivos inalterados: Exibir / Mostrar arquivos inalterados
  2. Clique com o botão direito do mouse no arquivo e selecione 'Log' ou pressione 'Ctrl-L'
Antonín Slejška
fonte
4

A resposta que eu estava procurando e que não estava nesse segmento é ver as alterações nos arquivos que eu havia preparado para confirmar. ie

git diff --cached
Malks
fonte
1
Se você deseja incluir alterações locais (sem estágio), geralmente corro git diff origin/masterpara mostrar as diferenças completas entre sua filial local e a filial principal (que podem ser atualizadas de forma remota via git fetch)
ghayes
4

Se você usa o TortoiseGit, poderá clicar com o botão direito do mouse no arquivo e fazer TortoiseGit --> Show Log. Na janela exibida, verifique se:

  • Show Whole Projectopção ' ' não está marcada.

  • All Branchesopção ' ' está marcada.

user3885927
fonte
O TortoiseGit (e o Eclipse Git também) de alguma forma esquecem as revisões do arquivo selecionado, não conte com isso!
Noam Manos
@NoamManos, não encontrei esse problema, portanto não posso verificar se sua declaração está correta.
user3885927
Meu erro, isso só acontece no Eclipse, mas no TortoiseGit você pode ver todas as revisões de um arquivo se desmarcar "mostrar todo o projeto" + marcar "todos os ramos" (caso o arquivo tenha sido confirmado em outro ramo, antes de ser mesclado com o main ramo). Vou atualizar sua resposta.
Noam Manos
3

git diff -U <filename> dar-lhe um diff unificado.

Deve ser colorido em vermelho e verde. Caso contrário, execute: git config color.ui autoprimeiro.

Lukasz Czerwinski
fonte
2

Se você estiver usando o eclipse com o plug-in git, ele possui uma excelente visualização de comparação com o histórico. Clique com o botão direito do mouse no arquivo e selecione "comparar com" => "histórico"

AhHatem
fonte
Isso não permitirá que você encontre um arquivo excluído.
precisa saber é o seguinte
Comparando duas versões de um arquivo é diferente Vendo o histórico de alterações de um arquivo
Golimar
0

Provavelmente, eu sou sobre onde o OP estava quando isso começou, procurando algo simples que me permita usar o git difftool com o vimdiff para revisar as alterações nos arquivos no meu repositório a partir de um commit específico. Eu não estava muito feliz com as respostas que estava encontrando, então juntei esse script git inc remental rep orter (gitincrep) juntos e isso tem sido útil para mim:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Chamado sem argumentos, isso começará no início do histórico do repositório, caso contrário, começará com o hash de confirmação abreviado que você fornecer e prosseguirá para o presente - você pode pressionar Ctrl-C a qualquer momento para sair. Qualquer argumento após o primeiro limitará os relatórios de diferença para incluir apenas os arquivos listados entre eles (que eu acho que é o que o OP queria, e eu recomendaria para todos os projetos, exceto pequenos). Se você estiver verificando alterações em arquivos específicos e quiser começar desde o início, precisará fornecer uma sequência vazia para arg1. Se você não é um usuário do vim, pode substituir o vimdiff por sua ferramenta de diff favorita.

O comportamento é gerar os comentários de confirmação quando alterações relevantes são encontradas e começar a oferecer execuções vimdiff para cada arquivo alterado (esse é o comportamento do git difftool , mas funciona aqui).

Essa abordagem provavelmente é bastante ingênua, mas, analisando muitas das soluções aqui e em um post relacionado, muitas envolveram a instalação de novas ferramentas em um sistema onde eu não tenho acesso de administrador, com interfaces que tinham sua própria curva de aprendizado. O script acima fez o que eu queria sem lidar com nada disso. Analisarei as muitas sugestões excelentes aqui quando precisar de algo mais sofisticado - mas acho que isso responde diretamente ao OP.

oracleif
fonte
0

Eu encontrei uma solução muito simples para encontrar rapidamente o histórico do arquivo.

  1. Faça uma alteração aleatória no arquivo
  2. Aparecerá como alterações não confirmadas no seu sourcetree
  3. Clique com o botão direito do mouse no arquivo e selecione 'Log Selected'

insira a descrição da imagem aqui

Isso mostraria a história de todos os commits.

savvyBrar
fonte
De onde vem essa GUI?
colidyre 31/03
UI do Sourcetree. Graças
savvyBrar