Sorot garis yang diubah dan byte yang diubah di setiap baris yang diubah

94

Proyek Open Source Trac memiliki penyorot diff yang sangat baik - ini menyoroti baris yang diubah dan byte yang diubah di setiap baris yang diubah! Lihat di sini atau di sini untuk contoh.

Apakah ada cara untuk menggunakan sorotan warna yang sama (yaitu mengubah baris dan mengubah byte juga ) di terminal bash git,, atau vim untuk keluaran diff (file-patch)?

Nikolay Frantsev
sumber
Apa yang ingin Anda soroti? Apakah Anda menginginkan alat diff yang menyoroti perubahan byte? (Itu akan sangat membantu). Anda mengatakan vim, seingat saya vim sudah melakukan banyak manipulasi warna saat Anda menggunakan templat bahasa pemrograman (dan lainnya). Bagaimana Anda akan mengubahnya? Ada beberapa teknik yang tersedia untuk mengubah warna pada jendela terminal yang ditentukan VT100 (dan ada lusinan definisi lain yang juga akan mendukung urutan pelarian warna). Lebih spesifiknya silakan. Atau baca en.wikipedia.org/wiki/VT100 dan tautan terkait. Mungkin itu bisa membantu.
shellter
Saya tahu Anda hanya tertarik pada alat open source, dan hanya pada terminal. Tetapi hanya sebagai titik referensi Anda mungkin ingin melihat diffzilla slickedit. dari beberapa alat diff yang saya gunakan itu selalu tampak paling mewakili perbedaan karakter (meskipun jelas memiliki masalah ketika perbedaan di mana kompleks (kombinasi pemformatan dan perubahan kode, yang selalu merupakan ide yang buruk)
nhed
Sepertinya duplikat stackoverflow.com/questions/3231759/…
Adam Monsen
Catatan: GitHub sekarang menawarkan alat yang berbeda di GUI Web-nya: stackoverflow.com/a/25723584/6309
VonC
Saya telah memposting 'lagi' murni git, solusi berbasis diff-highlight dengan tutorial untuk dengan mudah 1) menemukan file diff-highlight yang relevan, 2) membuatnya dapat dieksekusi 3) mengatur params yang diperlukan dalam .gitconfig. Mohon dilihat. Instruksi untuk Ubuntu 18.04 tetapi harus bekerja secara luas pada sistem linux.
Zorglub29

Jawaban:

60

The diff-highlightPerl contrib Script menghasilkan output sehingga mirip dengan screenshot Trac bahwa itu adalah mungkin bahwa Trac yang menggunakannya:

masukkan deskripsi gambar di sini

Instal dengan:

wget https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight && chmod +x diff-highlight

Pindahkan file diff-highlightke ~/bin/direktori (atau di mana pun Anda $PATHberada), lalu tambahkan yang berikut ini ke ~/.gitconfig:

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

Pemasangan salin tempel tunggal yang disarankan oleh @cirosantilli:

cd ~/bin
curl -O https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight
chmod +x diff-highlight
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'
git config --global interactive.diffFilter diff-highlight
Sina Samavati
sumber
Ini. Ini luar biasa. Terima kasih. Ini tampaknya sedikit konservatif di beberapa tempat, kehilangan beberapa baris yang jelas memiliki mayoritas teks yang sama. Apakah Anda memiliki pelacak bug untuk itu?
n nothing101
21
Ah, ini adalah bagian dari core git sekarang: github.com/git/git/tree/master/contrib/diff-highlight
naught101
2
Sekarang telah berubah menjadi modul, dan menurut saya versi termudah untuk diunduh adalah versi sebelum perubahan itu di raw.githubusercontent.com/git/git/…
Chris Midgley
4
Tidak hanya ini bagian dari core git, ini didistribusikan dengan git dan mungkin sudah ada di sistem Anda. Saya menambahkan detail tentang cara mengaktifkannya dalam jawaban saya di bawah ini. ↓
Cory Klein
2
Ini merindukan perbedaan yang Anda lihat melalui git add -p. Harap juga tambahkan:git config --global interactive.diffFilter diff-highlight
josch
41

