Bagaimana cara mewarnai diff pada baris perintah?

504

Ketika saya memiliki diff, bagaimana saya bisa mewarnainya sehingga terlihat bagus? Saya menginginkannya untuk baris perintah, jadi tolong jangan ada solusi GUI.

daniel kullmann
sumber
6
Adakah sistem operasi / shell tertentu?
Rowland Shaw
4
Coba github.com/walles/riff . Sebagai bonus tambahan, itu menyoroti bagian mana dari garis yang berubah.
Johan Walles

Jawaban:

608

Halaman manual untuk diffmenyarankan tidak ada solusi untuk pewarnaan dari dalam dirinya sendiri. Silakan pertimbangkan untuk menggunakan colordiff. Ini adalah pembungkus diffyang menghasilkan output yang sama dengan diff, kecuali bahwa itu menambah output menggunakan highlight sintaks berwarna untuk meningkatkan keterbacaan:

diff old new | colordiff

atau hanya:

colordiff old new

Instalasi:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordiffatauport install colordiff
kaji
sumber
45
Baru saja menemukan itu sendiri :-). Ini dapat disalurkan menjadi lebih sedikit dengan menggunakan less -R, yang menampilkan urutan pelarian untuk warna dengan benar.
daniel kullmann
34
Hanya dapat menggunakan sintaks: colordiff file1 file2
Felipe Alvarez
3
Sayangnya, ini tidak bekerja untuk output berdampingan ( -yopsi untuk mengaktifkan)vimdiffSaran di bawah ini mungkin cara yang lebih baik
Hi-Angel
8
colordiffberfungsi dengan baik untuk svn diff | colordiff(yaitu dalam situasi di mana Anda hanya memiliki diff, bukan dua file yang sedang di-diff).
Cornstalks
8
Sebagai pembaruan terhadap komentar @ Hi-Angel: colordiff telah diperbarui dan sekarang menyertakan -ydukungan berdampingan ( ).
Bailey Parker
333

Gunakan Vim :

diff /path/to/a /path/to/b | vim -R -

Atau lebih baik lagi, VimDiff (atau vim -d, yang lebih pendek untuk mengetik) akan menunjukkan perbedaan antara dua, tiga atau empat file berdampingan.

Contoh:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Johnsyweb
sumber
7
@ Jichao: Saya lebih suka mempelajari perintah daripada hanya memanggilnya saja. Dengan begitu saya bisa menggunakannya di mana saja, bahkan ketika dotfile saya tidak tersedia.
Johnsyweb
1
@AquariusPower: ctrl-cdan ctrl-xmemiliki kegunaan lain di Vim. ctrl-qditangkap oleh banyak terminal. Lihat Menulis dan berhenti untuk menemukan cara yang paling sesuai dengan kebutuhan Anda.
Johnsyweb
1
Pertama, cangkang macam apa ini? zsh? Saya tidak mengenali =(...)konstruk. Kedua, ada diff -ur a bdalam pikiran saya.
x-yuri
1
Solusi ini lebih baik daripada jawaban yang diterima, karena tidak mengharuskan Anda memiliki hak administrator sistem dan menginstal alat tambahan apa pun
amanzoor
173

Sebenarnya sepertinya ada pilihan lain (yang baru saya perhatikan baru-baru ini, ketika mengalami masalah yang dijelaskan di atas):

git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

Jika Anda memiliki Git (yang mungkin sudah Anda gunakan), maka Anda dapat menggunakannya untuk perbandingan, bahkan jika file itu sendiri tidak di bawah kontrol versi. Jika tidak diaktifkan untuk Anda secara default, mengaktifkan dukungan warna di sini tampaknya jauh lebih mudah daripada beberapa solusi yang disebutkan sebelumnya.

Lars Baehren
sumber
19
Ini rapi, tapi sayangnya ini tidak berfungsi ketika inputnya berupa pipa. Misalnya membandingkan file biner via git diff <(xxd file1) <(xxd filed)tidak berfungsi.
Michael Anderson
8
Anehnya, setidaknya salah satu file harus 'di luar repositori saat ini', menurut git help diff. Jadi jika git diff Anda kosong, coba cdkeluar dari tempat Anda berada.
Permintaan Buruk
7
Untuk mengaktifkan warna untuk git diff:git config color.diff auto
JWhy
2
super sederhana dan cepat
EE33
31
Jika kedua file berada di dalam repositori saat ini, gunakan git diff --no-indexuntuk membandingkan dua file.
Olivier 'Ölbaum' Scherler
95

