.gitignore

Xem thử

Vấn đề cần giải quyết

Bạn chạy git status và thấy hàng nghìn dòng node_modules/..., vài tệp .log, và một tệp .env chứa mật khẩu cơ sở dữ liệu. Chỉ cần một lần git add . bất cẩn là mật khẩu vào lịch sử, và lúc đó đã quá muộn. Tệp .gitignore liệt kê các mẫu mà Git sẽ bỏ qua.

Sau bài này, bạn có thể

  • Viết .gitignore cho dự án thật và hiểu các mẫu cơ bản.
  • Giải thích vì sao .gitignore không tác dụng với tệp đã được theo dõi.
  • Gỡ một tệp đã lỡ commit khỏi theo dõi mà vẫn giữ trên đĩa, và biết giới hạn của việc đó.

Tiên quyết: bài Tổng quan lưu thay đổi.

Ví dụ .gitignore

gitignore
# Phụ thuộc
node_modules/
vendor/

# Kết quả build
dist/
build/
*.log

# Biến môi trường và bí mật
.env
.env.local

# Tệp hệ điều hành và IDE
.DS_Store
.idea/
.vscode/

Git quyết định một tệp có bị bỏ qua thế nào

Với mỗi tệp trong Working Directory, Git hỏi hai câu theo thứ tự. Hãy chú ý nhánh đầu tiên.

Đang tải sơ đồ…

Cách đọc hình. Câu hỏi đầu tiên là tệp đã được theo dõi chưa. Nếu rồi, .gitignore không có tác dụng và tệp vẫn được theo dõi. Chỉ với tệp chưa theo dõi, Git mới kiểm tra mẫu: khớp thì bị bỏ qua, không khớp thì hiện là untracked trong git status.

Thử và quan sát

Hãy dự đoán: bạn thêm .env vào .gitignore, nhưng .env đã được commit từ trước. Sửa .env rồi chạy git status thì còn báo thay đổi không? Chạy mô phỏng cả hai kịch bản.

Đang tải Animation…

Bảng bước (bản đọc tĩnh của mô phỏng)

BướcLệnhĐiều xảy ra
1git status --shortBa thứ không nên theo dõi đang làm rối danh sách: log, bí mật và thư viện tải về.
2echo "*.log" >> .gitignoreMẫu *.log khớp mọi tệp kết thúc bằng .log nên debug.log bị bỏ qua.
3printf ".env\nnode_modules/\n" >> .gitignoreThêm hai mẫu nữa. Mẫu có dấu / ở cuối chỉ khớp thư mục.
4git status --shortBa tệp đã biến mất khỏi danh sách. Chỉ còn bản thân .gitignore là tệp mới cần commit.
5git add .gitignore && git commit -m "Thêm .gitignore"Commit .gitignore để cả đội dùng chung quy tắc.

Biến thể: .env đã lỡ commit từ trước

BướcLệnhĐiều xảy ra
1echo "SECRET=abc" >> .env.env nằm trong .gitignore nhưng đã được theo dõi, nên Git vẫn thấy nó đã sửa.
2git status --short.gitignore không có tác dụng với tệp đã được theo dõi.
3git rm --cached .envGỡ .env khỏi index nhưng giữ tệp trên đĩa. Từ giờ .gitignore bỏ qua nó.
4git commit -m "Ngừng theo dõi .env"Commit mới không còn chứa .env.
5git log --oneline -- .envCommit cũ vẫn chứa nội dung .env trong lịch sử. Nếu đó là bí mật, phải đổi bí mật.

Giải đáp. Còn báo, vì tệp đã được theo dõi. Phải ngừng theo dõi bằng git rm --cached, rồi .gitignore mới bỏ qua nó. Nhưng các commit cũ đã chứa .env vẫn giữ nguyên trong lịch sử; nếu đó là bí mật thật, hãy đổi bí mật.

Quy tắc mẫu

MẫuÝ nghĩa
*.logMọi tệp kết thúc bằng .log
build/Thư mục tên build ở mọi cấp
/secret.txtChỉ secret.txt ở thư mục gốc
!important.logKhông bỏ qua (phủ định)
doc/**/*.pdfMọi PDF ở mọi cấp trong doc

Đã lỡ commit thì sao

bash
git rm --cached .env
echo ".env" >> .gitignore
git commit -m "Ngừng theo dõi .env"

git rm --cached gỡ tệp khỏi index nhưng giữ trên đĩa. Để biết một tệp bị bỏ qua bởi mẫu nào:

bash
git check-ignore -v debug.log

Kết quả cho thấy tệp .gitignore, số dòng và mẫu khớp, ví dụ .gitignore:1:*.log debug.log.

Hiểu lầm thường gặp

  • "Thêm vào .gitignore là Git ngừng theo dõi." Không với tệp đã theo dõi.
  • "git rm --cached xóa tệp khỏi lịch sử." Nó chỉ ngừng theo dõi từ commit mới; commit cũ vẫn chứa tệp.
  • "Mỗi người nên tự có .gitignore riêng." Hãy commit .gitignore chung cho cả đội; quy tắc riêng của cá nhân đặt trong tệp ignore toàn cục.

Tự kiểm tra

  1. Một tệp đã commit rồi mới thêm vào .gitignore. Git có bỏ qua nó không?
  2. Mẫu /config.json khác config.json thế nào?
  3. Bạn lỡ commit một khóa API. Chỉ git rm --cached có đủ không?

Đáp án gợi ý. (1) Không, vì tệp đã theo dõi. (2) /config.json chỉ khớp ở thư mục gốc; config.json khớp ở mọi cấp. (3) Không; khóa vẫn nằm trong lịch sử, cần thu hồi và cấp khóa mới.

Điều cần nhớ

  • .gitignore chỉ tác động tới tệp chưa được theo dõi.
  • Tệp đã theo dõi: dùng git rm --cached, và lịch sử cũ vẫn giữ bản đã commit.
  • Commit .gitignore để cả đội dùng chung quy tắc.
  • Chương sau: Kiểm tra kho, đọc trạng thái và lịch sử.

Nguồn tham khảo

Pro Git, chương 2.2 "Ignoring Files" (git-scm.com/book); tài liệu gitignore (git-scm.com/docs/gitignore).