Bagaimana saya bisa mendapatkan diff berdampingan ketika saya melakukan "git diff"?

163

Ketika saya mengetik "git diff", saya ingin melihat diff berdampingan, seperti dengan "diff -y", atau ingin menampilkan diff dalam alat diff interaktif seperti "kdiff3". Bagaimana ini bisa dilakukan?

Mike
sumber

Jawaban:

89

Meskipun Git memiliki implementasi internal diff, Anda dapat mengatur alat eksternal sebagai gantinya.

Ada dua cara berbeda untuk menentukan alat diff eksternal:

  1. pengaturan GIT_EXTERNAL_DIFFdan GIT_DIFF_OPTSvariabel lingkungan.
  2. mengkonfigurasi alat diff eksternal melalui git config

Lihat juga:

Ketika melakukan a git diff, Git memeriksa pengaturan variabel lingkungan di atas dan .gitconfigfile -nya .

Secara default, Git meneruskan tujuh argumen berikut ke program diff:

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

Anda biasanya hanya memerlukan parameter file lama dan file baru. Tentu saja sebagian besar alat diff hanya mengambil dua nama file sebagai argumen. Ini berarti bahwa Anda perlu menulis skrip wrapper kecil, yang mengambil argumen yang disediakan oleh Git ke skrip, dan menyerahkannya ke program git eksternal pilihan Anda.

Katakanlah Anda meletakkan skrip pembungkus Anda di bawah ~/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"

Anda kemudian perlu membuat skrip itu dapat dieksekusi:

chmod a+x ~/scripts/my_diff.sh

Anda kemudian perlu memberi tahu Git bagaimana dan di mana menemukan skrip pembungkus khusus Anda. Anda memiliki tiga pilihan cara melakukannya: (Saya lebih suka mengedit file .gitconfig)

  1. Menggunakan GIT_EXTERNAL_DIFF,GIT_DIFF_OPTS

    misalnya dalam file .bashrc atau .bash_profile Anda, Anda dapat mengatur:

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

    gunakan "git config" untuk menentukan di mana skrip wrapper Anda dapat ditemukan:

    git config --global diff.external ~/scripts/my_diff.sh
    
  3. Mengedit ~/.gitconfigfile Anda

    Anda dapat mengedit ~/.gitconfigfile Anda untuk menambahkan baris-baris ini:

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

catatan:

Demikian pula untuk menginstal alat diff khusus Anda, Anda juga dapat menginstal alat gabungan kustom, yang bisa menjadi alat penggabungan visual untuk lebih membantu memvisualisasikan gabungan. (lihat halaman progit.org)

Lihat: http://fredpalma.com/518/visual-diff-and-merge-tool/ dan https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration

Tilo
sumber
1
Apakah ini mempertahankan pewarnaan terminal git?
Sridhar Sarnobat
3
Ini bagus, tetapi meluncurkan penampil baru untuk setiap file. Adakah cara untuk membuat perbedaan konsolidasi, misalnya meld,?
HRJ
2
@ Tuo Saya mendapatkan error untuk vim sebagai im: Peringatan: Output tidak ke terminal
programmer mati
Bisakah meldversi ini dikonfigurasikan untuk melakukan direktori diff, di mana saya dapat memilih file mana yang ingin saya lihat? Saat ini menjalankan meldperintah terpisah untuk setiap file, dan saya harus berhenti melduntuk melihat file berikutnya. Saya lebih suka meldmenunjukkan daftar direktori file yang diubah seperti itu berperilaku ketika melddigunakan dari Mercurial.
kasperd
163

Coba git difftool

Gunakan git difftoolsebagai ganti git diff. Anda tidak akan pernah kembali.

UPDATE untuk menambahkan contoh penggunaan:

Berikut ini tautan ke aliran stackover lain yang membahas git difftool: Bagaimana cara melihat output 'git diff' dengan alat / penampil diff pilihan saya?

Untuk versi yang lebih baru git, difftoolperintah ini mendukung banyak perangkat eksternal yang berbeda. Misalnya vimdiffdidukung otomatis dan dapat dibuka dari baris perintah dengan:

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

Alat diff eksternal lain yang didukung tercantum di git difftool --tool-helpsini adalah contoh keluaran:

'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
Matt Ball
sumber
34
Atau mungkin Anda akan kembali jika mendapatkannya This message is displayed because 'diff.tool' is not configured.. Mungkin memperbarui jawaban dengan minimal cara mengkonfigurasi hal ini, sehingga ia menampilkan berdampingan di terminal yang berbeda, apa yang diminta OP? Alat GUI sangat tidak berguna di server jauh di mana Anda terhubung menggunakan ssh.
Petr
1
Poin yang menarik, meskipun saya pikir saya secara pribadi tidak perlu menggunakan git saat SSH. Salah satu hal baik tentang DVCS adalah bagian yang Didistribusikan: setidaknya di lingkungan saya tidak pernah repot untuk mengkloning repo apa pun yang ingin saya lihat-lihat.
Matt Ball
1
Setidaknya dalam konfigurasi saya, git difftooldengan vimdifftidak selalu mengatur dua file / buffer dengan benar.
Rohmer
1
Itu bagus, dan begitu di bawah dalam daftar jawaban: OI gunakan git difftool -yuntuk mencegah tkdiff prompt
harshvchawla
Terkait: buat berbaur Anda git difftooldi Windows & Linux: stackoverflow.com/a/48979939/4561887
Gabriel Staples
55

Anda juga bisa mencoba git diff --word-diff. Ini tidak persis berdampingan, tapi entah bagaimana lebih baik, jadi Anda mungkin lebih suka itu daripada kebutuhan berdampingan Anda yang sebenarnya.

mb14
sumber
12
Ini cara termudah. Apa yang lebih baik adalahgit diff --word-diff=color
Rolf
@Rolf --word-diff=colormemberiku kesalahan opsi yang tidak valid. Versi apa itu diperkenalkan?
Holloway
@ Trengot saya menjalankan git 1.7.9 yang dimulai dari 02/2012
Rolf
4
@Rolf versi terinstal default di sini adalah 1.7.1. Bisa menjelaskan perbedaannya. git diff --color-wordstidak bekerja.
Holloway
4
Ya, git diff --color-wordsadalah cara untuk menggunakan versi git modern.
VasiliNovikov
41

ydiff

Dahulu disebut cdiff, alat ini dapat menampilkan berdampingan , tambahan , dan warna - warni .

Alih-alih melakukan git diff, lakukan:

ydiff -s -w0

Ini akan diluncurkan ydiffdalam mode tampilan berdampingan untuk masing-masing file dengan perbedaan.

Instal dengan:

python3 -m pip install --user ydiff

-atau-

brew install ydiff

Untuk git log, Anda dapat menggunakan:

ydiff -ls -w0

-w0otomatis mendeteksi lebar terminal Anda. Lihat ydiff halaman repositori GitHub untuk detail dan demo.

Diuji dalam Git 2.18.0, ydiff 1.1.

ymattw
sumber
@RyneEverett: Bisakah Anda menjelaskan bagaimana melakukan hal yang sama git diff | cdiff -sdengan icdiff?
einpoklum
Jalankan saja ydiff -sdari ruang kerja git / svn / hg, Anda tidak perlu menyalurkannya.
ymattw
jika Anda ingin membatasi diff ke file tertentu melalui sejarah Git, cd <git repo>dan kemudian jalankanydiff -ls <path/to/file>
slm
22

Anda dapat melakukan berdampingan diffmenggunakan sdiffsebagai berikut:

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

di mana HEAD^adalah contoh yang harus Anda ganti dengan apa pun yang ingin Anda lawan.

Saya menemukan solusi ini di sini di mana ada beberapa saran lain juga. Namun, jawaban ini adalah pertanyaan OP secara ringkas dan jelas.

Lihat man git-difftool untuk penjelasan argumennya.


Mengambil komentar di papan tulis, Anda dapat membuat git sdiffperintah praktis dengan menulis skrip yang dapat dieksekusi berikut:

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

Simpan sebagai /usr/bin/git-sdiffdan chmod -xitu. Maka Anda akan dapat melakukan ini:

$ git sdiff HEAD^
starfry
sumber
Saya biasanya melakukan "$ git difftool -x 'sdiff -s -w 240'" (atau berapa pun lebar layarnya) jika / ketika saya ingin menekan baris yang sama dan hanya ada satu file (
selain itu
1
@HidekiAI Saya merasa sakit untuk mengetik terminal lebar setiap waktu, jadi saya menggunakan tput colssebaliknya, misalnya: git difftool -x "sdiff -s -w $(tput cols)".
jaume
Bisakah itu menyoroti perubahan warna? Saat ini sepertinya kita harus menggunakan mata kita untuk melihat apa sebenarnya perubahannya
nonopolaritas
Gantikan sdiff dengan icdiff untuk mendapatkan tampilan warna yang bagus.
Greg
10
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'

maka cukup:

git diff
krzych
sumber
1
`berbaur. ' bekerja juga! Dan itu menunjukkan semua perubahan di jendela konsolidasi.
HRJ
@ HRJ yang bekerja dengan sempurna! Sangat sederhana dan praktis :)
waldyrious
9

Jika Anda ingin melihat perbedaan berdampingan di peramban tanpa melibatkan GitHub, Anda mungkin menikmati git webdiff , pengganti drop-in untuk git diff:

$ pip install webdiff
$ git webdiff

Ini menawarkan sejumlah keunggulan dibandingkan difftools GUI tradisional seperti tkdiffdalam hal ini dapat memberi Anda sorotan sintaks dan menampilkan diff gambar.

Baca lebih lanjut di sini .

danvk
sumber
7

Saya menggunakan colordiff .

Di Mac OS X, instal dengan

$ sudo port install colordiff

Di Linux mungkin apt get install colordiffatau sesuatu seperti itu, tergantung pada distro Anda.

Kemudian:

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

Atau buat alias

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

Maka Anda bisa menggunakannya

$ git diffy HEAD^ HEAD

Saya menyebutnya "diffy" karena diff -ymerupakan diff berdampingan dalam unix. Colordiff juga menambahkan warna, yang lebih bagus. Pada opsi -ydw, yis for the side-by-side, wis untuk mengabaikan spasi putih, dan dis untuk menghasilkan diff minimal (biasanya Anda mendapatkan hasil yang lebih baik sebagai diff)

Luigi R. Viggiano
sumber
tambahkan -yuntuk melewati Launch 'colordiff' [Y/n]:prompt.
Beni Cherniavsky-Paskin
yang Anda yakin itu adalah git alias diffy "difftool --extcmd=\"colordiff -ydw\""? Bukankah seharusnya begitu git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""?
nonopolaritas
6

Untuk unix, mengkombinasikan adil gitdan built-in diff:

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

Tentu saja, Anda dapat mengganti HEAD dengan referensi git lainnya, dan Anda mungkin ingin menambahkan sesuatu seperti -W 170perintah diff.

Ini mengasumsikan bahwa Anda hanya membandingkan konten direktori Anda dengan komit yang lalu. Membandingkan antara dua komitmen lebih kompleks. Jika shell bashAnda, Anda dapat menggunakan "proses substitusi":

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

di mana REF1dan REF2git referensi - tag, cabang atau hash.

Walker Hale IV
sumber
Terima kasih - perintah Anda 'git show HEAD: path / to / file' adalah apa yang saya butuhkan untuk menghasilkan solusi sendiri, 'vimdfiff <(git show HEAD: path / to / file) path / to / file'. Bit masih belum berbaris dengan benar, tapi itu solusi terbaik yang saya punya saat ini.
talexb
5

Saya pribadi sangat suka icdiff !

Jika Anda berada di Mac OS Xdengan HomeBrew, hanya melakukan brew install icdiff.

Untuk mendapatkan label file dengan benar, plus fitur keren lainnya, saya miliki di ~/.gitconfig:

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

Dan saya menggunakannya seperti: git difftool

Jose Alban
sumber
3

Pertanyaan ini muncul ketika saya sedang mencari cara cepat untuk menggunakan git builtin cara untuk menemukan perbedaan. Kriteria solusi saya:

  • Startup cepat, diperlukan opsi bawaan
  • Dapat menangani banyak format dengan mudah, xml, berbagai bahasa pemrograman
  • Cepat mengidentifikasi perubahan kode kecil di file teks besar

Saya menemukan jawaban ini untuk mendapatkan warna dalam git.

Untuk mendapatkan berdampingan diff bukan garis diff saya tweak mb14 's sangat baik jawaban atas pertanyaan ini dengan parameter berikut:

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

Jika Anda tidak menyukai ekstra [- atau {+ opsi --word-diff=colordapat digunakan.

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

Itu membantu untuk mendapatkan perbandingan yang tepat dengan teks json dan xml dan kode java.

Singkatnya, --word-diff-regexopsi memiliki visibilitas bermanfaat bersama dengan pengaturan warna untuk mendapatkan pengalaman kode sumber berdampingan berwarna dibandingkan dengan diff garis standar, ketika menelusuri file besar dengan perubahan garis kecil.

Mike
sumber
3

Beberapa yang lain telah menyebutkan cdiff untuk git berdampingan secara berdampingan tetapi tidak ada yang memberikan implementasi penuh darinya.

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

Edit ~ / .gitconfig menyisipkan baris ini:

[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

Pager off diperlukan agar cdiff dapat bekerja dengan Diff, ini pada dasarnya pager, jadi ini tidak masalah. Difftool akan berfungsi terlepas dari pengaturan ini.

Alias ​​acara diperlukan karena git show hanya mendukung alat diff eksternal melalui argumen.

Tanda '#' pada akhir perintah eksternal diff adalah penting. Perintah diff Git menambahkan $ @ (semua variabel diff yang tersedia) ke perintah diff, tetapi kami hanya menginginkan dua nama file. Jadi kami memanggil keduanya secara eksplisit dengan $ 2 dan $ 5, dan kemudian menyembunyikan $ @ di belakang komentar yang jika tidak akan membingungkan sdiff. Menghasilkan kesalahan yang terlihat seperti:

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

Perintah Git yang sekarang menghasilkan pembedaan berdampingan:

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

Penggunaan Cdiff:

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

Anda sekarang memiliki diff berdampingan melalui git diff dan difftool. Dan Anda memiliki kode sumber python cdiff untuk kustomisasi pengguna listrik jika Anda membutuhkannya.

Eric
sumber
2

Inilah pendekatannya. Jika Anda menyalurkan lebih sedikit, lebar xterm diatur ke 80, yang tidak terlalu panas. Tetapi jika Anda melanjutkan perintah dengan, misalnya COLS = 210, Anda dapat memanfaatkan xterm Anda yang diperluas.

gitdiff()
{
    local width=${COLS:-$(tput cols)}
    GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
Thomas Mellman
sumber
1
Lucu. Saya menandatangani dengan nama dengan nama samaran tetapi itu diabaikan ... Terima kasih karena telah menjebak saya, Stack Overflow. :(
Thomas Mellman
2

Buka Intellij IDEA , pilih satu atau beberapa komit di jendela alat "Kontrol Versi", telusuri file yang diubah, dan klik dua kali untuk memeriksa perubahan berdampingan untuk setiap file.

Dengan peluncur baris perintah yang dibundel, Anda dapat membawa IDEA ke mana saja dengan sederhana idea some/path

tampilan kontrol versi tampilan diff

Holger Brandl
sumber
1

Ada banyak jawaban bagus di utas ini. Solusi saya untuk masalah ini adalah menulis naskah.

Beri nama 'git-scriptname' ini (dan jadikan itu dapat dieksekusi dan letakkan di PATH Anda, seperti skrip apa pun), dan Anda dapat menjalankannya seperti perintah git normal dengan menjalankan

$ git scriptname

Fungsionalitas aktual hanyalah baris terakhir. Inilah sumbernya:

#!/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
Jon Carter
sumber
1

Ini mungkin solusi yang agak terbatas, tetapi apakah pekerjaan menggunakan perintah sistem difftanpa alat eksternal:

diff -y  <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
  • filter hanya menggunakan perubahan baris --suppress-common-lines(jika Anda diffmendukung opsi).
  • tidak ada warna dalam hal ini, hanya diffspidol biasa
  • dapat mengubah lebar kolom --width=term-width; di Bash bisa mendapatkan lebar sebagai $COLUMNSatau tput cols.

Ini juga dapat dibungkus dengan skrip pembantu helit untuk kenyamanan lebih, misalnya, penggunaan seperti ini:

git diffy the/file/path --from rev1 --to rev2
nomadbyte
sumber