“Git diff” i yaptığımda yan yana diferansiyeli nasıl alabilirim?


163

"Git diff" yazdığımda, "diff -y" gibi yan yana bir fark görmek veya "kdiff3" gibi etkileşimli bir fark aracında fark göstermek istiyorum. Bu nasıl yapılabilir?




Yanıtlar:


89

Git'te diff'in dahili bir uygulaması olsa da, bunun yerine harici bir araç ayarlayabilirsiniz.

Harici bir fark aracı belirtmenin iki farklı yolu vardır:

  1. ayarı GIT_EXTERNAL_DIFFve GIT_DIFF_OPTSçevre değişkenleri.
  2. harici fark aracının yapılandırılması git config

Ayrıca bakınız:

Bir işlemi yaparken git diffGit, hem yukarıdaki ortam değişkenlerinin ayarlarını hem de .gitconfigdosyasını kontrol eder.

Git varsayılan olarak diff programına aşağıdaki yedi bağımsız değişkeni iletir:

path  old-file  old-hex old-mode  new-file  new-hex new-mode

Genellikle yalnızca eski dosya ve yeni dosya parametrelerine ihtiyacınız vardır. Tabii ki çoğu diff aracı argüman olarak sadece iki dosya adını alır. Bu, Git'in komut dosyasına sağladığı bağımsız değişkenleri alan ve bunları seçtiğiniz harici git programına veren küçük bir sarmalayıcı komut dosyası yazmanız gerektiği anlamına gelir.

Diyelim ki sarmalayıcı komut dosyanızı altına koydunuz ~/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"

daha sonra bu komut dosyasını yürütülebilir hale getirmeniz gerekir:

chmod a+x ~/scripts/my_diff.sh

daha sonra Git'e özel fark sarmalayıcı komut dosyanızı nasıl ve nerede bulacağınızı söylemeniz gerekir. Bunu nasıl yapacağınız üç seçeneğiniz var: (.gitconfig dosyasını düzenlemeyi tercih ediyorum)

  1. Kullanma GIT_EXTERNAL_DIFF,GIT_DIFF_OPTS

    örneğin .bashrc veya .bash_profile dosyanızda aşağıdakileri ayarlayabilirsiniz:

    GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
    export GIT_EXTERNAL_DIFF
    
  2. kullanma git config

    sarmalayıcı komut dosyanızın nerede bulunacağını tanımlamak için "git config" kullanın:

    git config --global diff.external ~/scripts/my_diff.sh
    
  3. ~/.gitconfigDosyanızı düzenleme

    ~/.gitconfigşu satırları eklemek için dosyanızı düzenleyebilirsiniz :

    [diff]
      external = ~/scripts/my_diff.sh
    

Not:

Özel fark aracınızı yüklemeye benzer şekilde, birleştirmeyi görselleştirmeye yardımcı olmak için görsel birleştirme aracı olabilecek özel bir birleştirme aracı da yükleyebilirsiniz. (progit.org sayfasına bakınız)

Bkz. Http://fredpalma.com/518/visual-diff-and-merge-tool/ ve https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration


1
Bu git terminal renklendirmesini koruyor mu?
Sridhar Sarnobat

3
Bu harika, ancak her dosya için yeni bir görüntüleyici başlattı. Diyelim ki, bir konsolide diff oluşturmak için herhangi bir şekilde meld?
HRJ

2
@Tilo im olarak vim için hata alıyorum: Uyarı: Çıkış bir uçbirime değil
ölü programcı

Can meldsürümü ne için diff görmek istediğiniz dosya (lar) seçebileceğiniz bir dizin diff yapmak üzere yapılandırılabilir? Şu anda meldher dosya için ayrı bir komut çalıştırıyor meldve bir sonraki dosyayı görmek için çıkmak zorundayım . Mercurial kullanıldığında melddavrandığı gibi değiştirilmiş dosyaların bir dizin listesini göstermeyi tercih ederim meld.
kasperd

163

Git difftool'u deneyin

Yerine git difftoolkullanın git diff. Asla geri dönmeyeceksin.

Örnek bir kullanım eklemek için GÜNCELLEME:

Aşağıda konuşulan başka bir stackoverflow bağlantısı git difftool: Tercih edilen diff aracım / görüntüleyicimle 'git diff' çıktısını nasıl görüntüleyebilirim?

