Đánh dấu các dòng đã thay đổi và các byte đã thay đổi trong mỗi dòng đã thay đổi


90

Dự án nguồn mở Trac có một công cụ đánh dấu khác biệt tuyệt vời - nó đánh dấu các dòng đã thay đổi và các byte đã thay đổi trong mỗi dòng đã thay đổi! Xem tại đây hoặc đây để biết các ví dụ.

Có cách nào để sử dụng cùng màu tô sáng (tức là các dòng đã thay đổi và cả các byte cũng thay đổi ) trong bash terminal git, hoặc vim cho đầu ra khác biệt (patch-file) không?


Bạn muốn làm nổi bật điều gì? Bạn có muốn một công cụ khác biệt làm nổi bật các thay đổi byte không? (điều đó sẽ rất hữu ích). Bạn nói vim, theo hồi ức của tôi, vim đã thực hiện rất nhiều thao tác màu khi bạn đang sử dụng các mẫu ngôn ngữ lập trình (và các thứ khác). Bạn sẽ thay đổi điều đó như thế nào? Có khá nhiều kỹ thuật có sẵn để thay đổi màu trên cửa sổ đầu cuối được định nghĩa là VT100 (và có hàng chục định nghĩa khác cũng sẽ hỗ trợ trình tự thoát màu). Xin vui lòng thêm chi tiết cụ thể. Hoặc đọc en.wikipedia.org/wiki/VT100 và các liên kết liên quan. Có lẽ điều đó có thể giúp ích.
shellter

Tôi biết bạn chỉ quan tâm đến các công cụ mã nguồn mở và chỉ quan tâm đến thiết bị đầu cuối. Nhưng chỉ là một điểm tham khảo, bạn có thể muốn xem xét diffzilla của slickedit. trong số một vài công cụ khác biệt mà tôi đã sử dụng, nó dường như luôn thể hiện tốt nhất sự khác biệt về ký tự (mặc dù nó chắc chắn có vấn đề khi các khác biệt phức tạp (kết hợp giữa định dạng và thay đổi mã, luôn là một ý tưởng tồi)
nhed

Trông giống như một dup của stackoverflow.com/questions/3231759/...
Adam Monsen

Lưu ý: GitHub hiện cung cấp một công cụ khác như vậy trong GUI Web của nó: stackoverflow.com/a/25723584/6309
VonC

Tôi đã đăng 'một giải pháp dựa trên git khác, đánh dấu khác biệt' thuần túy với các hướng dẫn để dễ dàng 1) tìm tệp đánh dấu khác biệt có liên quan, 2) làm cho nó có thể thực thi được 3) thiết lập các thông số cần thiết trong .gitconfig. Mời các bạn xem qua. Hướng dẫn dành cho Ubuntu 18.04 nhưng sẽ hoạt động rộng rãi trên các hệ thống linux.
Zorglub29

Câu trả lời:


56

Tập diff-highlightlệnh Perl Contrib tạo ra đầu ra tương tự như trong các ảnh chụp màn hình của Trac đến mức có thể là Trac đang sử dụng nó:

nhập mô tả hình ảnh ở đây

Cài đặt bằng:

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

Di chuyển tệp diff-highlightvào ~/bin/thư mục (hoặc bất cứ nơi nào của bạn $PATH), sau đó thêm phần sau vào ~/.gitconfig:

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

Cài đặt dán một bản sao do @cirosantilli đề xuất:

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'

Điều này. Thật tuyệt vời. Cảm ơn bạn. Tuy nhiên, nó có vẻ hơi bảo thủ ở một số chỗ, thiếu một số dòng rõ ràng là có phần lớn văn bản chung. Bạn có một trình theo dõi lỗi cho nó không?
naught101

20
Ah, đây là một phần của core git bây giờ: github.com/git/git/tree/master/contrib/diff-highlight
naught101

