Làm cách nào để tôi có thể hình dung sự khác biệt theo từng ký tự trong một tệp khác biệt thống nhất?


122

Giả sử tôi nhận được một bản vá được tạo bằng git format-patch. Về cơ bản, tệp là một khác biệt thống nhất với một số siêu dữ liệu. Nếu tôi mở tệp trong Vim, tôi có thể thấy dòng nào đã được sửa đổi, nhưng tôi không thể thấy ký tự nào trong các dòng đã thay đổi khác nhau. Có ai biết cách (trong Vim, hoặc một số phần mềm miễn phí khác chạy trên Ubuntu) để hình dung sự khác biệt của mỗi ký tự không?

Ví dụ về bộ đếm trong đó sự khác biệt của mỗi ký tự được hiển thị khi thực thi vimdiff a b.

cập nhật Thứ Sáu ngày 12 tháng 11 22:36:23 UTC 2010

diffpatch rất hữu ích cho trường hợp bạn đang làm việc với một tệp duy nhất.

cập nhật Thứ Sáu ngày 16 tháng 6 17:56:10 UTC 2016

Kiểm tra điểm nổi bật khác trong git 2.9 . Tập lệnh này thực hiện chính xác những gì tôi đang tìm kiếm ban đầu.


Điều này có thể được tốt hơn về superuser.com
Daenyth

13
Có lẽ. Tôi chọn stackoverflow.com từ FAQ đề cập này là nơi dành cho các câu hỏi về "công cụ phần mềm thường được sử dụng bởi các lập trình viên"
Adam Monsen

7
Tôi không chắc rằng điều này trực tiếp trả lời câu hỏi của bạn, nhưng git diff --color-wordsrất hữu ích để xem những từ nào có sự thay đổi trong các dòng, thay vì đầu ra khác biệt thống nhất thông thường. Tuy nhiên, nó dựa trên từ thay vì dựa trên ký tự, vì vậy nếu không có nhiều khoảng trắng trong nội dung mà bạn đang khác biệt thì đầu ra có thể kém gọn gàng hơn. (Được sửa đổi: Rất tiếc, tôi thấy rằng tôi hiểu sai những gì bạn đang xin - vẫn có thể nhận xét này sẽ có ích cho một ai đó.)
Đánh dấu Longair

Câu trả lời:


13

Với các tham chiếu của bạn đến Vim trong câu hỏi, tôi không chắc đây có phải là câu trả lời bạn muốn hay không :) nhưng Emacs có thể làm được điều này. Mở tệp có chứa khác biệt, đảm bảo rằng bạn đang ở trong đó diff-mode(nếu tệp được đặt tên foo.diffhoặc foo.patchđiều này xảy ra tự động; nếu không M-x diff-mode RET, hãy nhập ), chuyển đến tệp bạn quan tâm và nhấn C-c C-btìm refine-hunk. Hoặc lướt qua từng tệp một với M-n; điều đó sẽ tự động tinh chỉnh.


1
Làm việc cho tôi! Heh, tôi đã sử dụng Vim được 10 năm, nhưng tôi mới cài đặt emacs. :)
Adam Monsen

Nhưng emacs không hỗ trợ đọc từ stdin, tôi không thể làm ví dụgit log master.. -p | emacs -
Hi-Thiên thần

1
@ Hi-Angel Bạn có thể mở Emacs và gõ M-!để chạy lệnh và ghi lại đầu ra trong bộ đệm.
legoscia 19/10/18

172

Trong git, bạn có thể hợp nhất mà không cần cam kết. Hợp nhất bản vá của bạn trước, sau đó thực hiện:

git diff --word-diff-regex=.

Lưu ý dấu chấm sau dấu bằng.


139
Tốt hơn: git diff --color-words=..
ntc2

4
@ ntc2 Bạn nên đưa nhận xét của mình thành câu trả lời.
Tyler Collier

