Cách so sánh hai văn bản hoặc tệp và đọc unified diff

Dán hai văn bản hoặc mở hai tệp để xem điều gì đã đổi, bỏ qua khoảng trắng hay chữ hoa, và học đọc unified diff từng dòng qua một ví dụ cụ thể.

Trong bài này

Để so sánh hai văn bản, hãy dán bản cũ vào bên trái và bản mới vào bên phải của một công cụ so sánh. Công cụ đánh dấu đỏ những dòng đã bị xóa, đánh dấu xanh những dòng được thêm, và tô đậm các từ thay đổi bên trong một dòng đã sửa. Sau đó bạn có thể sao chép kết quả dưới dạng unified diff, định dạng văn bản thuần mà Git, các công cụ duyệt mã và lệnh patch đều dùng. Bài này chỉ các bước, các tùy chọn giúp loại bớt nhiễu, và cách đọc từng ký hiệu của một unified diff.

Khi nào so sánh hơn đọc bằng mắt

Hai phiên bản của một điều khoản hợp đồng, bản dịch trước và sau khi người duyệt sửa, tệp cấu hình hôm qua còn chạy mà hôm nay thì không, hai bản xuất của cùng một danh sách, một đoạn mã bạn đã sửa mà không ghi lại. Đọc cả hai rồi cố tìm chỗ khác nhau vừa chậm vừa không đáng tin, vì mắt hay bỏ qua điều nó đã mong sẽ thấy. Công cụ so sánh tìm tập thay đổi nhỏ nhất biến văn bản này thành văn bản kia, và không bao giờ mệt.

So sánh trong trình duyệt

Mở công cụ so sánh văn bản. Cả hai văn bản ở lại trong trình duyệt của bạn, điều quan trọng khi chúng chứa tài liệu riêng tư hay thông tin đăng nhập.

  1. Dán bản gốc vào ô bên trái ("Văn bản gốc") và bản đã sửa vào ô bên phải ("Văn bản đã sửa"). Bạn cũng có thể thả một tệp văn bản vào ô, hoặc nhấn "Mở tệp". Nhấn "Thử một ví dụ" để xem nó trông thế nào.
  2. Đọc dòng tóm tắt, ví dụ "Thêm 2, xóa 2, giữ nguyên 15 dòng". Nếu hai văn bản giống hệt nhau, công cụ sẽ nói vậy.
  3. Chuyển giữa "Hai cột" và "Một cột". Dòng thêm màu xanh, dòng xóa màu đỏ, và trong một dòng đã sửa, các từ thay đổi được tô đậm hơn.
  4. Chọn "Bỏ qua khoảng trắng" nếu có người thụt lề lại cả tệp, hoặc "Bỏ qua chữ hoa và chữ thường" nếu bạn không quan tâm đến chữ in hoa.
  5. Nhấn "Sao chép unified diff", hoặc "Tải .diff", để giữ lại kết quả.

Những đoạn dài các dòng không đổi được gập vào một nút, nên bạn thấy từng thay đổi kèm ba dòng ngữ cảnh xung quanh. Nếu lỡ đặt văn bản mới vào bên trái, "Đổi hai bên" sẽ đảo lại màu sắc.

Đọc một unified diff

Đây là một tệp cài đặt nhỏ trước và sau khi sửa. Bản gốc:

name = shop
version = 1.4.2

[server]
host = 0.0.0.0
port = 8080
workers = 2

[database]
host = db.internal
port = 5432
pool = 10

[logging]
level = info
file = app.log
rotate = daily

Bản đã sửa có version = 1.5.0 ở dòng 2 và level = debug ở dòng 15. Unified diff là:

--- a/original
+++ b/changed
@@ -1,5 +1,5 @@
 name = shop
-version = 1.4.2
+version = 1.5.0
 
 [server]
 host = 0.0.0.0
@@ -12,6 +12,6 @@
 pool = 10
 
 [logging]
-level = info
+level = debug
 file = app.log
 rotate = daily