2
Nó bây giờ được biến thành một mô-đun, và tôi nghĩ rằng phiên bản đơn giản nhất để tải về từ là một ngay trước rằng sự thay đổi ở raw.githubusercontent.com/git/git/...
Chris Midgley

4
Đây không chỉ là phần của core git, nó được phân phối với git và có thể đã có trên hệ thống của bạn. Tôi đã thêm chi tiết về cách kích hoạt nó trong câu trả lời của tôi bên dưới. ↓
Cory Klein

1
Điều này bỏ lỡ những khác biệt mà bạn thấy qua git add -p. Cũng vui lòng thêm:git config --global interactive.diffFilter diff-highlight
josch

40

Trong khi sử dụng git diffhoặc git logvà có thể là những người khác, hãy sử dụng tùy chọn --word-diff=color(cũng có các chế độ khác cho các từ khác BTW)


2
--word-diff=colorthực sự là tốt hơn (đặc biệt là với git config color.diff.old "red reverse"git config color.diff.new "green reverse"), nhưng nó không phải là những gì tôi muốn :(
Nikolay Frantsev

4
Vì vậy, điều duy nhất bạn đang thiếu là đánh dấu bằng màu sắc / bằng cách nào đó cả hai dòng và byte đã thay đổi cùng một lúc?
anydot

6
Tôi muốn đánh dấu các dòng đã thay đổi và các byte đã thay đổi trong mỗi dòng đã thay đổi, như trong Trac. Không chỉ thay đổi byte, nó không giống nhau.
Nikolay Frantsev

Bạn cũng có thể sử dụng điều này với git add --patch: stackoverflow.com/questions/10873882/...
naught101

Ưu điểm của diff-highlightnó là nó hoạt động tốt cho cả khác từ và khác dòng.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

20

diff-so-fancylà một diff-highlighter được thiết kế cho nhãn cầu của con người.

Nó loại bỏ phần đầu +/ -gây khó chịu cho việc cắt / dán và làm rõ ràng các phần giữa các tệp.

Màu git(trái) so với diff-so-fancy(phải - lưu ý các điểm nổi bật ở cấp độ nhân vật):

đầu ra rất khác biệt

Nếu bạn muốn đầu ra diff-so-fancy(phía bên phải) nhưng không bị giới hạn đối với các tệp trong gitkho lưu trữ, hãy thêm hàm sau vào của bạn .bashrcđể sử dụng nó trên bất kỳ tệp nào:

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

Ví dụ:

dsf original changed-file

Đánh dấu cấp độ ký tự và diffđịnh dạng tiêu chuẩn

Nếu bạn không thích định dạng không chuẩn diff-so-fancy, nhưng vẫn muốn gitđánh dấu cấp độ ký tự , hãy sử dụng định dạng diff-highlightnày sẽ lấy gitđầu ra và tạo diffra đầu ra định dạng chuẩn thực sự đẹp :

ảnh chụp màn hình diff-highlight

Để sử dụng nó theo mặc định từ git, hãy thêm vào .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

Phần [pager]này yêu cầu gitchuyển đầu ra đã được tô màu của nó sang diff-highlightmàu nào ở cấp độ ký tự, sau đó trang đầu ra ít hơn (nếu cần), thay vì chỉ sử dụng mặc định less.


Điều này rất thú vị, bạn có thể giải thích một chút về các gitconfigtùy chọn này ?
caesarsol

Cập nhật, cũng thêm chức năng dsf().
Tom Hale

14

Hành vi bạn muốn hiện có sẵn trong chính git (như đã được chỉ ra trong nhận xét của naught101). Để kích hoạt nó, bạn cần đặt máy nhắn tin của mình thành

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

đâu /usr/share/doc/git/contrib/diff-highlight/diff-highlightlà vị trí của tập lệnh đánh dấu trên Ubuntu 13.10 (Tôi không biết tại sao nó lại nằm trong một docthư mục). Nếu nó không có trên hệ thống của bạn, hãy thử sử dụng locate diff-highlightđể tìm nó. Lưu ý rằng tập lệnh tô sáng không thể thực thi (ít nhất là trên máy của tôi), do đó yêu cầu đối với perl.

Để luôn sử dụng công cụ đánh dấu cho các lệnh khác nhau, chỉ cần thêm phần sau vào ~/.gitconfigtệp của bạn :

[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

Tôi đã thêm điều này vì một câu trả lời mới nhận xét của naught101 bị chôn vùi và bởi vì việc thiết lập không hoàn toàn tầm thường như nó nên diễn ra và ít nhất là trên phiên bản Ubuntu mà tôi có hướng dẫn trong README không hoạt động.


Tôi vừa nhận thấy rằng điều này không cho phép làm nổi bật các điểm khác biệt trong git add -p(chế độ tương tác). Tuy nhiên, tôi không biết làm thế nào để khắc phục điều đó, chỉ cần thêm add vào danh sách là nó sẽ bị treo.
dshepherd vào

5
Điều này sẽ làm việc bây giờ trong git 2.9.0:git config interactive.diffFilter diff-highlight
Thomas

^ Cái này! Thật không may, diff-highlightnó không nằm trên con đường của tôi nên tôi phải xác định vị trí của nó trước. Chi tiết trong câu trả lời của tôi bên dưới.
Cory Klein

11

Một tiện ích cho các khác biệt dựa trên byte đã được phân phối với Git chính thức kể từ v1.7.8 1 . Bạn chỉ cần xác định vị trí nó được cài đặt trên máy của bạn và kích hoạt nó.

Tìm nơi Git được cài đặt

  • MacOS với Git được cài đặt qua Homebrew : Đó là/usr/local/opt/git
  • Windows với Git dành cho Windows : Chạy cd / && pwd -Wđể tìm thư mục cài đặt.
  • Linux: Nerd. Nếu bạn chưa biết nơi Git được cài đặt, sau đó ll $(which git)hoặc locate gitcần giúp đỡ.

Liên kết diff-highlightđến thư mục bin của bạn để PATH của bạn có thể tìm thấy nó

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'

Bật nó trong cấu hình Git của bạn

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 Đây là phiên bản v1.7.8 , nhưng rất nhiều thay đổi đã được thực hiện kể từ đó.


1
Sẽ rất tốt nếu chỉ định phiên bản mà nó bắt đầu được phân phối với git. Tôi cũng đoán rằng các bản phân phối sẽ đặt nó trong PATH theo mặc định, vì vậy bước liên kết biểu tượng sẽ không cần thiết? Và which gityêu cầu nó phải ở PATH ngay từ đầu nên nó sẽ không hoạt động nếu không :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
Nó sẽ là tốt! Hãy thêm thông tin đó. Và mặc dù Git có gói diff-highlightnhưng nó không thực sự cài đặt nó, vì vậy bước liên kết biểu tượng thực sự cần thiết (ít nhất là trên macOS). Nếu bạn thấy rằng nó không cần thiết cho nền tảng của mình, hãy cập nhật câu trả lời một lần nữa. Trong khi đó, which gitthường làm việc, bởi vì Git không cài đặt gitở đâu đó nhị phân trên con đường.
Cory Klein

Lưu ý rằng trong debian không ổn định, tôi cần "biên dịch" tệp này, bởi vì tôi vừa có một .perl. Việc biên dịch là không đáng kể: chỉ cần chạy sudo maketrong diff-highlightthư mục.
tobiasBora

10

Tôi sử dụng --color-wordstùy chọn và nó hoạt động tốt cho tôi:

$ git diff --color-words | less -RS

5
Không, điều này chỉ cho thấy sự khác biệt trong lời nói. Những gì OP (và tôi) muốn là sự khác biệt từng dòng bình thường, với sự khác biệt của từ được đánh dấu (vì vậy, giả sử các dòng khác nhau là văn bản màu và sự khác biệt từ trong các dòng đó là văn bản màu bình thường, với tô sáng màu hoặc gì đó). Xem các liên kết ví dụ bây giờ trong câu hỏi.
naught101

1
pastebin.com/1JrhYHRt Thực ra tôi sử dụng vimdiff làm difftool và vimdiff với molokai Colorscheme để có được điểm nhấn đẹp như bạn mô tả trong câu hỏi của mình. 1- git config --global diff.tool vimdiff 2- in vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Có thể tự động kiểm tra màu với ~ / .vimrc: if & diff set background = dark Colorscheme molokai endif
vui vẻ

4

như @dshepherd nói :

Hành vi bạn muốn hiện đã có trong chính git

Nhưng diff-highlightnằm trong DOC và không có sẵn từ shell.
Để cài đặt diff-highlightvào ~/binthư mục của bạn, hãy làm theo các bước tiếp theo (Thao tác này sẽ lưu lại quá trình nhập của bạn):

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

Sau đó, định cấu hình .gitconfigtài liệu chính thức của bạn như sau:

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

UPD
Ngoài ra, bạn có thể thử tiếp theo trên phiên bản mới nhất gitmà không cần cài đặt:

git diff --color-words=.

Phức tạp hơn:

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

1

Emacs có chức năng ediff-patch-buffer sẽ đáp ứng nhu cầu của bạn.

Mở tệp chưa được vá bằng emacs loại ESC-x, ediff-patch-buffer.

Làm theo lời nhắc và bạn sẽ thấy bản so sánh được đánh dấu của các phiên bản gốc và bản vá của tệp của bạn.

Theo nhận xét của bạn, phần sau sẽ cung cấp cho bạn một giải pháp bash chỉ cần 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

xin lỗi, tôi không muốn sử dụng emacs, chỉ bash, git hoặc vim
Nikolay Frantsev

Nó có thể hiểu được. Điều duy nhất khác tôi có thể nghĩ đến là sử dụng colordiff với stdout từ vá: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) nhưng điều này chỉ là đi để làm nổi bật thay đổi dòng không cắn ...
Finbar Crago

Tôi đã suy nghĩ kỹ hơn vấn đề của bạn và đã thêm một giải pháp thứ hai mà chỉ cần dwdiff.
Finbar Crago

1
xin vui lòng đọc kỹ câu hỏi của tôi, tôi không muốn so sánh các file
Nikolay Frantsev

1
xin lỗi vì sự nhầm lẫn, vì vậy bạn chỉ sau một cách để đánh dấu các byte đã thay đổi trên các dòng đã thay đổi của một tệp khác nhau? nếu vì vậy hãy thửdwdiff -c --diff-input diff_file
Finbar Crago

1

Diffy

GitLab đang sử dụng Diffy https://github.com/samg/diffy (Ruby) để đạt được đầu ra tương tự như GitHub và diff-highlight:

nhập mô tả hình ảnh ở đây

Diffy tự tạo ra sự khác biệt bằng cách sử dụng cùng một thuật toán quảng cáo Git và hỗ trợ các loại đầu ra khác nhau, bao gồm cả đầu ra HTML mà GitLab sử dụng:

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

Đầu ra:

<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>

Lưu ý cách strongđược thêm vào các byte đã thay đổi.


0

Có, Vim thực hiện điều này bao gồm việc đánh dấu văn bản được thay đổi trong một dòng.
Xem :h diff:h 08.7để biết thêm chi tiết về cách khác biệt các tệp.

Vim sử dụng một thuật toán khá đơn giản để làm nổi bật nó. Nó tìm kiếm trên dòng cho ký tự được thay đổi đầu tiên, sau đó là ký tự được thay đổi cuối cùng và chỉ cần đánh dấu tất cả các ký tự giữa chúng.
Điều này có nghĩa là bạn không thể có nhiều điểm nổi bật trên mỗi dòng - nhiều quyết định thiết kế trong Vim ưu tiên hiệu quả.


không may, nó không làm nổi bật thay đổi byte trên diff đầu ra (set filetype = diff)
Nikolay Frantsev

1
Tôi nghĩ tôi đã hiểu câu hỏi của bạn bây giờ - Bạn muốn đánh dấu cú pháp đánh dấu đầu ra văn bản của lệnh diff để nó làm nổi bật bất kỳ thay đổi nào được thực hiện bên trong một dòng. Chỉnh sửa văn bản này trong Vim làm nổi bật sự khác biệt của dòng, nhưng không làm nổi bật những thay đổi được thực hiện trong một dòng.
PDug

Bạn có thể sử dụng lệnh Vim's: patchfile để tải tệp gốc và sau đó so sánh nó với phiên bản đã vá không?
PDug

tiếc là không có, tôi muốn sử dụng sản lượng diff đệ quy cho nhiều file
Nikolay Frantsev

0

vimdiff file1 file2 sẽ hiển thị sự khác biệt về ký tự giữa hai tệp.

vimdiff là một công cụ khác biệt được bao gồm trong vim. (Vim nên được biên dịch với tùy chọn + diff, để đảm bảo bạn có thể kiểm tra :version)

Bạn cũng có thể khởi chạy nó từ bên trong vim. Xem :help diffđể biết thêm thông tin và lệnh.


Tôi không muốn so sánh các tệp, tôi muốn làm nổi bật tệp khác biệt (bản vá).
Nikolay Frantsev

@Nikolay Frantsev Nếu bạn không quan tâm đến hiệu suất, bạn có thể cài đặt plugin format.vim của tôi và thực hiện vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX

Nó sẽ thực hiện một sự khác biệt trong chế độ hàng loạt (thêm trước screen -D -mhoặc nối thêm &>/dev/null(biến thể / dev / null đôi khi tạo ra các lỗi lạ) nếu bạn không muốn thấy thiết bị đầu cuối nhấp nháy) và thoát vim sau khi định dạng xong, nhưng đó là vimscript thuần túy và ngay cả với tối ưu hóa của tôi, nó rất chậm đối với các tệp lớn.
ZyX

0

Lưu ý : đây là bản sao của những gì được tìm thấy ở đây: Làm thế nào để cải thiện tính năng nổi bật khác biệt của git? . Đăng câu trả lời của tôi ở đây, vì nó có thể hữu ích cho một số người trực tiếp tìm thấy chủ đề này :)