1
Những người ủng hộ xin lưu ý, trường hợp sử dụng ban đầu của tôi giả định rằng bạn chỉ có một tệp bản vá , không có git repo hoặc thậm chí các phiên bản cơ sở / đã sửa đổi. Đó là lý do tại sao tôi chấp nhận câu trả lời của @ legoscia ... nó mô tả chính xác những gì được yêu cầu.
Adam Monsen

2
@ ntc2 git diff --color-words=.git diff --color-words .hoạt động khác. Tốt hơn là git diff --color-words ..
abhisekp

2
@abhisekp: cảm ơn vì bức ảnh. Tôi nghĩ rằng tôi đã tìm ra nó: git diff --color-words .thực sự giống như git diff --color-words -- .! Tức là, .được hiểu là một con đường. Bạn có thể xác minh với mkdir x y; echo foo > x/test; git add x/test; git commit -m test; echo boo > x/test; cd y; git diff --color-words=.; git diff --color-words .; git diff --color-words -- ..
ntc2

145

Dưới đây là một số phiên bản có đầu ra ít ồn hơn git diff --word-diff-regex=<re>và yêu cầu nhập ít hơn, nhưng tương đương với git diff --color-words --word-diff-regex=<re>,.

Đơn giản (không gian tô sáng có thay đổi không):

git diff --color-words

Đơn giản (làm nổi bật các thay đổi ký tự riêng lẻ; không làm nổi bật các thay đổi không gian):

git diff --color-words=.

Phức tạp hơn (không gian tô sáng có thay đổi không):

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

Nói chung:

git diff --color-words=<re>

đâu <re>là regexp xác định "từ" cho mục đích xác định các thay đổi.

Chúng ít ồn ào hơn ở chỗ chúng tô màu cho các "từ" đã thay đổi, trong khi chỉ sử dụng --word-diff-regex=<re>bao quanh các "từ" phù hợp với -/+các điểm đánh dấu màu .


9
Bản thân tôi thích --color-words, không có =.phần.
Tyler Collier

1
git diff --color-words='\w'sẽ hoạt động tốt hơn với dấu phụ (git v1.7.10.4)
nr

1
Phiên bản phức tạp hơn của bạn hoạt động tốt. Tôi đã thêm vào --word-diff=plainđể có thêm [--]xóa xung quanh và {++}bổ sung xung quanh. Như hướng dẫn cảnh báo, tuy nhiên, lần xuất hiện thực tế của những delimiters trong nguồn được không trốn dưới mọi hình thức
Tobias KIENZLER

2
Phiên bản phức tạp hơn của bạn không may dường như không làm nổi bật ví dụ như thay đổi thụt đầu dòng, tôi đã mở một câu hỏi về vấn đề này
Tobias KIENZLER

Câu trả lời này là tuyệt vời! Tuy nhiên, có cách nào để thực sự thay đổi nền của những thay đổi đó thành màu xanh lá cây / đỏ không?
WoLfPwNeR

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

Regex ở trên ( của Thomas Rast ) thực hiện một công việc tốt trong việc tách các đoạn khác nhau ở cấp độ dấu câu / ký tự (trong khi không ồn ào như --word-diff-regex=.).

Tôi đã đăng ảnh chụp màn hình của kết quả đầu ra ở đây .


Cập nhật:

Bài viết này có một số gợi ý tuyệt vời. Cụ thể, contrib/cây của git repo có diff-highlighttập lệnh perl hiển thị các điểm nổi bật chi tiết.

Bắt đầu nhanh để sử dụng nó:

$ curl https://git.kernel.org/cgit/git/git.git/plain/contrib/diff-highlight/diff-highlight > diff-highlight
$ chmod u+x diff-highlight
$ git diff --color=always HEAD~10 | diff-highlight | less -R

