Quando digito "git diff", gostaria de ver um diff lado a lado, como com "diff -y", ou gostaria de exibir o diff em uma ferramenta de diff interativa como "kdiff3". Como isso pode ser feito?
Quando digito "git diff", gostaria de ver um diff lado a lado, como com "diff -y", ou gostaria de exibir o diff em uma ferramenta de diff interativa como "kdiff3". Como isso pode ser feito?
Respostas:
Embora o Git tenha uma implementação interna do diff, você pode configurar uma ferramenta externa.
Existem duas maneiras diferentes de especificar uma ferramenta de comparação externa:
GIT_EXTERNAL_DIFF
eo GIT_DIFF_OPTS
ambiente variáveis.git config
Veja também:
git diff --help
Ao fazer a git diff
, o Git verifica as configurações das variáveis de ambiente acima e seu .gitconfig
arquivo.
Por padrão, o Git passa os sete argumentos a seguir para o programa diff:
path old-file old-hex old-mode new-file new-hex new-mode
Normalmente, você só precisa dos parâmetros do arquivo antigo e do novo arquivo. É claro que a maioria das ferramentas diff usa apenas dois nomes de arquivos como argumento. Isso significa que você precisa escrever um pequeno script wrapper, que aceita os argumentos que o Git fornece ao script e os entrega ao programa externo do git de sua escolha.
Digamos que você coloque seu wrapper-script em ~/scripts/my_diff.sh
:
#!/bin/bash
# un-comment one diff tool you'd like to use
# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5"
# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"
# using Meld
/usr/bin/meld "$2" "$5"
# using VIM
# /usr/bin/vim -d "$2" "$5"
você precisa tornar esse script executável:
chmod a+x ~/scripts/my_diff.sh
você precisará informar ao Git como e onde encontrar seu script de wrapper diff personalizado. Você tem três opções de como fazer isso: (prefiro editar o arquivo .gitconfig)
Usando GIT_EXTERNAL_DIFF
,GIT_DIFF_OPTS
Por exemplo, no seu arquivo .bashrc ou .bash_profile, você pode definir:
GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
export GIT_EXTERNAL_DIFF
Usando git config
use "git config" para definir onde seu script wrapper pode ser encontrado:
git config --global diff.external ~/scripts/my_diff.sh
Editando seu ~/.gitconfig
arquivo
você pode editar seu ~/.gitconfig
arquivo para adicionar estas linhas:
[diff]
external = ~/scripts/my_diff.sh
Nota:
De maneira semelhante à instalação da ferramenta diff personalizada, você também pode instalar uma ferramenta de mesclagem personalizada, que pode ser uma ferramenta de mesclagem visual para ajudar a visualizar melhor a mesclagem. (veja a página progit.org)
Consulte: http://fredpalma.com/518/visual-diff-and-merge-tool/ e https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
meld
,?
meld
versão pode ser configurada para fazer uma comparação de diretório, onde posso escolher para quais arquivos quero ver a comparação? Atualmente, ele executa um meld
comando separado para cada arquivo, e eu tenho que sair meld
para ver o próximo arquivo. Prefiro meld
me mostrar uma lista de diretórios de arquivos alterados, como se comporta quando meld
é usado no Mercurial.
Use em git difftool
vez de git diff
. Você nunca voltará.
Aqui está um link para outro stackoverflow que fala sobre git difftool
: Como visualizo a saída 'git diff' com minha ferramenta / visualizador preferido de diff?
Para versões mais recentes do git
, o difftool
comando suporta muitas ferramentas externas diff prontas para uso. Por exemplo, vimdiff
é suportado automaticamente e pode ser aberto na linha de comando:
cd /path/to/git/repo
git difftool --tool=vimdiff
Outras ferramentas de diff externas suportadas são listadas git difftool --tool-help
aqui, é um exemplo de saída:
'git difftool --tool=<tool>' may be set to one of the following:
araxis
kompare
vimdiff
vimdiff2
The following tools are valid, but not currently available:
bc3
codecompare
deltawalker
diffuse
ecmerge
emerge
gvimdiff
gvimdiff2
kdiff3
meld
opendiff
tkdiff
xxdiff
This message is displayed because 'diff.tool' is not configured.
. Talvez atualize a resposta com o mínimo de como configurar essa coisa, para que ela exiba diferenças lado a lado no terminal, o que o OP pediu? As ferramentas da GUI são bastante inúteis no servidor remoto onde você se conecta usando o ssh.
git difftool
com vimdiff
nem sempre se alinham os dois arquivos / buffers corretamente.
git difftool -y
para evitar tkdiff pronta
git difftool
no Windows e Linux: stackoverflow.com/a/48979939/4561887
Você também pode tentar git diff --word-diff
. Não é exatamente lado a lado, mas de alguma forma melhor, então você pode preferir à sua real necessidade lado a lado.
git diff --word-diff=color
--word-diff=color
me dá um erro de opção inválida. Em qual versão foi introduzida?
git diff --color-words
funciona.
git diff --color-words
é o caminho a seguir nas versões modernas do git.
ydiff
Anteriormente chamada cdiff
, essa ferramenta pode exibir diferenças lado a lado , incremental e colorida .
Em vez de fazer git diff
, faça:
ydiff -s -w0
Isso será iniciado ydiff
no modo de exibição lado a lado para cada um dos arquivos com diferenças.
Instale com:
python3 -m pip install --user ydiff
-ou-
brew install ydiff
Para git log
, você pode usar:
ydiff -ls -w0
-w0
detecta automaticamente a largura do seu terminal. Veja a ydiff
página do repositório do GitHub para detalhes e demonstração.
Testado no Git 2.18.0, ydiff 1.1.
git diff | cdiff -s
ao icdiff?
ydiff -s
partir de um espaço de trabalho git / svn / hg, você não precisa
cd <git repo>
e , em seguida, executeydiff -ls <path/to/file>
Você pode fazer um lado a lado diff
usando sdiff
o seguinte:
$ git difftool -y -x sdiff HEAD^ | less
Onde HEAD^
está um exemplo que você deve substituir pelo que você quer diferenciar.
Encontrei esta solução aqui, onde há algumas outras sugestões também. No entanto, essa resposta é a pergunta do OP de maneira sucinta e clara.
Veja o man git-difftool para uma explicação dos argumentos.
Levando os comentários em consideração, você pode criar um git sdiff
comando útil escrevendo o seguinte script executável:
#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less
Salve como /usr/bin/git-sdiff
e chmod -x
. Então você poderá fazer isso:
$ git sdiff HEAD^
tput cols
em vez disso, por exemplo: git difftool -x "sdiff -s -w $(tput cols)"
.
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'
então simplesmente:
git diff
Se você quiser ver diferenças lado a lado em um navegador sem envolver o GitHub, poderá desfrutar do git webdiff , um substituto para git diff
:
$ pip install webdiff
$ git webdiff
Isso oferece várias vantagens sobre os difftools da GUI tradicional, como tkdiff
no sentido de oferecer realce de sintaxe e mostrar diferenças de imagem.
Leia mais sobre isso aqui .
Eu uso colordiff .
No Mac OS X, instale-o com
$ sudo port install colordiff
No Linux, é possível apt get install colordiff
ou algo assim, dependendo da sua distribuição.
Então:
$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD
Ou crie um alias
$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""
Então você pode usá-lo
$ git diffy HEAD^ HEAD
Eu o chamei de "diffy" porque diff -y
é o diff lado a lado no unix. Colordiff também adiciona cores mais agradáveis. Na opção -ydw
, y
é para o lado a lado, w
é para ignorar espaços em branco e d
é para produzir a diferença mínima (geralmente você obtém um melhor resultado como diferença)
-y
para ignorar o Launch 'colordiff' [Y/n]:
prompt.
git alias diffy "difftool --extcmd=\"colordiff -ydw\""
? Não deveria ser git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""
?
Para unix, combinando just git
e o built-in diff
:
git show HEAD:path/to/file | diff -y - path/to/file
Obviamente, você pode substituir HEAD por qualquer outra referência git e provavelmente deseja adicionar algo como -W 170
o comando diff.
Isso pressupõe que você está apenas comparando o conteúdo do diretório com uma confirmação anterior. Comparar entre dois commits é mais complexo. Se o seu shell for, bash
você pode usar "substituição de processo":
diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)
onde REF1
e REF2
são referências git - tags, ramificações ou hashes.
Eu pessoalmente gosto muito de icdiff !
Se você estiver em Mac OS X
com HomeBrew
, apenas faça brew install icdiff
.
Para obter os rótulos dos arquivos corretamente, além de outros recursos interessantes, tenho no meu ~/.gitconfig
:
[pager]
difftool = true
[diff]
tool = icdiff
[difftool "icdiff"]
cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"
E eu uso como: git difftool
Essa pergunta apareceu quando eu estava procurando uma maneira rápida de usar o git builtin para localizar diferenças. Meus critérios de solução:
Encontrei esta resposta para obter cores no git.
Para obter diferenças lado a lado em vez de diferenças de linha, ajustei a excelente resposta do mb14 nesta pergunta com os seguintes parâmetros:
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"
Se você não gostar do extra [- ou {+, a opção --word-diff=color
pode ser usada.
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color
Isso ajudou a obter uma comparação adequada com o texto json e xml e o código java.
Em resumo, as --word-diff-regex
opções têm uma visibilidade útil, juntamente com as configurações de cores, para obter uma experiência colorida do código-fonte lado a lado em comparação com o diferencial de linha padrão, ao navegar por arquivos grandes com pequenas alterações de linha.
Vários outros já mencionaram o cdiff para diferenciar lado a lado do git, mas ninguém deu uma implementação completa dele.
Setup cdiff:
git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
# or just create a new terminal
Edite ~ / .gitconfig inserindo estas linhas:
[pager]
diff = false
show = false
[diff]
tool = cdiff
external = "cdiff -s $2 $5 #"
[difftool "cdiff"]
cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"
[alias]
showw = show --ext-dif
O pager desativado é necessário para que o cdiff funcione com o Diff, ele é essencialmente um pager de qualquer maneira, portanto está ótimo. A ferramenta Difftool funcionará independentemente dessas configurações.
O alias show é necessário porque o git show suporta apenas ferramentas diff externas via argumento.
O '#' no final do comando externo diff é importante. O comando diff do Git anexa um $ @ (todas as variáveis diff disponíveis) ao comando diff, mas queremos apenas os dois nomes de arquivos. Então, chamamos esses dois explicitamente com US $ 2 e US $ 5 e, em seguida, ocultamos o $ @ por trás de um comentário que, de outra forma, confundiria sdiff. Resultando em um erro parecido com:
fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
Comandos Git que agora produzem diferenças lado a lado:
git diff <SHA1> <SHA2>
git difftool <SHA1> <SHA2>
git showw <SHA>
Uso de Cdiff:
'SPACEBAR' - Advances the page of the current file.
'Q' - Quits current file, thus advancing you to the next file.
Agora você tem diff lado a lado via git diff e difftool. E você tem o código-fonte cdiff python para personalização de usuários avançados, caso precise.
Aqui está uma abordagem. Se você passar por menos, a largura xterm é definida como 80, o que não é tão quente. Mas se você prosseguir com o comando, por exemplo, COLS = 210, poderá utilizar o xterm expandido.
gitdiff()
{
local width=${COLS:-$(tput cols)}
GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
Abra Intellij IDEA , selecione uma confirmação única ou múltipla na janela da ferramenta "Controle de Versão", procure os arquivos alterados e clique duas vezes neles para inspecionar as alterações lado a lado de cada arquivo.
Com o iniciador de linha de comando incluído, você pode trazer o IDEA para qualquer lugar com um simples idea some/path
Há muitas boas respostas neste tópico. Minha solução para esse problema foi escrever um script.
Nomeie esse 'git-scriptname' (e torne-o executável e coloque-o no PATH, como qualquer script), e você pode invocá-lo como um comando normal do git executando
$ git scriptname
A funcionalidade real é apenas a última linha. Aqui está a fonte:
#!/usr/bin/env zsh
#
# Show a side-by-side diff of a particular file how it currently exists between:
# * the file system
# * in HEAD (latest committed changes)
function usage() {
cat <<-HERE
USAGE
$(basename $1) <file>
Show a side-by-side diff of a particular file between the current versions:
* on the file system (latest edited changes)
* in HEAD (latest committed changes)
HERE
}
if [[ $# = 0 ]]; then
usage $0
exit
fi
file=$1
diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R
Esta pode ser uma solução um tanto limitada, mas executa o trabalho usando o diff
comando do sistema sem ferramentas externas:
diff -y <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
--suppress-common-lines
(se o seu diff
suportar a opção).diff
marcadores usuais--width=term-width
; no Bash pode obter a largura como $COLUMNS
ou tput cols
.Isso também pode ser envolvido em um script git helper para maior comodidade, por exemplo, uso como este:
git diffy the/file/path --from rev1 --to rev2