Como diferenciar um arquivo para uma versão arbitrária no Git?

324

Como posso diferenciar um arquivo, digamos pom.xml, do ramo mestre para uma versão mais antiga e arbitrária no Git?

Chris K
fonte

Respostas:

347

Você pode fazer:

git diff master~20:pom.xml pom.xml

... para comparar sua atual pom.xmlcom a de master20 revisões atrás, até o primeiro pai. É possível substituir master~20, é claro, pelo nome do objeto (SHA1sum) de uma confirmação ou por qualquer uma das muitas outras maneiras de especificar uma revisão .

Observe que, na verdade, isso está comparando a pom.xmlversão antiga com a versão em sua árvore de trabalho, e não a versão confirmada master. Se você desejar, faça o seguinte:

git diff master~20:pom.xml master:pom.xml
Mark Longair
fonte
12
Observe que isso não funciona apenas para arquivos, mas também para diretórios (sub), por exemplo git diff <revision>:foo/ HEAD:foo/.
2
Observe também que, no Windows, você precisa usar barras para diretórios, se estiver usando um especificador de revisão ou git, irá fornecer um erro sobre o arquivo / diretório que não existe nessa revisão.
Dylan Nissley
1
@DylanNissley ou isso não lhe dará nenhum erro e nenhuma diferença. É o que eu vejo. De qualquer forma, obrigado pela dica sobre como usar barras invertidas em vez de barras invertidas.
Gary S.
Com arquivos de janelas que eu achei mais fácil de alterar diretório e, em seguida, chamar mestre git diff ~ 20: ./ pom.xml ./pom.xml
Lloyd
Alguma versão do git requer "-" entre <revision> e <path>
Josh
140
git diff <revision> <path>

Por exemplo:

git diff b0d14a4 foobar.txt
Benjamin Pollack
fonte
não funciona para a versão 1.7.11 se o arquivo não estiver no diretório atual. Exemplo: 'git diff f76d078 test / Config' gera "erro: Não foi possível acessar 'test / f76d078'"
simpleuser 4/13/13
1
@ user1663987 apenas passar um caminho completo relativo à raiz do projeto: git diff <revision> root/path/file.
1
test / Config é relativo à raiz (como em test é um subdiretório da raiz). mas, em seguida, seu exemplo de raiz / caminho / arquivo parece incluir a raiz?
Simples
41

Se você quiser ver a diferença entre a última confirmação de um único arquivo, você pode:

git log -p -1 filename

Isso fornecerá a comparação do arquivo no git, não comparando o arquivo local.

Gerardo
fonte
2
isso não está retornando nada #
Andrei Cristian Prodan
@AndreiCristianProdan Então você não tem alterações lá. Você pode incrementar o -1passo a passo até obter as alterações.
Kaiser #
Isso é muito legal. Eu criei uma função bash que pode ser útil: gitlog () { git log -${3:-p} -${2:-1} $1; } Usado como: gitlog Rakefileou gitlog Rakefile 5e gitlog Rakefile 10 s. O primeiro mostra um diff; o segundo mostra cinco diferenças; o terceiro mostra dez --no-patch.
Auxbuss 7/06
18

Para ver o que foi alterado em um arquivo na última confirmação:

git diff HEAD~1 path/to/file.

Você pode alterar o número (~ 1) para o n-ésimo commit com o qual deseja diferenciar.

Juampy NR
fonte
Essa resposta é realmente apenas um caso específico dessa resposta mais geral , onde HEAD~1é substituída <revision>, o que torna essa resposta uma duplicata.
1
isso não está funcionando! fatal: argumento ambíguo 'HEAD ~ 1': revisão desconhecida ou caminho fora da árvore de trabalho. Use '-' para separar caminhos de revisões
Andrei Cristian Prodan
Esta resposta é simples e funcional para mim.
Douglas Frari
6

Sintaxe genérica:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

para todos os arquivos denominados "FileName.xml" em qualquer lugar do seu repositório.

Observe o espaço entre "-" e "**"

Responda a sua pergunta:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

como sempre com o git, você pode usar uma tag / sha1 / "HEAD ^" para identificar um commit.

Testado com git 1.9.1 no Ubuntu.

soundslikeodd
fonte
6

Se nenhum dos commit for o seu HEAD, a expansão de chaves do bash será realmente útil, especialmente se os seus nomes de arquivos forem longos, o exemplo acima:

git diff master~20:pom.xml master:pom.xml

Se tornaria

git diff {master~20,master}:pom.xml

Mais sobre a expansão Brace com bash.

robstarbuck
fonte
6

Para comparar com 5 confirmados com o atual, ambos ativados master, basta:

git diff master~5:pom.xml master:pom.xml

Também é possível consultar o número do hash de confirmação, por exemplo, se o número do hash for x110bd64, você pode fazer algo assim para ver a diferença:

git diff x110bd64 pom.xml
Alireza
fonte
4

origem do git diff -w HEAD / caminho principal / para / arquivo

CatalinBerta
fonte
2
git diff master~20 -- pom.xml

Funciona se você também não estiver no ramo mestre.

Gunar Gessner
fonte
2

Se você estiver bem usando uma ferramenta gráfica (ou até preferindo), você pode:

gitk pom.xml

No gitk, você pode clicar em qualquer confirmação (para "selecioná-la") e clicar com o botão direito do mouse em qualquer outra confirmação para selecionar "Dif. Isto -> selecionado" ou "Dif. Selecionado -> este" no menu pop-up, dependendo da ordem que você preferir.

Martin G
fonte
0

Se você precisar diferenciar um único arquivo em um stash, por exemplo, poderá fazer

git diff stash@{0} -- path/to/file
lacostenycoder
fonte
-1

Se você está procurando o diff em um commit específico e deseja usar a interface do usuário do github em vez da linha de comando (digamos que deseja vinculá-lo a outras pessoas), você pode:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Por exemplo:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Observe os links Anterior e Próximo no canto superior direito que permitem navegar por todos os arquivos no commit.

Porém, isso funciona apenas para um commit específico, não para comparar entre duas versões arbitrárias.

Schmick
fonte