Như đã nói trong một số câu trả lời trước, điều này có thể thực hiện được chỉ với nội dung git. Tôi đăng bài này vì hướng dẫn có thể dễ thực hiện hơn một chút tùy thuộc vào hệ thống của bạn, nhưng điều này cũng tương tự với một số câu trả lời khác.

Một giải pháp hoàn toàn dựa vào git và contribs của nó. Điều này không yêu cầu tệp bổ sung ngoài những gì đi kèm với git . Tất cả các giải thích đều dành cho Ubuntu (được thử nghiệm trên 18.04LTS), sẽ hoạt động tương tự trên các hệ thống linux khác:

  • Tìm đoạn mã git đóng góp nổi bật khác biệt:
find -L /usr -name diff-highlight -type f

trên hệ thống của tôi, câu trả lời hợp lệ duy nhất là:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Làm cho tập lệnh perl tương ứng có thể thực thi được. Trong trường hợp của tôi, tôi cần làm:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Cập nhật của bạn ~/.gitconfigđể nhận được kết quả bạn muốn, bằng cách thêm (lưu ý đây là TABS, không phải 4 dấu cách):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Hãy tận hưởng kết quả (lưu ý: cái này chỉ dành cho phần tô màu + điểm nhấn khác biệt, tôi cũng có những thứ khác đang chơi ở đây để có lời nhắc :)).

diff-highligh

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.