Tại sao bạn nên quan tâm đến git range-diff?
Hồi mới vào nghề, mình cực kỳ sợ rebase những nhánh (branch) có lịch sử dài. Giải quyết conflict xong, mình thường toát mồ hôi hột. Nỗi lo lớn nhất là lỡ tay xóa mất logic quan trọng của đồng nghiệp hoặc làm biến mất code của chính mình.
Thông thường, chúng ta hay dùng git diff để kiểm tra lại sau khi rebase. Tuy nhiên, lệnh này sẽ hiện ra một “rừng” thay đổi bao gồm cả những code mới nhất từ nhánh main. Bạn sẽ rất khó phân biệt đâu là code mình vừa sửa, đâu là code thừa hưởng từ nhánh gốc.
Tại team 8 người của mình, sau khi áp dụng quy trình kiểm tra bằng git range-diff trước khi force push, tỉ lệ lỗi logic do rebase ẩu đã giảm hơn 70%. Anh em trong team cũng tự tin hơn hẳn khi xử lý các tính năng phức tạp.
Hạn chế của cách làm cũ
Hãy tưởng tượng bạn đang làm một tính năng, trong khi đó nhánh main đã có thêm 10 commit mới. Bạn thực hiện git rebase main và phải xử lý xung đột. Lúc này, một câu hỏi lớn xuất hiện: “Liệu nội dung các commit của mình có còn giữ nguyên như trước khi rebase không?”
- git diff: Chỉ so sánh trạng thái cuối (snapshot). Kết quả bị nhiễu nặng bởi code mới từ main.
- git log: Cho thấy lịch sử nhưng không giúp bạn thấy chi tiết sự khác biệt giữa hai phiên bản của cùng một tập hợp commit.
Đây chính là lúc git range-diff phát huy tác dụng. Thay vì so sánh file, nó so sánh các bản vá (patches) của từng commit với nhau.
Kiểm tra phiên bản Git
Bạn không cần cài thêm công cụ bên thứ ba nào cả. Git đã tích hợp sẵn tính năng này từ phiên bản 2.19 (năm 2018). Hầu hết môi trường dev hiện nay đều đã vượt xa phiên bản này.
Hãy kiểm tra bằng lệnh:
git --version
Nếu phiên bản thấp hơn 2.19, bạn nên cập nhật ngay. Ngoài ra, hãy bật màu sắc hiển thị để dễ quan sát kết quả hơn:
git config --global color.ui true
Cách sử dụng trong thực tế
Nguyên lý của lệnh này là so sánh hai dải commit (commit ranges). Chúng ta sẽ so sánh nhánh feature cũ (trước rebase) và nhánh feature mới (sau rebase).
1. Luôn tạo điểm tựa trước khi Rebase
Mình luôn tạo một nhánh tạm hoặc tag để đánh dấu trạng thái cũ. Việc này chỉ mất 2 giây nhưng sẽ cứu bạn trong những tình huống ngặt nghèo.
# Đánh dấu trạng thái trước khi rebase
git branch feature-backup
# Thực hiện rebase
git rebase main
# So sánh bản cũ và bản mới
git range-diff main feature-backup feature
Lệnh trên yêu cầu Git: “Hãy so sánh những thay đổi từ main đến feature-backup với những thay đổi từ main đến feature“.
2. Đọc hiểu các ký hiệu
Khi màn hình hiện kết quả, hãy chú ý các ký hiệu ở đầu dòng. Chúng là chìa khóa để bạn biết mình có làm hỏng code hay không:
=: Commit hoàn toàn giống nhau. Đây là trạng thái lý tưởng.<: Commit chỉ xuất hiện ở dải cũ (có thể do bạn đã gộp commit).>: Commit chỉ xuất hiện ở dải mới.!: Commit bị thay đổi nội dung. Thường do bạn đã can thiệp khi sửa conflict.
Ví dụ, khi mình sửa file auth.service.ts và vô tình làm sai logic:
1: a1b2c3d = 1: e5f6g7h Thêm logic login
2: i9j0k1l ! 2: m3n4o5p Sửa lỗi validate email
@@ -10,5 +10,7 @@
- if (email === '')
+ if (!validateEmail(email))
++ console.log('Quên chưa xóa dòng này');
return false;
Dấu ! và dòng ++ cảnh báo rằng mình đã lỡ tay để lại một dòng console.log. Nếu không có range-diff, dòng code thừa này chắc chắn đã lọt lên môi trường production.
3. Mẹo xử lý khi quên backup
Nếu lỡ rebase mà chưa kịp tạo branch backup, bạn hãy dùng git reflog. Công cụ này lưu lại mọi bước chân của bạn trong Git. Bạn chỉ cần tìm mã hash của commit ngay trước khi lệnh rebase bắt đầu là xong.
git reflog
# Giả sử hash cũ tìm được là abc1234
git range-diff main abc1234 feature
Tối ưu quy trình làm việc
Để tận dụng tối đa sức mạnh của range-diff, bạn có thể áp dụng hai mẹo nhỏ sau:
Xem tóm tắt thay đổi: Nếu dải commit quá dài và bạn không muốn đọc từng dòng code, hãy thêm flag --summary. Git sẽ chỉ liệt kê danh sách các commit và trạng thái tương ứng của chúng.
Nâng cao chất lượng Review: Khi mình review PR cho các bạn Junior, mình thường yêu cầu các bạn giữ lại hash cũ nếu có rebase phức tạp. Nếu kết quả range-diff trả về toàn dấu =, mình có thể tự tin Approve ngay mà không cần đọc lại toàn bộ logic.
Một điểm cộng lớn là git range-diff cực kỳ thông minh. Thậm chí khi bạn thay đổi thứ tự commit bằng rebase -i, nó vẫn tự tìm được các cặp commit tương ứng để so sánh thay vì báo lỗi loạn xạ.
Lời kết: Hãy coi git range-diff như một chiếc kính hiển vi. Nó giúp bạn soi rõ từng thay đổi nhỏ nhất sau khi “xới tung” lịch sử bằng rebase. Đừng ngại rebase để giữ lịch sử Git sạch đẹp, chỉ cần bạn nhớ kiểm tra lại bằng lệnh này trước khi thực hiện push --force-with-lease.

