Como diferencio o mesmo arquivo entre duas confirmações diferentes no mesmo ramo?


Respostas:


1476

Na página de git-diffmanual:

git diff [--options] <commit> <commit> [--] [<path>...]

Por exemplo, para ver a diferença de um arquivo "main.c" entre agora e duas confirmações, aqui estão três comandos equivalentes:

$ git diff HEAD^^ HEAD main.c
$ git diff HEAD^^..HEAD -- main.c
$ git diff HEAD~2 HEAD -- main.c

43
O ..não é realmente necessário, embora funcione com ele (exceto em versões bastante antigas, talvez). Você também pode usar git logou gitkencontrar SHA1s para usar, caso os dois commits estejam muito distantes. gitktambém possui um "diff selected -> this" e "diff this -> selected" em seu menu de contexto.
Cascabel 26/07

17
Isso funcionará mesmo que o nome do arquivo tenha sido modificado entre as duas confirmações?
Reebenjohn

26
Então, qual é o objetivo do "-"
user64141

29
@ user64141 Isso --é útil, por exemplo, quando você tem um arquivo chamado -p. É bom usar em scripts, apenas em casos raros necessários na prática.
Palec

13
Nota: você precisa usar caminhos relativos à raiz do repositório. Os caminhos relativos ao diretório de trabalho atual não funcionarão.
Kevin Wheeler

281

Você também pode comparar dois arquivos diferentes em duas revisões diferentes, assim:

git diff <revision_1>:<file_1> <revision_2>:<file_2>


25
nota que parece que se <file_1>e <file_2>estão no diretório atual, não no diretório de nível superior git gerenciado, um tem que preceder ./em Unix:<revision_1>:./filename_1
Andre Holzner

7
<revisão>: pode ser omitido, para que você possa diferenciar um arquivo que ainda não foi confirmado.
Yaroslav Nikitenko

2
Observe que no Windows é necessário usar '/' para caminhos de arquivo, não '\'.
Np8 23/10/18

88

Se você configurou o "difftool", pode usar

git difftool revision_1:file_1 revision_2:file_2

Exemplo: Comparando um Arquivo da Última Confirmação com a Confirmação Anterior na Mesma Ramificação: Supondo que, se você estiver na pasta raiz do projeto

$git difftool HEAD:src/main/java/com.xyz.test/MyApp.java HEAD^:src/main/java/com.xyz.test/MyApp.java

Você deve ter as seguintes entradas no seu arquivo ~ / .gitconfig ou no projeto / .git / config. Instale o p4merge [Esta é minha ferramenta preferida de difusão e mesclagem]

[merge]
    tool = p4merge
    keepBackup = false
[diff]
    tool = p4merge
    keepBackup = false
