Script chạy git diff, không thấy lỗi trên màn hình nhưng vẫn đưa ra quyết định sai. Có thể script đang đọc sai exit code hoặc so sánh sai hai trạng thái. Trong automation, “không có khác biệt”, “có khác biệt” và “lệnh không chạy được” cần được xử lý riêng.
Bài viết dùng repository thông thường để kiểm tra file đã được Git theo dõi. Các lệnh kiểm tra không sửa working tree; không có bước tự commit hay push.
1. Chọn đúng hai trạng thái cần so sánh
| Lệnh | Phạm vi |
|---|---|
| git diff | Working tree so với index: thay đổi chưa stage của file đã theo dõi. |
| git diff --cached | Index so với HEAD: thay đổi đã stage cho commit tiếp theo. |
| git diff HEAD | Working tree so với commit HEAD, gồm thay đổi đã stage và chưa stage theo trạng thái cuối. |
Index và working tree có thể cùng chứa thay đổi nhưng kết quả cuối lại trùng HEAD. Do đó git diff HEAD không chứng minh riêng rằng cả index và working tree đều sạch. Nếu workflow cần kiểm tra từng tầng, hãy kiểm tra từng tầng.
2. Bật chế độ trả mã theo khác biệt
git diff --exit-code --no-ext-diff --no-textconv --
git diff --quiet --no-ext-diff --no-textconv --
Với --exit-code, mã 0 nghĩa là không có khác biệt trong phạm vi đang so; mã 1 nghĩa là có khác biệt. --quiet bỏ phần output diff và bao hàm chế độ exit code. Những mã khác cần được coi là lỗi thực thi để điều tra, không gộp vào “có thay đổi”.
Các ví dụ tắt external diff và text conversion để tránh phụ thuộc bộ trợ giúp hiển thị của máy. Chỉ dấu -- kết thúc phần tùy chọn; nếu muốn giới hạn đường dẫn, đặt đường dẫn sau nó.
3. Đọc mã trả về ngay trong PowerShell
git diff --quiet --no-ext-diff --no-textconv --
$diffCode = $LASTEXITCODE
switch ($diffCode) {
0 { 'No unstaged tracked changes' }
1 { 'Unstaged tracked changes found' }
default { throw "git diff failed with exit code $diffCode" }
}
Chạy trong PowerShell với Git đã cài và script được phép nhận mã native khác 0 để tự phân nhánh. Lưu $LASTEXITCODE ngay sau git diff, trước khi gọi một chương trình native khác có thể ghi đè giá trị.
Đừng chỉ dùng output rỗng để kết luận sạch: --quiet chủ động không in bản diff. Đồng thời không dùng một nhánh “khác 0” chung cho cả thay đổi và lỗi sai thư mục hoặc revision không tồn tại.
4. Kiểm tra phần đã stage và giới hạn đường dẫn
git diff --cached --quiet --no-ext-diff --no-textconv --
$stagedCode = $LASTEXITCODE
git diff --quiet --no-ext-diff --no-textconv -- src/
$sourceCode = $LASTEXITCODE
Đoạn này chỉ lấy hai mã, chưa quyết định pipeline phải làm gì. Mỗi mã vẫn cần được phân loại 0, 1 hoặc lỗi như ví dụ trước. Chạy từ thư mục gốc repo nếu src/ là đường dẫn tương đối từ gốc.
Nếu src/ không khớp file nào, một kết quả không khác biệt không chứng minh đường dẫn đã đúng. Cần xác minh phạm vi kiểm tra khi đổi cấu trúc thư mục hoặc sao chép script sang dự án khác.
5. File untracked cần một phép kiểm tra riêng
git ls-files --others --exclude-standard
git status --short --untracked-files=all
Một file mới chưa add có thể tồn tại dù git diff --quiet trả 0. ls-files ở trên liệt kê file untracked không bị các quy tắc ignore chuẩn loại ra; status giúp người vận hành đọc cả trạng thái index và working tree.
Hai lệnh này không tự trả mã 1 chỉ vì danh sách không rỗng. Script cần kiểm tra cả thành công của lệnh lẫn dữ liệu kết quả. Nếu tên file có ký tự đặc biệt và cần parse tự động, dùng định dạng phân cách NUL phù hợp như -z cùng bộ đọc hỗ trợ nó, thay vì giả định mỗi dòng luôn là một tên file nguyên bản.
6. Dựng các ca nhỏ trước khi dùng trong CI
- Repo có commit ban đầu và không thay đổi: hai phép diff chưa stage/đã stage đều trả 0.
- Sửa file đã theo dõi nhưng chưa stage: diff thường trả 1, --cached trả 0.
- Stage thay đổi đó: diff thường trở về 0, --cached trả 1.
- Tạo file mới chưa add: diff có thể vẫn trả 0; ls-files --others phải nhìn thấy file.
- Chạy với revision sai: nhận lỗi và không báo thành công.
- Stage một thay đổi rồi đưa working tree về nội dung HEAD: kiểm tra hai tầng có thể cùng trả 1 dù diff HEAD trả 0.
Các tình huống trên đã được chạy trong repository tạm riêng ở local. Không sửa index của workspace nội dung và chưa chạy CI trên dịch vụ hosting. Với submodule, filter hoặc quy tắc bỏ qua đặc biệt, cần bổ sung ca sát cấu hình dự án.
Tài liệu đối chiếu: git diff, git ls-files và gitignore. Hãy đặt tên kết quả theo đúng phạm vi kiểm tra, chẳng hạn “không có thay đổi chưa stage trong src”, thay vì gọi chung là “repo sạch”.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.