Mỗi phần đều có ý nghĩa:

  • Hai dòng đầu gọi tên hai phía. --- là bản gốc và +++ là bản đã sửa. Công cụ dùng a/original và b/changed vì nó so sánh văn bản dán vào, không phải các tệp có tên.
  • Dòng bắt đầu bằng `@@` mở một khối thay đổi, gọi là hunk. Trong @@ -1,5 +1,5 @@, phần sau dấu trừ nói "ở bản gốc, bắt đầu từ dòng 1 và lấy 5 dòng", còn phần sau dấu cộng nói như vậy cho bản đã sửa. Hunk thứ hai, @@ -12,6 +12,6 @@, bắt đầu từ dòng 12 và gồm 6 dòng ở mỗi phía.
  • Dòng bắt đầu bằng dấu trừ chỉ có ở bản gốc: nó đã bị xóa hoặc thay thế.
  • Dòng bắt đầu bằng dấu cộng chỉ có ở bản đã sửa.
  • Dòng bắt đầu bằng dấu cách là ngữ cảnh: giống nhau ở cả hai bản và có mặt để bạn biết mình đang ở đâu. Ba dòng ngữ cảnh bao quanh mỗi thay đổi.
  • Hai hunk xuất hiện vì hai chỗ sửa cách nhau hơn sáu dòng không đổi. Các chỗ sửa gần nhau hơn mức đó được gộp vào một hunk.
  • Một dòng bị sửa là một cặp: dòng trừ và dòng cộng ngay sau nó. Cùng nhau chúng nói "dòng này đã thành dòng kia".
  • `\ No newline at end of file` xuất hiện dưới một dòng cuối không có dấu xuống dòng phía sau, khi dòng đó dính vào một thay đổi.

Các con số cũng khớp nhau: hai số của một hunk cho biết đã thêm và xóa bao nhiêu dòng. Nếu ghi -3 +4 thì đã thêm một dòng.

Dùng diff sau đó

Unified diff là một công thức. Trên Mac hoặc Linux, patch app.ini < changes.diff áp nó vào bản sao của tệp gốc và cho ra văn bản đã sửa, đây là cách gửi cho người khác chỉ phần chỉnh sửa mà không cần cả tệp. Git hiểu cùng định dạng này qua git apply, nhưng nó mong đường dẫn trong hai dòng đầu khớp với tệp thật, nên hãy sửa hai dòng đó trước.

Các tùy chọn và những gì chúng che đi

  • Bỏ qua khoảng trắng. Khác biệt về dấu cách, tab và thụt lề bị bỏ qua. Dùng nó để chỉ thấy phần chữ đã thay đổi sau khi định dạng lại, nhưng nhớ rằng ở một số ngôn ngữ và định dạng, như Python hay YAML, thụt lề là một phần của ý nghĩa.
  • Bỏ qua chữ hoa và chữ thường. Hữu ích khi so sánh tên hoặc mã. Đừng dùng cho mật khẩu hay định danh phân biệt hoa thường.
  • Kiểu xuống dòng không bao giờ được tính. Tệp dùng xuống dòng của Windows và tệp dùng của Unix được coi là bằng nhau khi chữ giống nhau.

Vì sao hai văn bản trông giống nhau mà vẫn khác

  • Dấu nháy thẳng và dấu nháy cong. Trình soạn văn bản thay " bằng dấu nháy kiểu in và thay dấu gạch bằng dấu gạch dài hơn. Hãy so sánh văn bản thuần ở cả hai phía.
  • Dấu cách hay tab ở cuối dòng. Không nhìn thấy, nhưng phần tô sáng sẽ lộ ra.
  • Thứ tự khác nhau. Công cụ so sánh theo trình tự. Hai danh sách có cùng các mục nhưng khác thứ tự sẽ hiện thành nhiều thay đổi. Hãy sắp xếp cả hai trước nếu thứ tự không quan trọng.
  • JSON có khoá xếp khác thứ tự. Hãy định dạng cả hai bằng công cụ định dạng JSON và chọn "Sắp xếp khoá từ A đến Z" trước khi so sánh, để chỉ còn lại khác biệt thật.

Giới hạn

Mỗi bên nhận tối đa 5 triệu ký tự và tệp mở vào tối đa 5 MB, và tệp không giống văn bản sẽ bị từ chối: tệp Word và PDF phải được sao chép ra dạng chữ trước. Nếu hai văn bản khác nhau ở hàng nghìn chỗ, công cụ không thể khớp chúng từng dòng một cách chính xác; nó sẽ báo và hiển thị một phần là đã thay thế, nên hãy so sánh từng đoạn nhỏ hơn. Một kết quả rất dài chỉ vẽ 3.000 hàng đầu, còn unified diff được sao chép luôn chứa đầy đủ.

Nếu bạn chỉ cần biết hai tệp có giống hệt nhau không

Bạn không cần so sánh từng dòng. Hãy đối chiếu mã băm SHA-256 của chúng, cũng là cách kiểm tra tệp tải về, và chỉ dùng công cụ so sánh khi chúng khác nhau và bạn muốn biết vì sao.

Công cụ được nhắc trong bài

Về trang blog