[difftool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
[mergetool]
    keepBackup = false
[difftool]
    keepBackup = false
[mergetool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
    cmd = p4merge.exe \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

50

Verifique $ git log, copie o ID SHA-1 das duas confirmações diferentes e execute o git diffcomando com esses IDs. por exemplo:

$ git diff (sha-id-one) (sha-id-two)

18
Se você deseja o diff para um arquivo específico, adicione o caminho no final do comando.
Hbrent

Também faça um "git pull" para baixar as informações completas da árvore se os dois commits estiverem em diferentes ramificações. Caso contrário, você receberá um erro "fatal: bad object".
User238607

4
git diff (sha-id-one) (sha-id-two) -- filename.ext sem o nome do arquivo, ele listará as diferenças de todos os arquivos nesses dois commits.
precisa saber é o seguinte

40

Se você quiser ver todas as alterações no arquivo entre as duas confirmações em uma base de confirmação por confirmação, também poderá fazer

git log -u $start_commit..$end_commit -- path/to/file


O que são "$ start_commit" e "$ end_commit"? Eles são literais ou, se não, você pode fornecer um exemplo?
Peter Mortensen

Essas são variáveis do shell que contêm a revisão de início e fim, o que pode em vez disso ser literais SHA1 ou refs
cxreg

21

Aqui está um script Perl que imprime os comandos diff do Git para um determinado arquivo, conforme encontrado em um comando de log do Git.

Por exemplo

git log pom.xml | perl gldiff.pl 3 pom.xml

Rendimentos:

git diff 5cc287:pom.xml e8e420:pom.xml
git diff 3aa914:pom.xml 7476e1:pom.xml
git diff 422bfd:pom.xml f92ad8:pom.xml

que poderia ser recortado e colado em uma sessão de janela de shell ou canalizado para /bin/sh.

Notas:

  1. o número (3 neste caso) especifica quantas linhas imprimir
  2. o arquivo (pom.xml neste caso) deve concordar nos dois lugares (você pode envolvê-lo em uma função shell para fornecer o mesmo arquivo nos dois lugares) ou colocá-lo em um diretório binário como um script shell

Código:

# gldiff.pl
use strict;

my $max  = shift;
my $file = shift;

die "not a number" unless $max =~ m/\d+/;
die "not a file"   unless -f $file;

my $count;
my @lines;

while (<>) {
    chomp;
    next unless s/^commit\s+(.*)//;
    my $commit = $1;
    push @lines, sprintf "%s:%s", substr($commit,0,6),$file;
    if (@lines == 2) {
        printf "git diff %s %s\n", @lines;
        @lines = ();
    }
    last if ++$count >= $max *2;
}

14

Se você quiser fazer uma comparação com mais de um arquivo, com o método especificado por @mipadi:

Por exemplo, diff between HEADe your master, para encontrar todos os .coffeearquivos:

git diff master..HEAD -- `find your_search_folder/ -name '*.coffee'`

Isso pesquisará recursivamente your_search_folder/todos os .coffeearquivos e fará uma diferença entre eles e suas masterversões.


13

Se você possui vários arquivos ou diretórios e deseja comparar confirmações não contínuas, faça o seguinte:

Faça uma ramificação temporária ( "revisão" neste exemplo)

git checkout -b revision

Retroceder para o primeiro destino de confirmação

git reset --hard <commit_target>

Cereja escolhendo aqueles que se interessam

git cherry-pick <commit_interested> ...

Apply diff

git diff <commit-target>^

Quando você terminou

git branch -D revision

2
Obrigado por esta solução. Funcionou bem para o meu caso de uso. A única coisa que eu atualizaria é que, quando terminar, você não poderá excluir o ramo até que o desative.
Steven Dix

9

Apenas outra maneira de usar a grandiosidade do Git ...

git difftool HEAD HEAD@{N} /PATH/FILE.ext

I definido um alias a partir desta resposta que funciona com bash:difftool-file = "!git difftool HEAD@{\"$2\"} HEAD \"$1\" #"
blueogive

2

Se você deseja uma comparação visual simples no Windows, como é possível obter no Visual SourceSafe ou no Team Foundation Server (TFS), tente o seguinte:

  • clique com o botão direito do mouse no arquivo no File Explorer
  • selecione 'Histórico do Git'

Nota: Após a atualização para o Windows 10, perdi as opções do menu de contexto do Git. No entanto, você pode conseguir o mesmo usando 'gitk' ou 'gitk filename' em uma janela de comando.

Depois de chamar 'Git History', a ferramenta Git GUI será iniciada, com um histórico do arquivo no painel superior esquerdo. Selecione uma das versões que você gostaria de comparar. Em seguida, clique com o botão direito do mouse na segunda versão e escolha

Dif - -> selecionado

ou

Dif. Selecionado -> este

As diferenças codificadas por cores aparecerão no painel inferior esquerdo.


Nota para os que recusam: esta é uma solução simples, fácil de implementar e soluciona o problema do OP. Ele funciona no Windows que o OP está usando claramente (consulte as referências ao TFS e ao VSS na pergunta).
Resource
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.