arquivo git diff contra sua última alteração


236

É possível fazer com que o git produza uma diferença entre um arquivo específico como ele existe agora e como existia antes da última confirmação que o alterou?

Ou seja, se soubermos:

$ git log --oneline myfile
123abc Fix some stuff
456def Frobble the foos
789dba Initial commit

Em seguida, git diff 456def myfilemostra a última alteração no myfile. É possível fazer o mesmo sem o conhecimento produzido pelo git log; o que mudou no 123abc?


8
Eu prefiro usargit diff HEAD^ <file_path>
asgs

4
@asgs - não faz o que eu estava pedindo (por duas razões - HEAD^é 123abc, HEAD^^é 456def, e se havia outros commits que não afetaram esse arquivo , em seguida, HEAD^se refere a eles)
Chowlett

Você está certo, perdeu o "a última confirmação que mudou" parte
ASGs

Respostas:


215

Isso existe, mas na verdade é um recurso de git log:

git log -p [--follow] [-1] <path>

Observe que -ptambém pode ser usado para mostrar o diff inline de um único commit:

git log -p -1 <commit>

Opções utilizadas:

  • -p(também -uou --patch) está oculto na git-logpágina de manual e, na verdade, é uma opção de exibição para git-diff. Quando usado com log, mostra o patch que seria gerado para cada confirmação , juntamente com as informações de confirmação - e oculta as confirmações que não tocam na especificada <path>. (Esse comportamento é descrito no parágrafo --full-diffa seguir, o que faz com que o diff completo de cada confirmação seja mostrado.)
  • -1mostra apenas a alteração mais recente no arquivo especificado ( -n 1pode ser usado em vez de -1); caso contrário, todas as diferenças diferentes de zero desse arquivo serão mostradas.
  • --follow é necessário para ver as alterações que ocorreram antes de uma renomeação.

Até onde sei, essa é a única maneira de ver imediatamente o último conjunto de alterações feitas em um arquivo sem usar git log(ou semelhante) para contar o número de revisões intermediárias ou determinar o hash da confirmação.

Para ver alterações nas revisões mais antigas, basta rolar pelo log ou especificar uma confirmação ou marca a partir da qual iniciar o log. (Obviamente, especificar uma confirmação ou marca retorna ao problema original de descobrir qual é a confirmação ou marca correta.)

Crédito onde o crédito é devido:

  • Eu descobri log -pgraças a esta resposta .
  • Agradeço a FranciscoPuga e esta resposta por me mostrar a --followopção.
  • Agradecemos a ChrisBetti por mencionar a -n 1opção e a atatko por mencionar a -1variante.
  • Os nossos agradecimentos a sweaver2112 por me fazer realmente ler a documentação e descobrir o que -p"significa" semanticamente.

6
Essa foi uma ótima solução para mim. Mostrou cada commit e suas diferenças no arquivo atual quando eu corrigit log -p filename
Ian Jamieson

4
Perfeito. Para ver apenas a última alteração, é tão simples quanto adicionar o -n 1parâmetro. git log -p -n 1 filename
22815 Chris Betti

@ChrisBetti Thanks; Eu incorporei isso na minha resposta!
Kyle Strand

1
-n 1também pode ser substituído por -1, não altera o resultado, apenas prefiro a sintaxe:git log -p -1 filename
atatko 27/04

1
existe uma opção útil "--skip = [n]". Você pode digitar git log -p -1 --skip=1 <path>para exibir a segunda confirmação.
Maciek Łoziński

220

Uma das maneiras de usar o git diff é:

git diff <commit> <path>

E uma maneira comum de referir um commit do último commit é como um caminho relativo para o HEAD real. Você pode referenciar confirmações anteriores como HEAD ^ (no seu exemplo, será 123abc) ou HEAD ^^ (456def no seu exemplo), etc ...

Portanto, a resposta para sua pergunta é:

git diff HEAD^^ myfile

6
Ah, claro. Eu tentei HEAD^, mas é claro que isso não produziu nada. Não pensou em tentar HEAD^^.
Chowlett #

17
Talvez mais fácil sintaxe para commits há muito tempo:HEAD~2
ibizaman

19
Não é verdade (pelo menos para o Git 1.9.0) que HEAD^^ myfilerealmente se refere ao penúltimo commit que foi alterado myfile; ele se referirá ao penúltimo commit geral. Existe alguma maneira de especificar "Quero ver a última alteração feita neste arquivo" sem especificar (parte de) o hash de confirmação ou contar o número de confirmações entre a última alteração feita nesse arquivo e a revisão atual?
Kyle Strand

3
Parece que git log -pestá bem perto.
Kyle Strand

30
motivo negativo: a pergunta "entre um arquivo específico como ele existe agora e como existia antes do último commit que o alterou ", mas se o arquivo não foi alterado no último commit geral, essa resposta não funcionará.
22815 Chris Betti

8

Se você estiver bem usando uma ferramenta gráfica, isso funciona muito bem:

gitk <file>

O gitk agora mostra todos os commits nos quais o arquivo foi atualizado. Marcar uma confirmação mostrará a diferença em relação à confirmação anterior na lista. Isso também funciona para diretórios, mas você também pode selecionar o arquivo a ser diferenciado para a confirmação selecionada. Super útil!


1
Também é muito útil: git difftool HEAD^ fileougit difftool -d HEAD^ path
ForeverLearning
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.