diff --color opsi ditambahkan ke GNU diffutils 3.4 (2016-08-08)

Ini adalah diffimplementasi default pada sebagian besar distro, yang akan segera mendapatkannya.

Ubuntu 18.04 memiliki diffutils3.6 dan karenanya memilikinya.

Pada 3.5 terlihat seperti ini:

masukkan deskripsi gambar di sini

Diuji:

diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

Rupanya ditambahkan di commit c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (Mar 2015).

Perbedaan tingkat kata

Seperti diff-highlight. Sepertinya tidak mungkin, permintaan fitur: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Utas terkait:

ydiff meskipun begitu, lihat di bawah.

ydiff perbedaan level kata berdampingan

https://github.com/ymattw/ydiff

Apakah ini Nirvana?

python3 -m pip install --user ydiff
diff -u a b | ydiff -s

Hasil:

masukkan deskripsi gambar di sini

Jika garis terlalu sempit (default 80 kolom), paskan layar dengan:

diff -u a b | ydiff -w 0 -s

Isi file uji:

Sebuah

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

b

1
2
3
4
5 the original line teh original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the origlnal line
16
17
18
19
20

ydiff Integrasi git

ydiff terintegrasi dengan Git tanpa konfigurasi apa pun yang diperlukan.

Dari dalam repositori git, alih-alih git diff, Anda bisa melakukannya:

ydiff -s

dan bukannya git log:

ydiff -ls

Lihat juga: Bagaimana saya bisa mendapatkan diff berdampingan ketika saya melakukan "git diff"?

Diuji pada Ubuntu 16.04, git 2.18.0, ydiff 1.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
Ini dokumentasinya.
Alexey
1
Di utas milis itu: There is no word-highlighting, yet- ada pembaruan? Inilah yang saya datangi untuk pertanyaan ini (saya ingin- grep --colorseperti keluaran diff).
i336_
@ i336_ sayangnya tidak ada pembaruan, jika saya mendapatkannya, saya akan memperbarui pertanyaan. Ping saya jika Anda menemukan sesuatu.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
By the way git diff --colorjuga bekerja. Berguna saat bekerja di ssh.
Nagev
Diff terlalu besar? usediff --color=always | less -R
inetphantom
69

Dan untuk saat-saat ketika sebuah yum install colordiffatau apt-get install colordiffbukan merupakan pilihan karena kendala gila di luar kendali langsung Anda, atau Anda hanya merasa gila , Anda dapat menciptakan kembali roda dengan sederet:

sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

Lemparkan itu dalam skrip shell dan pipa un diff output melaluinya.

Ini membuat marka biru dan menyoroti nama file baru / lama dan menambahkan / menghapus garis di latar belakang hijau dan merah, masing-masing. 1 Dan itu akan membuat spasi tambahan 2 perubahan lebih mudah terlihat daripada yang bisa dilakukan colordiff.


1 Secara kebetulan, alasan untuk menyorot nama file sama dengan baris yang dimodifikasi adalah bahwa untuk membedakan antara nama file dan baris yang dimodifikasi secara tepat membutuhkan penguraian format diff, yang bukan sesuatu untuk ditangani dengan regex. Menyoroti mereka sama berfungsi "cukup baik" secara visual dan membuat masalah sepele. Yang mengatakan, ada beberapa seluk-beluk yang menarik .

2 Tapi tidak mengeklik tab. Rupanya tab tidak mendapatkan latar belakang mereka, setidaknya di xterm saya. Itu membuat perubahan tab vs ruang sedikit menonjol.

retracile
sumber
5
@ Matt: Ini pendekatan kasar untuk Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(meskipun saya berharap ada cara yang lebih baik).
retracile
1
Hmm, itu agak berhasil ... memberi 3 tanda hubung antara masing-masing chunk latar belakang merah muda.
Matt Montag
Manual tidak terbaca, cara yang tidak dapat dipelihara tanpa opsi untuk dengan mudah mengubah warna misalnya.
1
Bung ini luar biasa! Jalan untuk pergi! Itu adalah sihir sed yang bagus.
fthinker
6
sed / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m / 'terlihat juga bagus
Yura
16

Anda dapat mengubah konfigurasi subversi untuk menggunakan colordiff

~ / .subversion / config.diff

 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

via: https://gist.github.com/westonruter/846524

Azd325
sumber
svn: Tidak dapat memulai proses 'colordiff': Sumberdaya untuk sementara tidak tersedia
niken
Apakah Anda menginstal colordiff?
Azd325
Yup, saya mencoba hardcoding jalan juga (berjalan di cygwin)
niken
idk coba mungkin ini superuser.com/questions/635995/…
Azd325
12