5
Bạn có thể rút ngắn nó thành--color-words=[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Đã chỉnh sửa 13/12/12

tôi đã phải thêm 'vào đầu giá trị ở đó. nếu không thì tôi gặp lỗi. Ngoài ra, tôi chỉ đơn giản sử dụng, --color-wordstôi nhận được hành vi giống hệt như sử dụng regexp đó.
gcb

3
@gcb Nội dung văn bản quan trọng. Nếu các thay đổi của bạn được phân tách bằng khoảng trắng thì không có sự khác biệt. Nhưng nếu bạn thay đổi nếu bạn thay đổi một cái gì đó như foo.barđể foo.quxbạn sẽ thấy sự khác biệt.
Justin M. Keyes

5
Đơn giản hơn: git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'.
ntc2

1
Tôi đã cài đặt git với Homebrew và đã có tập lệnh đó tại /usr/local/share/git-core/contrib/diff-highlight/diff-highlight. Điều này dường như cho thấy rằng git của Homebrew đã cài đặt toàn bộ phần đóng góp vào /usr/local/share/git-core/contrib/. Vì vậy, cuối cùng, sau đây làm việc cho tôigit diff --color=always | /usr/local/share/git-core/contrib/diff-highlight/diff-highlight
Ashutosh Jindal

6

Nếu bạn không có gì để cài đặt NodeJS, có một gói có tên "diff-so-ưa thích" ( https://github.com/so-fancy/diff-so-fancy ), rất dễ cài đặt và hoạt động hoàn hảo:

npm install -g diff-so-fancy
git diff --color | diff-so-fancy | less -R

Chỉnh sửa: Chỉ cần phát hiện ra rằng nó thực sự là một trình bao bọc cho điểm nổi bật khác biệt chính thức ... Ít nhất thì nó cũng dễ cài đặt hơn cho perlophobes như tôi và trang GitHub được ghi lại rất độc đáo :)


2

Tôi không biết về công cụ khác biệt cho mỗi ký tự, nhưng có một công cụ khác biệt cho mỗi từ: wdiff.

tham khảo ví dụ Top 4 Công cụ Khác biệt Tệp trên UNIX / Linux - Diff, Colordiff, Wdiff, Vimdiff .


wdiff là thú vị, cảm ơn! Để làm rõ câu hỏi ban đầu của tôi, tôi đang tìm thứ gì đó cung cấp tính năng đánh dấu cú pháp nâng cao cho một tệp duy nhất có định dạng khác biệt thống nhất.
Adam Monsen

Hơi sai lệch (về khác biệt từng từ, không tăng cường đầu ra khác biệt đã có trước), nhưng tôi đã tìm thấy các kết hợp sau đây tốt nhất cho hình ảnh hóa từng từ: * wdiff old_file new_file | cdiff * vimdiff , sau đó bên trong vim :windo wincmd Kđể chuyển sang bố cục cửa sổ dọc (một bên dưới cái kia) từ cạnh nhau một. Bố cục đó tốt hơn nhiều cho các tệp có dòng dài.
Aleksander Adamowski

2
BTW, Một số công cụ khác đáng để thử qua, không được đề cập trong bài viết liên quan: wdiff2, mdiff, và các công cụ trực tuyến của Google .
Aleksander Adamowski

1

Sau khi nghiên cứu một chút, tôi nhận thấy câu hỏi này đã xuất hiện hai lần gần đây trên danh sách gửi thư chính của Vim. Các Plugin NrrwRgn được nhắc đến cả hai lần (làm hai khu vực hẹp và diff họ). Sử dụng NrrwRgn như Christian Brabandt mô tả giống như một giải pháp thay thế hơn là một giải pháp, nhưng có lẽ như vậy là đủ tốt.

Tôi đã dùng thử NrrwRgn và nó, cùng với: diffthis, thực sự hữu ích để minh họa sự khác biệt theo từng ký tự trong các phần của một tệp. Nhưng phải mất nhiều lần gõ phím. Vimscript của tôi khá cũ, nhưng nó có thể là tập lệnh. Có thể NrrwRgn có thể được cải tiến để cung cấp các chức năng mong muốn.

Suy nghĩ?

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.