Bạn đã thêm file vào .gitignore nhưng Git vẫn báo file đó trong git status? Đây là một lỗi rất dễ gây khó chịu, nhất là khi file đó là .env, thư mục build, cache IDE hoặc file log.
Tin tốt là đa số trường hợp .gitignore không hoạt động không phải do Git bị lỗi. Thường là vì file đã được track trước đó, pattern viết chưa đúng, hoặc bạn đang đặt file .gitignore sai cấp thư mục. Mình sẽ giúp bạn kiểm tra từng nguyên nhân và sửa an toàn nhé.

Tóm tắt nhanh
- .gitignore không hoạt động thường vì file đã được Git track trước khi bạn thêm rule ignore.
- Dùng
git check-ignore -v <file>để biết pattern nào đang áp dụng. - Dùng
git rm --cached <file>để bỏ tracking nhưng vẫn giữ file local. - Kiểm tra lại đường dẫn, dấu slash, wildcard và vị trí file
.gitignore. - Không dùng
.gitignoređể xử lý secret đã lỡ push; lúc đó cần rotate key và cleanup history.
.gitignore hoạt động như thế nào?
.gitignore là file khai báo các pattern mà Git nên bỏ qua khi phát hiện file chưa được track. Nó không tự xóa file khỏi repository, cũng không làm Git quên những file đã được commit trước đó.
Tài liệu chính thức của Git mô tả gitignore là cơ chế chỉ định intentionally untracked files để Git bỏ qua [1]. Cụm từ quan trọng ở đây là untracked. Nếu file đã từng được git add hoặc commit, Git vẫn tiếp tục theo dõi file đó dù bạn thêm nó vào .gitignore.
Ví dụ dễ gặp:
# Bạn đã từng commit file này config/local.env # Sau đó mới thêm vào .gitignore *.env
Trong tình huống này, *.env có thể đúng, nhưng file config/local.env vẫn hiện trong status vì nó đã nằm trong Git index. Đây là nguyên nhân phổ biến nhất.

Vì sao .gitignore không hoạt động?
Có 5 nhóm nguyên nhân chính: file đã tracked, pattern sai, file .gitignore đặt sai chỗ, rule bị override, hoặc bạn đang hiểu nhầm output của Git. Hãy kiểm tra theo thứ tự từ dễ đến khó.
| Dấu hiệu | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| File vẫn hiện dù rule đúng | File đã tracked | Dùng git rm --cached |
| Rule không bắt được file | Pattern sai đường dẫn | Dùng git check-ignore -v |
| Rule chỉ đúng ở thư mục khác | .gitignore đặt sai cấp | Đặt rule ở root hoặc chỉnh path |
| Một số file ignore, một số không | Wildcard hoặc slash dùng sai | Review pattern theo docs |
| Secret đã lỡ push | Không còn là vấn đề ignore đơn thuần | Rotate secret và xử lý lịch sử Git |
Nếu bạn đang gặp trường hợp IDE tạo thư mục như .idea, có thể đọc thêm bài loại bỏ thư mục .idea khỏi Git. Nếu đã commit nhầm file, bài Git commit nhầm file sẽ giúp bạn chọn cách sửa theo trạng thái đã push hay chưa.
Bạn đang đọc bài viết thuộc chuyên mục Lập trình của VietnamTutor — nơi mình ưu tiên các hướng dẫn Git thực tế, có lệnh kiểm tra rõ ràng và cảnh báo rủi ro trước khi sửa.
Cách kiểm tra pattern .gitignore
Cách debug tốt nhất là dùng git check-ignore -v để xem rule nào đang khiến Git ignore file, hoặc xác nhận không rule nào khớp. Lệnh này giúp bạn không phải đoán pattern bằng mắt.
# Kiểm tra file có bị ignore không và rule nào khớp git check-ignore -v path/to/file.log # Kiểm tra nhiều file cùng lúc git check-ignore -v .env storage/debug.log node_modules/demo.js
Tài liệu git check-ignore cho biết tùy chọn -v sẽ hiển thị nguồn pattern, số dòng và pattern khớp [2]. Đây là thông tin rất hữu ích khi repository có nhiều file ignore ở các cấp khác nhau.
Nếu lệnh không in gì, có hai khả năng: file không bị ignore bởi pattern nào, hoặc file đã tracked nên bạn đang nhìn vấn đề ở hướng khác. Khi đó hãy kiểm tra file có nằm trong index chưa:
# Nếu lệnh in ra đường dẫn, file đang được Git track git ls-files path/to/file.log

Bỏ tracking nhưng giữ file local
Nếu file đã tracked, bạn cần bỏ file khỏi Git index bằng git rm --cached, sau đó commit thay đổi này. Tùy chọn --cached giúp Git ngừng theo dõi file nhưng vẫn giữ file trên máy bạn.
Ví dụ với một file:
# Thêm rule ignore trước echo ".env" >> .gitignore # Bỏ tracking file khỏi index nhưng giữ file local git rm --cached .env # Commit thay đổi .gitignore và trạng thái bỏ tracking git add .gitignore git commit -m "Stop tracking local env file"
Với cả thư mục:
# Bỏ tracking toàn bộ thư mục build nhưng giữ lại trên máy git rm -r --cached dist/ git add .gitignore git commit -m "Ignore build output"
Tài liệu git rm giải thích --cached dùng để unstage và chỉ xóa path khỏi index, không xóa file khỏi working tree [3]. Đây là lý do lệnh này phù hợp khi bạn muốn giữ file local như .env, dist/ hoặc cache IDE.
Lưu ý quan trọng: nếu file chứa secret đã bị push lên remote, git rm --cached chỉ ngăn Git theo dõi từ commit mới trở đi. Secret vẫn còn trong lịch sử cũ. Với trường hợp đó, GitHub khuyến nghị xem secret là đã lộ, cần revoke/rotate và xử lý lịch sử nếu cần [4].