Berwarna, ouput tingkat kata diff

Inilah yang dapat Anda lakukan dengan skrip di bawah ini dan sorot berbeda :

Tangkapan layar berwarna yang berbeda

#!/bin/sh -eu

# Use diff-highlight to show word-level differences

diff -U3 --minimal "$@" |
  sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;34m@/;s/$/\x1b[0m/' |
  diff-highlight

( Terima kasih atas jawaban @ retracile untuk sedsorotan)

Tom Hale
sumber
Bagaimana cara menggunakan output ini di GVim?
Hemant Sharma
Untuk vim, gunakan plugin, mis . Diffchar .
Tom Hale
10

Saya menggunakan grc(Generic Colouriser), yang memungkinkan Anda untuk mewarnai keluaran dari sejumlah perintah termasuk diff.

Ini adalah skrip python yang dapat membungkus perintah apa pun. Jadi, alih-alih memohon diff file1 file2, Anda akan meminta grc diff file1 file2untuk melihat output berwarna. Saya telah alias diffuntuk grc diffuntuk membuatnya lebih mudah.

dogbane
sumber
Tidak bekerja di Windows dengan mingw / cygwin karena fork()panggilan, meskipun kemungkinan bekerja dengan WSL.
Gabriel Devillers
6

Berikut ini adalah solusi lain yang memanggil seduntuk memasukkan urutan ANSI escape sesuai untuk warna untuk menunjukkan +, -dan @garis-garis merah, hijau, dan cyan masing-masing.

diff -u old new | sed "s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"

Berbeda dengan solusi lain untuk pertanyaan ini, solusi ini tidak menguraikan urutan pelarian ANSI secara eksplisit. Sebagai gantinya, ia memanggil tput setafdan tput sgr0memerintahkan untuk menghasilkan urutan pelarian ANSI masing-masing untuk mengatur warna yang sesuai dan mengatur ulang atribut terminal.

Untuk melihat warna yang tersedia untuk setiap argumen tput setaf, gunakan perintah ini:

for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo

Berikut tampilan hasilnya:

masukkan deskripsi gambar di sini

Berikut adalah bukti bahwa perintah tput setafdan tput sgr0menghasilkan urutan pelarian ANSI yang sesuai:

$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m
Susam Pal
sumber
5

Karena wdiffaccepts args menentukan string di awal dan akhir dari kedua penyisipan dan penghapusan, Anda dapat menggunakan urutan warna ANSI sebagai string tersebut:

wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

Sebagai contoh, ini adalah hasil dari membandingkan dua file CSV:

keluaran berbeda dari file CSV

Contoh dari https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

jcomeau_ictx
sumber
1
colordiffsekarang (1.0.16) mengerti wdiff, sehingga Anda juga dapat hanya pipa: wdiff -n f1 f2 | colordiff. wdiffharus digabung menjadi diffutils ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3

Saya sarankan Anda untuk mencoba diff-so-fancy . Saya menggunakannya selama pekerjaan saya dan itu tampak hebat seperti sekarang. Itu datang dikemas dengan banyak pilihan dan sangat mudah untuk mengkonfigurasi diff Anda seperti yang Anda inginkan.

Anda dapat menginstalnya dengan:

sudo npm install -g diff-so-fancy

atau di Mac:

brew install diff-so-fancy

Setelah itu, Anda dapat menyorot diff Anda seperti ini:

diff -u file1 file2 | diff-so-fancy
Naveen
sumber
1

Dengan perintah kelelawar :

diff file1 file2 | bat -l diff
Jian Weihang
sumber
0

Pada git versi terbaru di Ubuntu, Anda dapat mengaktifkan diff-highlighting dengan:

sudo ln -s /usr/share/doc/git/contrib/diff-highlight/diff-highlight /usr/local/bin
sudo chmod a+x /usr/share/doc/git/contrib/diff-highlight/diff-highlight

Dan kemudian menambahkan ini ke Anda .gitconfig:

[pager]
    log = diff-highlight | less
    show = diff-highlight | less
    diff = diff-highlight | less

Mungkin saja skrip tersebut berada di tempat lain di distro lain, bisa Anda gunakan locate diff-highlightuntuk mencari tahu di mana.

tidak ada apa-apa101
sumber
0

Perbedaan warna tingkat karakter: Instal ccdiff

ccdiff -r /usr/share/dict/words /tmp/new-dict

Output ccdiff

aprikot
sumber