Saat menggunakan git diffatau git logdan mungkin yang lain, gunakan opsi --word-diff=color(ada juga mode lain untuk kata diffs BTW)

anydot
sumber
2
--word-diff=colorbenar-benar lebih baik (terutama dengan git config color.diff.old "red reverse"dan git config color.diff.new "green reverse"), tetapi bukan itu yang saya inginkan :(
Nikolay Frantsev
4
Jadi satu-satunya hal yang Anda lewatkan adalah menandai warna / entah bagaimana mengubah garis dan byte pada waktu yang sama?
anydot
7
Saya ingin menyoroti baris yang diubah dan byte yang diubah di setiap baris yang diubah, seperti di Trac. Tidak hanya mengubah byte, itu tidak sama.
Nikolay Frantsev
Anda juga dapat menggunakan ini dengan git add --patch: stackoverflow.com/questions/10873882/…
naught101
Keuntungan dari diff-highlightadalah bahwa ia bekerja dengan baik untuk kata diffs dan line diffs.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
21

diff-so-fancyadalah diff-highlighter yang dirancang untuk bola mata manusia.

Ini menghapus bagian depan +/ -yang mengganggu untuk potong / tempel dan membuat bagian yang jelas di antara file.

Berwarna git(kiri) vs diff-so-fancy(kanan - perhatikan sorotan level karakter):

keluaran yang sangat mewah

Jika Anda menginginkan diff-so-fancyoutput (sisi kanan) tetapi tidak dibatasi ke file dalam gitrepositori, tambahkan fungsi berikut ke Anda .bashrcuntuk menggunakannya pada file apa pun:

dsf() { git diff --no-index --color "$@" | diff-so-fancy; }

Misalnya:

dsf original changed-file

Penyorotan level karakter dan diffformat standar

Jika Anda tidak menyukai pemformatan non-standar diff-so-fancy, tetapi masih menginginkan gitpenyorotan tingkat karakter , gunakan diff-highlightyang akan mengambil gitkeluaran dan menghasilkan diffkeluaran format standar yang sangat cantik :

tangkapan layar diff-highlight

Untuk menggunakannya secara default dari git, tambahkan ke .gitconfig:

[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22

[pager]
  diff = diff-highlight | less -FRXsu --tabs=4

The [pager]Bagian memberitahu gitpipa outputnya sudah colourised untuk diff-highlightyang colourises di tingkat karakter, dan kemudian halaman output kurang (jika diperlukan), bukan hanya menggunakan default less.

Tom Hale
sumber
Ini sangat menarik, bisakah Anda menjelaskan sedikit tentang gitconfigopsi ini ?
caesarsol
Diperbarui, juga menambahkan fungsi dsf().
Tom Hale
15

Perilaku yang Anda inginkan sekarang tersedia di git itu sendiri (seperti yang ditunjukkan dalam komentar oleh naught101). Untuk mengaktifkannya Anda perlu mengatur pager Anda ke

perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

di mana /usr/share/doc/git/contrib/diff-highlight/diff-highlightlokasi skrip stabilo di Ubuntu 13.10 (Saya tidak tahu mengapa itu ada di docfolder). Jika tidak ada di sistem Anda, coba gunakan locate diff-highlightuntuk menemukannya. Perhatikan bahwa skrip penyorotan tidak dapat dieksekusi (setidaknya di mesin saya), oleh karena itu persyaratan untuk perl.

Untuk selalu menggunakan penyorot untuk berbagai perintah seperti diff, tambahkan saja yang berikut ini ke ~/.gitconfigfile Anda :

[pager]
    log = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    show = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    diff = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

Saya menambahkan ini sebagai jawaban baru komentar naught101 dikubur dan karena pengaturannya tidak sepele seperti yang seharusnya dan setidaknya pada versi Ubuntu yang saya memiliki instruksi di README tidak berfungsi.

dshepherd
sumber
Saya baru saja memperhatikan bahwa ini tidak mengaktifkan penyorotan untuk perbedaan dalam git add -p(mode interaktif). Saya tidak tahu bagaimana itu bisa diperbaiki, hanya menambahkan tambahkan ke daftar menyebabkannya hang.
dshepherd
5
Ini seharusnya berfungsi sekarang di git 2.9.0:git config interactive.diffFilter diff-highlight
Thomas
^ Ini! Sayangnya, diff-highlighttidak ada di jalur saya jadi saya harus menemukannya terlebih dahulu. Detail jawaban saya di bawah.
Cory Klein
11

Sebuah utilitas untuk diff berbasis byte telah didistribusikan dengan Git resmi sejak v1.7.8 1 . Anda hanya perlu mencari di mana itu diinstal pada mesin Anda dan mengaktifkannya.

Temukan di mana Git diinstal

  • MacOS dengan Git diinstal melalui Homebrew : Ini/usr/local/opt/git
  • Windows dengan Git untuk Windows : Jalankan cd / && pwd -Wuntuk menemukan direktori instal.
  • Linux: Nerd. Jika Anda belum tahu di mana Git diinstal, maka ll $(which git)atau locate githarus membantu.

Tautkan diff-highlightke direktori bin Anda sehingga PATH Anda dapat menemukannya

GIT_HOME='/usr/local/opt/git/'  # Use the value from the first step.
ln -s "${GIT_HOME}/share/git-core/contrib/diff-highlight/diff-highlight" \
      '/usr/local/bin/diff-highlight'

Aktifkan di konfigurasi Git Anda

git config --global interactive.diffFilter diff-highlight # Use on interactive prompts
git config --global pager.diff "diff-highlight | less"    # Use on git diff
git config --global pager.log  "diff-highlight | less"    # Use on git log
git config --global pager.show "diff-highlight | less"    # Use on git show

1 Ini adalah versi v1.7.8 , tetapi banyak perubahan telah dilakukan sejak saat itu.

Cory Klein
sumber
1
Sebaiknya tentukan di versi mana ia mulai didistribusikan dengan git. Saya juga menebak bahwa distro akan meletakkannya di PATH secara default, jadi langkah symlink tidak diperlukan? Dan which gitmengharuskannya untuk berada di PATH di tempat pertama sehingga tidak akan berfungsi jika tidak :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Itu akan bagus! Jangan ragu untuk menambahkan informasi itu. Dan meskipun Git memaketkan diff-highlight, ia tidak benar-benar menginstalnya , jadi langkah symlink memang diperlukan (setidaknya di macOS). Jika Anda merasa itu tidak perlu untuk platform Anda, sekali lagi jangan ragu untuk memperbarui jawabannya. Sementara itu, which gitbiasanya tidak bekerja, karena Git tidak menginstal gitsuatu tempat biner di jalan.
Cory Klein
Perhatikan bahwa di debian tidak stabil saya perlu "mengkompilasi" file ini, karena saya baru saja memiliki .perl. Kompilasinya sepele: jalankan saja sudo makedi diff-highlightdirektori.
tobiasBora
10

Saya menggunakan --color-wordsopsi dan berfungsi dengan baik untuk saya:

$ git diff --color-words | less -RS
diubah
sumber
5
Tidak, ini hanya menunjukkan perbedaan kata. Yang diinginkan OP (dan saya) adalah perbedaan baris demi baris normal, dengan perbedaan kata yang disorot (jadi, katakanlah baris yang berbeda adalah teks berwarna, dan perbedaan kata di dalam baris tersebut adalah teks berwarna normal, dengan sorotan berwarna atau sesuatu). Lihat tautan contoh sekarang di pertanyaan.
n nothing101
1
pastebin.com/1JrhYHRt Sebenarnya saya menggunakan vimdiff sebagai difftool dan vimdiff dengan molokai colourscheme untuk mendapatkan sorotan yang bagus seperti yang Anda gambarkan dalam pertanyaan Anda. 1- git config --global diff.tool vimdiff 2- in vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Kemungkinan skema warna otomatis dengan ~ / .vimrc: if & diff setel latar belakang = dark colourscheme molokai endif
diubah
4

seperti yang dikatakan @dshepherd :

Perilaku yang Anda inginkan sekarang tersedia di git itu sendiri

Tetapi diff-highlightterletak di DOC dan tidak tersedia dari shell.
Untuk menginstal diff-highlightke ~/bindirektori Anda , ikuti langkah selanjutnya (Ini akan menghemat pengetikan Anda):

$ locate diff-highlight
$ cd /usr/share/doc/git/contrib/diff-highlight  #or path you locate
$ sudo make
$ mv diff-highlight ~/bin

Kemudian konfigurasikan Anda .gitconfigsebagai dokumen resmi yang mengatakan:

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

UPD
Anda juga dapat mencoba berikutnya yang terbaru gittanpa instalasi apa pun:

git diff --color-words=.

Lebih kompleks:

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Eugen Konkov
sumber
1

Emacs memiliki fungsi ediff-patch-buffer yang akan memenuhi kebutuhan Anda.

Buka file yang belum di-patch di emacs ketik ESC-x, ediff-patch-buffer.

Ikuti petunjuknya dan Anda akan melihat perbandingan yang disorot dari versi patch dan asli file Anda.

Sesuai komentar Anda, berikut ini akan memberi Anda solusi bash yang hanya membutuhkan dwdiff:

#!/bin/bash
paste -d'\n' <(dwdiff -2 -L -c <(cat $2) <(patch $2 -i $1 -o -)) <(dwdiff -1 -L -c <(cat $2) <(patch $2 -i $1 -o -))| uniq
Finbar Crago
sumber
maaf, saya tidak ingin menggunakan emacs, hanya bash, git atau vim
Nikolay Frantsev
Itu bisa dimengerti. Satu-satunya hal lain yang dapat saya pikirkan adalah menggunakan colordiff dengan stdout dari tambalan: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) tetapi ini hanya akan menyoroti baris yang diubah, bukan gigitan ...
Finbar Crago
Saya memberikan masalah Anda sedikit lebih banyak pemikiran dan telah menambahkan solusi kedua yang hanya membutuhkan dwdiff.
Finbar Crago
1
harap baca dengan seksama pertanyaan saya, saya tidak ingin membandingkan file
Nikolay Frantsev
1
maaf atas kebingungannya, jadi Anda baru saja mencari cara untuk menyorot byte yang diubah pada baris yang diubah dari file diff? jika demikian cobadwdiff -c --diff-input diff_file
Finbar Crago
1

Diffy

GitLab menggunakan Diffy https://github.com/samg/diffy (Ruby) untuk mencapai keluaran yang mirip dengan GitHub dan diff-highlight:

masukkan deskripsi gambar di sini

Diffy membuat perbedaan itu sendiri menggunakan algoritme yang sama dengan iklan Git, dan mendukung berbagai jenis keluaran, termasuk keluaran HTML yang digunakan GitLab:

gem install diffy
echo '
  require "diffy"    
  puts Diffy::Diff.new("a b c\n", "a B c\n").to_s(:html)
' | ruby

Keluaran:

<div class="diff">
  <ul>
    <li class="del"><del>a <strong>b</strong> c</del></li>
    <li class="ins"><ins>a <strong>B</strong> c</ins></li>
  </ul>
</div>

Perhatikan bagaimana strongditambahkan ke byte yang diubah.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
0

Ya, Vim melakukan ini termasuk penyorotan teks yang diubah dalam satu baris.
Lihat :h diffdan:h 08.7 untuk rincian lebih lanjut tentang bagaimana cara menyebarkan file.

Vim menggunakan algoritma yang cukup sederhana untuk penyorotannya. Ini mencari baris untuk karakter pertama yang diubah, dan kemudian karakter yang terakhir diubah, dan hanya menyoroti semua karakter di antara mereka.
Ini berarti Anda tidak dapat memiliki beberapa sorotan per baris - banyak keputusan desain di Vim memprioritaskan efisiensi.

PDug
sumber
sayangnya, itu tidak menyoroti byte yang diubah pada keluaran diff (set filetype = diff)
Nikolay Frantsev
1
Saya rasa saya memahami pertanyaan Anda sekarang - Anda ingin menyorot sintaks keluaran tekstual dari perintah diff sehingga menyoroti perubahan apa pun yang dibuat di dalam baris. Mengedit teks ini di Vim menyoroti perbedaan baris, tetapi bukan perubahan yang dibuat dalam satu baris.
PDug
Bisakah Anda menggunakan perintah Vim's: patchfile untuk memuat file asli dan kemudian membandingkannya dengan versi yang ditambal?
PDug
sayangnya tidak, saya ingin menggunakan keluaran diff rekursif untuk banyak file
Nikolay Frantsev
0

vimdiff file1 file2 akan menampilkan perbedaan karakter antara dua file.

vimdiff adalah alat diff yang disertakan dalam vim. (Vim seharusnya telah dikompilasi dengan opsi + diff, untuk memastikan Anda dapat memeriksanya :version)

Anda juga dapat meluncurkannya dari dalam vim. Lihat:help diff untuk informasi dan perintah lebih lanjut.

Xavier T.
sumber
Saya tidak ingin membandingkan file, saya ingin menyorot file diff (patch).
Nikolay Frantsev
@Nikolay Frantsev Jika Anda tidak peduli dengan kinerja, Anda dapat menginstal plugin format.vim dan melakukannya vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX
Ini akan melakukan diff dalam mode batch (prepend screen -D -matau append &>/dev/null(varian / dev / null terkadang menghasilkan bug aneh) jika Anda tidak ingin melihat terminal berkedip) dan keluar dari vim setelah pemformatan selesai, tetapi ini murni vimscript dan bahkan dengan pengoptimalan saya itu sangat lambat untuk file besar.
ZyX
0

Catatan : ini adalah duplikat dari apa yang ditemukan di sini: Bagaimana cara meningkatkan penyorotan diff git? . Memposting jawaban saya di sini juga, karena mungkin bermanfaat bagi beberapa orang yang menemukan langsung utas ini :)

Seperti yang dikatakan dalam beberapa jawaban sebelumnya, ini hanya mungkin dengan hal-hal git. Saya memposting ini karena instruksinya mungkin sedikit lebih mudah diikuti tergantung pada sistem Anda, tetapi ini mirip dengan beberapa jawaban lainnya.

Satu solusi yang hanya mengandalkan git dan kontribusinya. Ini tidak memerlukan file tambahan selain yang disertakan dengan git . Semua penjelasan untuk Ubuntu (diuji pada 18.04LTS), seharusnya bekerja dengan cara yang sama pada sistem linux lain:

  • Temukan potongan contrib git diff-highlight:
find -L /usr -name diff-highlight -type f

di sistem saya, satu-satunya jawaban yang valid adalah:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Buat skrip perl yang sesuai dapat dieksekusi. Dalam kasus saya, saya perlu melakukan:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Perbarui Anda ~/.gitconfiguntuk mendapatkan hasil yang Anda inginkan, dengan menambahkan (perhatikan ini TABS, bukan 4 spasi):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Nikmati hasilnya (catatan: ini hanya untuk pewarnaan diff + highlight, saya memiliki hal-hal lain yang berperan di sini juga untuk prompt tentunya :)).

diff-highligh

Zorglub29
sumber