Các pattern .gitignore hay viết sai
Nhiều lỗi .gitignore đến từ việc pattern không khớp đúng đường dẫn bạn nghĩ. Chỉ cần sai dấu slash hoặc wildcard, Git có thể bỏ qua file khác với kỳ vọng.
| Pattern | Ý nghĩa thực tế | Khi nên dùng |
|---|---|---|
.env | Ignore file hoặc thư mục tên .env ở nhiều cấp | File môi trường đơn giản |
/.env | Chỉ ignore .env ở root nơi đặt .gitignore | Muốn giới hạn ở root repo |
dist/ | Ignore thư mục dist | Build output |
*.log | Ignore mọi file đuôi .log | Log files |
!example.env | Không ignore file này dù pattern trước đó có khớp | Giữ file mẫu trong repo |
Tài liệu gitignore mô tả rõ cách slash, dấu !, wildcard và thứ tự pattern hoạt động [1]. Nếu repository của bạn có cấu trúc phức tạp, mình khuyên bạn thêm từng rule nhỏ rồi kiểm tra bằng git check-ignore -v thay vì dán một block rất dài.
Ví dụ pattern thực tế cho dự án web:
# File môi trường local .env .env.local # Build output dist/ build/ # Dependency cache node_modules/ vendor/ # Log *.log # Giữ file mẫu để team biết biến môi trường cần có !.env.example

Quy trình sửa an toàn cho team
Với repository dùng chung, hãy sửa .gitignore theo quy trình có kiểm tra để không vô tình xóa file cần thiết của đồng đội. Đừng chạy lệnh hàng loạt nếu bạn chưa xem danh sách file bị ảnh hưởng.
Quy trình mình thường dùng:
- Chạy
git status -sbđể xem trạng thái hiện tại. - Thêm hoặc sửa rule trong
.gitignore. - Dùng
git check-ignore -v <file>để xác nhận pattern khớp đúng. - Dùng
git ls-files <file>để biết file có đang tracked không. - Nếu đã tracked, chạy
git rm --cachedcho đúng file hoặc thư mục. - Review bằng
git diff --cachedtrước khi commit. - Commit với message rõ: bỏ tracking file local, build output hoặc cache.
Ví dụ review trước commit:
git status -sb git diff --cached --name-status git commit -m "Ignore generated files"
Nếu bạn lỡ đưa secret vào Git, đừng chỉ thêm vào .gitignore rồi yên tâm. Hãy rotate secret trước, kiểm tra nơi secret đã được dùng, rồi mới quyết định có cần rewrite history hay không. Với những ca nhạy cảm như vậy, ưu tiên quy trình bảo mật hơn là chỉ làm sạch status.
Tóm lại, .gitignore không hoạt động phần lớn vì Git vẫn đang track file cũ. Hãy kiểm tra bằng git check-ignore và git ls-files, sau đó dùng git rm --cached đúng phạm vi. Làm chậm một chút ở bước kiểm tra sẽ giúp bạn tránh một commit cleanup gây rối cho cả team.
Nguồn tham khảo
- Git Documentation: gitignore
- Git Documentation: git-check-ignore
- Git Documentation: git-rm
- GitHub Docs: Remediating a leaked secret
- GitHub Docs: Ignoring files
- Git Documentation: git-ls-files
Các câu hỏi thường gặp
Vì sao thêm .env vào .gitignore nhưng Git vẫn hiện file?
Thường là vì .env đã được Git track trước đó. Bạn cần thêm rule ignore rồi chạy git rm –cached .env để bỏ file khỏi index nhưng vẫn giữ file trên máy.
git rm –cached có xóa file local không?
Không. Tùy chọn –cached chỉ bỏ file khỏi Git index. File vẫn còn trong working tree của bạn, miễn là bạn không dùng lệnh rm không có –cached.
Làm sao biết rule .gitignore nào đang khớp?
Dùng git check-ignore -v path/to/file. Lệnh này hiển thị file ignore, số dòng và pattern đang khớp với file bạn kiểm tra.
Có nên ignore vendor hoặc node_modules không?
Trong đa số dự án web hiện đại, node_modules nên được ignore. Với vendor, hãy theo quy ước dự án và cách deploy. Nếu dependency được cài từ lockfile trong CI/CD, thường không cần commit thư mục dependency.
.gitignore có xóa secret đã lỡ push không?
Không. .gitignore chỉ ngăn tracking về sau. Secret đã push vẫn có thể nằm trong lịch sử Git, nên bạn cần rotate hoặc revoke secret và xử lý lịch sử nếu cần.
