.gitignore không hoạt động: nguyên nhân và cách sửa

Nội dung

Bài viết giúp bạn kiểm tra vì sao .gitignore không hoạt động, sửa lỗi file đã tracked và dùng git check-ignore để debug pattern.

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é.

.gitignore không hoạt động trong Git
.gitignore chỉ bỏ qua file chưa được Git track, không tự gỡ file đã nằm trong index.

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.

Sơ đồ tracked và untracked khi .gitignore không hoạt động
.gitignore không tự bỏ tracking file đã được Git theo dõi.

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ệuNguyên nhân thường gặpCách xử lý
File vẫn hiện dù rule đúngFile đã trackedDùng git rm --cached
Rule không bắt được filePattern sai đường dẫnDù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ôngWildcard hoặc slash dùng saiReview pattern theo docs
Secret đã lỡ pushKhông còn là vấn đề ignore đơn thuầnRotate 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
Minh họa dùng git check-ignore để debug .gitignore không hoạt động
git check-ignore -v cho biết rule ignore nào đang được áp dụng.

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].

Quy trình git rm --cached khi .gitignore không hoạt động
git rm –cached bỏ file khỏi index nhưng không xóa file khỏi máy.

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
.envIgnore file hoặc thư mục tên .env ở nhiều cấpFile môi trường đơn giản
/.envChỉ ignore .env ở root nơi đặt .gitignoreMuốn giới hạn ở root repo
dist/Ignore thư mục distBuild output
*.logIgnore mọi file đuôi .logLog files
!example.envKhông ignore file này dù pattern trước đó có khớpGiữ 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
Ví dụ pattern .gitignore đúng và sai
Pattern .gitignore nên ngắn, rõ phạm vi và được kiểm tra bằng lệnh.

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:

  1. Chạy git status -sb để xem trạng thái hiện tại.
  2. Thêm hoặc sửa rule trong .gitignore.
  3. Dùng git check-ignore -v <file> để xác nhận pattern khớp đúng.
  4. Dùng git ls-files <file> để biết file có đang tracked không.
  5. Nếu đã tracked, chạy git rm --cached cho đúng file hoặc thư mục.
  6. Review bằng git diff --cached trước khi commit.
  7. 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-ignoregit 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

  1. Git Documentation: gitignore
  2. Git Documentation: git-check-ignore
  3. Git Documentation: git-rm
  4. GitHub Docs: Remediating a leaked secret
  5. GitHub Docs: Ignoring files
  6. 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.

Tú Anh

Cây bút chính tại VietnamTutor

Bài viết cùng chuyên mục

Git push bị rejected: cách sửa non-fast-forward

Bài viết giải thích vì sao git push bị rejected, cách đọc lỗi non-fast-forward và quy trình xử lý an toàn trước khi push lại.

Git reset revert restore: chọn lệnh đúng

Bài viết so sánh git reset, git revert và git restore theo mục đích sử dụng: sửa staging area, khôi phục file, undo commit chưa push

Git commit vào nhánh sai: cách chuyển an toàn

Bài viết hướng dẫn xử lý git commit vào nhánh sai theo từng tình huống: commit chưa push, đã push, nhiều commit liên tiếp hoặc branch

TypeScript cho website doanh nghiệp: API, form và lỗi

TypeScript cho website doanh nghiệp đáng dùng khi bạn cần kiểm soát API contract, form schema, CMS payload và cấu hình môi trường. Bài này giúp

React Server Components performance: khi nào nên dùng?

React Server Components performance không phải phép màu. Bài này giúp bạn biết khi nào RSC giảm JavaScript thật, khi nào làm kiến trúc phức tạp

Git commit nhầm file: bỏ file khỏi commit an toàn

Bài viết hướng dẫn xử lý git commit nhầm file theo từng tình huống: chưa commit, đã commit chưa push, đã push lên remote, hoặc lỡ

Git reflog: khôi phục commit đã mất an toàn

Bài viết hướng dẫn dùng git reflog để khôi phục commit đã mất sau reset, rebase, amend hoặc xóa nhánh. Bạn sẽ biết cách đọc reflog,

Git pull bị conflict: cách sửa không mất code

Bài viết hướng dẫn cách xử lý git pull bị conflict theo từng bước: kiểm tra trạng thái, sửa file xung đột, test lại và hoàn

Next.js production performance: chọn SSR, SSG, ISR hay Edge

Bài viết giúp developer và tech lead chọn cách render phù hợp để tối ưu Next.js production performance mà không làm kiến trúc phức tạp quá

Nâng cấp Laravel 13: Checklist 10 bước cần kiểm tra

Hướng dẫn nâng cấp Laravel 13 chi tiết với checklist 10 bước. Từ kiểm tra PHP 8.3, cập nhật dependencies, đến xử lý lỗi thường gặp

Hardening Laravel production: Checklist bảo mật cần làm

Checklist hardening Laravel production toàn diện. Từ cấu hình server, database, SSL đến security headers, rate limiting và monitoring.

Authentication và authorization trong Laravel: Cách phân biệt

Hướng dẫn chi tiết cách xây dựng hệ thống Authentication (xác thực) và Authorization (phân quyền) trong Laravel với Breeze, Fortify, Sanctum, Policies và Gates.