Komutunun daha yeni sürümleri için git, difftoolkomut kullanıma hazır birçok harici fark aracını destekler. Örneğin vimdiff, otomatik olarak desteklenir ve komut satırından şu şekilde açılabilir:

cd /path/to/git/repo
git difftool --tool=vimdiff

git difftool --tool-helpBurada listelenen diğer desteklenen harici fark araçları örnek bir çıktıdır:

'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

34
Ya da belki geri alırsanız gidersiniz This message is displayed because 'diff.tool' is not configured.. Belki de cevabı en az nasıl yapılandıracağınızla güncelleyin, böylece terminalde yan yana farklılıklar gösterebilir, OP'nin istediği şey nedir? GUI araçları, ssh kullanarak bağlandığınız uzak sunucuda oldukça işe yaramaz.
Petr

1
İlginçtir, SSH'd iken şahsen hiç kullanmam gerektiğini düşünmüyorum. DVCS ile ilgili güzel şeylerden biri Dağıtılmış kısımdır: en azından çevrelerimde, etrafta konuşmak istediğim repoyu yerel olarak klonlamak asla zor değildir.
Matt Ball

1
Benim config En azından git difftoolile vimdiffher zaman doğru iki dosya / tamponlar hizaya gelmez.
Rohmer

1
Bu güzel, ve böylece aşağıda cevap listesinde: OI git difftool -ytkdiff istemini önlemek için kullanın
harshvchawla

İlgili: git difftoolWindows ve Linux'ta kaynaştırın : stackoverflow.com/a/48979939/4561887
Gabriel Staples

55

Ayrıca deneyebilirsiniz git diff --word-diff. Tam olarak yan yana değil, bir şekilde daha iyi, bu yüzden gerçek yan yana ihtiyaçlarınıza tercih edebilirsiniz.


12
Bu en kolay yol. Daha da iyisigit diff --word-diff=color
Rolf

@Rolf --word-diff=colorbana geçersiz bir seçenek hatası veriyor. Hangi sürümde tanıtıldı?
Holloway

@Trengot I koşmak git 1.7.9 olan 02/2012
Rolf

4
@Rolf varsayılan yüklü sürümü burada 1.7.1 olduğunu. Farkı açıklayabilir. git diff --color-wordsçalışır.
Holloway

4
Evet, git diff --color-wordsmodern git versiyonlarına geçmenin yolu.
VasiliNovikov

41

ydiff

Eski adıyla cdiff, bu araç yan yana , artımlı ve renkli fark görüntüleyebilir.

git diffYapmak yerine şunları yapın:

ydiff -s -w0

Bu, ydifffarklı dosyaların her biri için yan yana görüntüleme modunda başlatılır .

Yükleme yeri:

python3 -m pip install --user ydiff

-veya-

brew install ydiff

İçin git logşunları kullanabilirsiniz:

ydiff -ls -w0

-w0terminal genişliğinizi otomatik olarak algılar. Ayrıntılar ve demo için ydiff GitHub veri havuzu sayfasına bakın .

Git 2.18.0, ydiff 1.1'de test edilmiştir.


@RyneEverett: icdiff git diff | cdiff -sile eşdeğerini nasıl yapacağınızı açıklayabilir misiniz?
einpoklum

Sadece ydiff -sbir git / svn / hg çalışma alanından çalıştırın,
içeri

fark'ı Git'in geçmişi boyunca belirli bir dosyayla sınırlamak cd <git repo>ve sonra çalıştırmak istiyorsanızydiff -ls <path/to/file>
slm

22

Aşağıdaki işlemleri diffkullanarak yan yana yapabilirsiniz sdiff:

$ git difftool -y -x sdiff  HEAD^ | less

Burada HEAD^, neye karşı koymak istediğinizle değiştirmeniz gereken bir örnek var.

Bu çözümü burada birkaç öneride daha buldum . Ancak, bu OP'nin sorusunu kısa ve öz bir şekilde cevaplıyor.

Argümanların açıklaması için man git-difftool'a bakınız .


Gemide yorumları alarak, git sdiffaşağıdaki yürütülebilir komut dosyasını yazarak kullanışlı bir komut oluşturabilirsiniz :

#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less

Farklı /usr/bin/git-sdiffve kaydedin chmod -x. Sonra bunu yapabilirsiniz:

$ git sdiff HEAD^

Genellikle "$ git difftool -x 'sdiff -s -w 240'" (ya da genişliği ne olursa olsun ekranı) Aynı satırları bastırmak isteyen ve sadece bir dosya (Başka ne vimdiff yapmak) varken / yapmanız
HidekiAI

1
Kullandığım böylece @HidekiAI I bunu her zaman genişlik terminali tip bir ağrı bulmak tput colsbunun yerine örneğin: git difftool -x "sdiff -s -w $(tput cols)".
jaume

renkteki değişiklikleri vurgulayabilir mi? Şu anda, gerçekte ne olduğunu görmek için gözlerimizi kullanmamız gerekiyor gibi görünüyor
nonopolarity

Güzel bir renkli ekran elde etmek için sdiff'i icdiff ile değiştirin.
Greg

10
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'

o zaman basitçe:

git diff

1
`meld. ' çok çalışıyor! Ve tüm değişiklikleri birleştirilmiş pencerede gösterir.
HRJ

@HRJ mükemmel çalışıyor! Çok basit ve pratik :)
waldyrious


7

Kullandığım colordiff .

Mac OS X'te ile yükleyin

$ sudo port install colordiff

Linux'ta apt get install colordiffdağıtımınıza bağlı olarak muhtemelen böyle bir şey.

Sonra:

$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD

Veya bir takma ad oluşturun

$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""

Sonra kullanabilirsiniz

$ git diffy HEAD^ HEAD

Ben "diffy" olarak adlandırdım çünkü unix'te diff -yyan yana fark var. Colordiff ayrıca daha güzel renkler ekler. Seçenekte -ydw, yyan-yana içindir, wboşlukları göz ardı etmek ve dminimum diff üretmektir (genellikle fark olarak daha iyi bir sonuç almak)


istemi -yatlamak için ekleyin Launch 'colordiff' [Y/n]:.
Beni Cherniavsky-Paskin

olduğundan emin misin git alias diffy "difftool --extcmd=\"colordiff -ydw\""? Olmamalı mı git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""?
nonopolarity

6

Unix için, sadece gitve yerleşik olanı birleştirin diff:

git show HEAD:path/to/file | diff -y - path/to/file

Tabii ki, HEAD'i başka bir git referansıyla değiştirebilirsiniz ve muhtemelen -W 170diff komutuna benzer bir şey eklemek istersiniz .

Bu, dizin içeriğinizi geçmiş bir işlemle karşılaştırdığınızı varsayar. İki taahhüt arasında karşılaştırma yapmak daha karmaşıktır. Kabuğunuz ise bash"işlem ikamesi" ni kullanabilirsiniz:

diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)

Burada REF1ve REF2git referanslarıdır - etiketler, dallar veya karmalar.


Teşekkürler - 'git show HEAD: path / to / file' komutunuz, kendi çözümümle ortaya çıkmam gereken şeydi, 'vimdfiff <(git show HEAD: path / to / file) path / to / file'. Bitler hala doğru şekilde sıralanmamış, ancak şu anda sahip olduğum en iyi çözüm bu.
talexb

5

Şahsen icdiff'i çok seviyorum !

Üzerinde iseniz Mac OS Xile HomeBrew, sadece yap brew install icdiff.

Dosya etiketlerini ve diğer harika özellikleri doğru bir şekilde almak için ~/.gitconfig:

[pager]
    difftool = true
[diff]
    tool = icdiff
[difftool "icdiff"]
    cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"

Ve şu şekilde kullanıyorum: git difftool


3

Bu soru, farkları bulmak için git yerleşik yolunu kullanmanın hızlı bir yolunu ararken ortaya çıktı. Çözüm kriterlerim:

  • Hızlı başlatma, gerekli yerleşik seçenekler
  • Birçok formatı kolayca işleyebilir, xml, farklı programlama dilleri
  • Büyük dosyalardaki küçük kod değişikliklerini hızlı bir şekilde belirleyin

Git içinde renk almak için bu cevabı buldum .

Çizgi farkı yerine yan yana fark almak için mb14'ün bu soruya mükemmel cevabını aşağıdaki parametrelerle değiştirdim:

$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"

Ekstra [- veya {+ 'yı beğenmediyseniz seçenek --word-diff=colorkullanılabilir.

$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color

Bu, hem json hem de xml metin ve java kodu ile uygun karşılaştırmanın elde edilmesine yardımcı oldu.

Özetle, --word-diff-regexküçük satır değişikliklerine sahip büyük dosyalara göz atarken, standart satır farkına kıyasla renklendirilmiş yan yana kaynak kodu deneyimi elde etmek için seçenekler renk ayarlarıyla birlikte yararlı bir görünüme sahiptir.


3

Bazıları git git yan yana difüzyon için cdiff'den bahsetti, ancak hiç kimse tam bir uygulama vermedi.

Kurulum 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

Bu satırları ekleyerek ~ / .gitconfig dosyasını düzenleyin:

[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

CDiff'in Diff ile çalışması için çağrı cihazı kapalıdır, aslında zaten bir çağrı cihazıdır, bu yüzden bu iyidir. Difftool bu ayarlardan bağımsız olarak çalışacaktır.

Gösteri takma adı gereklidir, çünkü git show yalnızca bağımsız diff araçlarını bağımsız değişken aracılığıyla destekler.

Diff harici komutunun sonundaki '#' önemlidir. Git'in diff komutu diff komutuna $ @ (tüm kullanılabilir fark değişkenleri) ekler, ancak yalnızca iki dosya adını istiyoruz. Bu yüzden bu ikisini açıkça $ 2 ve $ 5 ile çağırıyoruz ve sonra $ @ 'ı aksi takdirde sdiff'i karıştıracak bir yorumun arkasına saklıyoruz. Şuna benzer bir hatayla sonuçlanıyor:

fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.

Şimdi yan yana farklılıklar üreten Git komutları:

git diff <SHA1> <SHA2> 
git difftool <SHA1> <SHA2>
git showw <SHA>

Cdiff kullanımı:

'SPACEBAR' - Advances the page of the current file.
'Q'        - Quits current file, thus advancing you to the next file.

Artık git diff ve difftool ile yan yana farkınız var. Ve ihtiyacınız varsa, güçlü kullanıcı özelleştirmesi için cdiff python kaynak koduna sahipsiniz.


2

İşte bir yaklaşım. Daha az boru kullanırsanız, xterm genişliği 80'e ayarlanır ve bu çok sıcak değildir. Ancak, komutu COLS = 210 ile devam ettirirseniz, genişletilmiş xterm'inizi kullanabilirsiniz.

gitdiff()
{
    local width=${COLS:-$(tput cols)}
    GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}

1
Komik. Bir takma adla isimle imzaladım ama bu göz ardı edildi ... Beni gezdiğiniz için teşekkürler, Stack Overflow. :(
Thomas Mellman

2

Intellij IDEA'yı açın , "Sürüm Denetimi" araç penceresinde bir veya birden fazla işlem seçin, değiştirilen dosyalara göz atın ve her dosya için değişiklikleri yan yana incelemek üzere çift tıklayın.

Birlikte verilen komut satırı başlatıcısı ile IDEA'yı istediğiniz yerde idea some/path

sürüm kontrol görünümü farklı görüş


1

Bu konuda çok iyi cevaplar var. Bu konudaki çözümüm bir senaryo yazmaktı.

Bu 'git-scriptname' olarak adlandırın (ve çalıştırılabilir yapın ve PATH'nize, herhangi bir komut dosyası gibi koyun) ve çalıştırarak normal bir git komutu gibi çağırabilirsiniz.

$ git scriptname

Gerçek işlevsellik sadece son satır. İşte kaynak:

#!/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

1

Bu biraz sınırlı bir çözüm olabilir, ancak diffharici komutlar olmadan sistemin komutunu kullanan iş :

diff -y  <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
  • yalnızca değişiklik satırlarını kullanın --suppress-common-lines( diffseçenekleriniz destekliyorsa).
  • bu durumda renk yok, sadece normal diffişaretleyiciler
  • sütun genişliğini değiştirebilir --width=term-width; Bash içinde genişliği $COLUMNSveya olarak alabilirsiniz tput cols.

Bu, daha fazla kolaylık sağlamak için yardımcı bir git komut dosyasına da sarılabilir, örneğin, aşağıdaki gibi kullanım:

git diffy the/file/path --from rev1 --to rev2
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.