Bạn vừa commit xong mới phát hiện có file không nên đi theo commit: file cấu hình local, file log, ảnh test, hoặc tệ hơn là .env? Đây là lỗi rất thường gặp, kể cả khi bạn đã dùng Git lâu. Điều quan trọng là đừng vội chạy lệnh mạnh khi chưa biết commit đó đã push hay chưa.
Trong bài này, mình sẽ hướng dẫn bạn xử lý git commit nhầm file theo từng trạng thái: file mới chỉ staged, đã commit nhưng chưa push, đã push lên remote, hoặc file chứa secret. Bài này thuộc series xử lý lỗi Git của VietnamTutor, nối tiếp pillar Cách xử lý lỗi Git thường gặp và các bài recovery như Git reflog.

Tóm tắt nhanh
- Git commit nhầm file cần xử lý khác nhau tùy file mới staged, đã commit chưa push, hay đã push lên remote.
- Nếu mới staged, dùng
git restore --staged fileđể bỏ file khỏi staging area. - Nếu đã commit nhưng chưa push, dùng
git rm --cached filehoặcgit restore --stagedrồigit commit --amend. - Nếu đã push, ưu tiên tạo commit mới để sửa hoặc revert; chỉ rewrite history khi team đã thống nhất.
- Nếu file chứa secret như
.env, hãy rotate secret ngay; xóa khỏi Git history không đủ để coi là an toàn.
Git commit nhầm file là gì?
Git commit nhầm file là tình huống bạn đưa một hoặc nhiều file không mong muốn vào commit. File đó có thể không nguy hiểm, như log hoặc file test local, nhưng cũng có thể rất nghiêm trọng nếu chứa password, API key hoặc thông tin môi trường production.
Về mặt Git, commit là một snapshot của nội dung đã được đưa vào index tại thời điểm commit. Tài liệu git commit mô tả commit là thao tác ghi lại nội dung hiện tại của index cùng log message để tạo revision mới [1]. Vì vậy, nếu file đã vào index bằng git add, nó có thể đi theo commit nếu bạn không kiểm tra trước.
Các tình huống hay gặp gồm:
- Chạy
git add .và vô tình add cả file log, cache, ảnh test. - Commit cả file cấu hình local như
.env,config.local.php,docker-compose.override.yml. - Commit file build như
dist/hoặcvendor/trong repo không cần tracking. - Commit file đúng nhưng vào commit sai, làm pull request khó review.
- Commit file nhạy cảm rồi mới phát hiện sau khi push.
Điểm quan trọng: đừng chỉ hỏi “lệnh nào xóa file khỏi commit?”. Hãy hỏi trước: commit đã push chưa, file có chứa secret không, và có ai đã pull commit đó chưa.

Cần kiểm tra gì trước khi sửa?
Trước khi sửa, bạn cần biết file đang ở staging area, commit local chưa push, hay commit đã lên remote. Lệnh đầu tiên luôn nên là git status, sau đó kiểm tra commit gần nhất bằng git log hoặc git show.
git status # Xem file staged, unstaged và branch hiện tại git log --oneline --decorate -3 # Xem vài commit gần nhất git show --stat HEAD # Xem commit mới nhất đã chứa file nào
Tài liệu git status cho biết lệnh này hiển thị khác biệt giữa working tree, index và HEAD, nên đây là lệnh nền tảng trước khi quyết định unstage, amend hay revert [2].
Nếu bạn chưa push, kiểm tra thêm remote tracking:
git status # Nếu thấy "Your branch is ahead of 'origin/main' by 1 commit" # nghĩa là commit local chưa push lên remote.
Nếu đã push hoặc đang làm trên branch nhiều người dùng chung, cách xử lý cần thận trọng hơn. Rewrite history có thể làm người khác phải rebase hoặc mất công đồng bộ lại branch.

File mới staged nhưng chưa commit thì làm sao?
Nếu file mới được add vào staging area nhưng chưa commit, cách sửa đơn giản nhất là unstage file đó bằng git restore --staged. Lệnh này bỏ file khỏi index nhưng giữ nội dung file trong máy bạn.
Ví dụ bạn lỡ add .env và debug.log:
git restore --staged .env git restore --staged debug.log git status # Kiểm tra file đã rời khỏi nhóm "Changes to be committed" chưa
Tài liệu git restore mô tả tùy chọn --staged dùng để restore nội dung trong index, tức là tác động tới staging area chứ không xóa file local [3]. Đây là lệnh phù hợp cho người mới vì ít gây mất dữ liệu hơn reset --hard.
Nếu file không bao giờ nên được track, thêm vào .gitignore:
printf "\\n.env\\ndebug.log\\n" >> .gitignore git add .gitignore git commit -m "chore: ignore local env and logs"
Lưu ý: .gitignore chỉ giúp Git bỏ qua file chưa tracked. Nếu file đã từng được commit, bạn cần dùng cách ở phần tiếp theo.
Đã commit nhưng chưa push: sửa bằng amend
Nếu commit nhầm file nhưng chưa push, bạn có thể bỏ file khỏi commit rồi dùng git commit --amend để sửa commit gần nhất. Đây là tình huống dễ xử lý nhất vì history chỉ nằm trên máy bạn.
Giả sử commit mới nhất chứa nhầm .env, nhưng bạn muốn giữ file đó trong máy:
git rm --cached .env # Bỏ .env khỏi Git index nhưng giữ file local git add .gitignore # Nếu cần, thêm .env vào .gitignore git commit --amend # Sửa lại commit gần nhất
Tài liệu git rm giải thích tùy chọn --cached dùng để unstage và remove path khỏi index, nhưng để lại file trong working tree [4]. Đây là lệnh rất hữu ích khi bạn muốn Git ngừng track file nhưng không xóa file trên máy.
Nếu file chỉ bị đưa nhầm vào commit này nhưng vẫn cần track ở commit khác, bạn có thể reset mềm commit gần nhất rồi commit lại chọn lọc:
git reset --soft HEAD~1 # Đưa commit mới nhất về staging area git restore --staged path/to/file-nham.txt # Bỏ file nhầm khỏi staging git commit -m "feat: cập nhật luồng thanh toán" # Commit lại phần đúng
Tài liệu git reset mô tả reset có nhiều chế độ khác nhau; --soft chỉ đặt HEAD về commit trước và giữ thay đổi trong index/working tree [5]. Vì vậy nó phù hợp khi bạn muốn tách lại commit mà không mất code.
Mình khuyên bạn chạy git show --stat HEAD sau khi amend để chắc chắn file nhầm đã rời khỏi commit.

Đã push lên remote: nên sửa thế nào?
Nếu commit nhầm file đã push, cách an toàn cho team là tạo commit mới để sửa thay vì rewrite history ngay. Rewrite history chỉ nên dùng khi branch cá nhân và bạn chắc chắn chưa ai dựa vào commit đó.
Nếu file không nhạy cảm và chỉ cần bỏ khỏi repo từ thời điểm hiện tại:
git rm --cached path/to/local-file.txt echo "path/to/local-file.txt" >> .gitignore git add .gitignore git commit -m "chore: stop tracking local file" git push
Cách này không xóa file khỏi lịch sử cũ, nhưng làm repo sạch từ commit mới trở đi. Với file build, log, cache hoặc cấu hình local không nhạy cảm, đây thường là cách ít rủi ro nhất.
Nếu commit nhầm làm hỏng tính năng và bạn muốn hoàn tác toàn bộ commit đã push, dùng git revert thay vì reset branch chung:
git revert abc1234 git push
Tài liệu git revert mô tả lệnh này tạo commit mới để đảo ngược thay đổi từ commit cũ, phù hợp với history đã publish vì không xóa lịch sử [6]. Nếu trong lúc sửa phát sinh conflict khi pull code mới, bạn có thể xem thêm bài Git pull bị conflict để xử lý đúng flow merge hoặc rebase.
Với branch cá nhân, bạn có thể amend rồi force push bằng --force-with-lease, nhưng chỉ khi đã hiểu tác động:
git rm --cached file-nham.txt git commit --amend git push --force-with-lease
--force-with-lease vẫn là rewrite history. Nó an toàn hơn force push trần vì kiểm tra remote ref trước khi ghi đè, nhưng không biến rewrite history thành thao tác vô hại. Với branch chung, hãy trao đổi trước.

Lỡ commit .env hoặc secret thì xử lý ra sao?
Nếu file nhầm chứa secret, bước đầu tiên không phải là xóa commit mà là rotate hoặc thu hồi secret ngay. Một khi secret đã push lên remote, bạn phải xem như secret đó đã lộ.
GitHub Docs khuyến nghị khi xóa dữ liệu nhạy cảm khỏi repository, bạn vẫn cần coi secret là đã bị lộ và phải thay đổi token, password hoặc khóa liên quan [7]. Lý do rất đơn giản: người khác, bot, CI log hoặc cache có thể đã nhìn thấy nội dung trước khi bạn dọn history.
Quy trình thực tế nên là:
- Thu hồi hoặc rotate API key, password, token, private key ngay.
- Thêm file nhạy cảm vào
.gitignorevà commit rule ignore. - Thông báo team nếu secret liên quan staging, production hoặc third-party service.
- Dọn file khỏi commit hiện tại bằng commit sửa hoặc lịch sử repo nếu policy yêu cầu.
- Kiểm tra lại CI/CD, webhook, deployment variable và secret manager.
Nếu secret chỉ commit local chưa push, bạn có thể dùng amend như phần trên. Nếu đã push public hoặc repo nhiều người, hãy dùng công cụ dọn history theo hướng dẫn chính thức của nền tảng, sau đó rotate secret vẫn là bắt buộc.
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 chia sẻ các workflow thực chiến để developer xử lý lỗi trong dự án thật, không chỉ học lệnh rời rạc.

Cách tránh commit nhầm file lần sau
Cách tốt nhất để tránh commit nhầm là kiểm tra diff trước commit, dùng git add -p khi cần chọn lọc, và giữ .gitignore đúng ngay từ đầu dự án. Git không thay bạn hiểu ý nghĩa file, nhưng Git cho bạn đủ công cụ để kiểm soát.
Checklist mình khuyên dùng trước mỗi commit quan trọng:
- Chạy
git statusđể xem file nào sẽ đi theo commit. - Chạy
git diff --stagedđể đọc nội dung staged. - Dùng
git add -pnếu một file có cả thay đổi đúng và thay đổi chưa nên commit. - Không dùng
git add .theo thói quen khi repo đang có nhiều file local. - Thêm file môi trường, log, cache, build output vào
.gitignore. - Dùng pre-commit hook hoặc secret scanning nếu team hay làm việc với key/token.
Bảng chọn lệnh nhanh:
| Tình huống | Lệnh nên dùng | Ghi chú |
|---|---|---|
| File mới staged, chưa commit | git restore --staged file | Giữ file local, bỏ khỏi staging |
| Đã commit chưa push | git rm --cached file + git commit --amend | Sửa commit gần nhất |
| Muốn tách lại commit | git reset --soft HEAD~1 | Giữ thay đổi để commit lại |
| Đã push file không nhạy cảm | Commit sửa mới | Ít rủi ro cho team |
| Đã push secret | Rotate secret trước | Xóa history không thay thế rotate |
Nếu lỡ sửa quá tay trong lúc dọn commit, đừng hoảng. Bạn vẫn có thể dùng git reflog để tìm lại commit nếu commit từng tồn tại trong repo local.

Nguồn tham khảo
- Git documentation: git-commit
- Git documentation: git-status
- Git documentation: git-restore
- Git documentation: git-rm
- Git documentation: git-reset
- Git documentation: git-revert
- GitHub Docs: Removing sensitive data from a repository
Các câu hỏi thường gặp
Git commit nhầm file nhưng chưa push thì sửa thế nào?
Bạn có thể dùng git rm --cached file để bỏ file khỏi index, sau đó chạy git commit --amend để sửa commit gần nhất. Nếu chỉ muốn tách commit lại từ đầu, dùng git reset --soft HEAD~1.
Git restore –staged có xóa file trên máy không?
Không. git restore --staged file chỉ bỏ file khỏi staging area. Nội dung file vẫn còn trong working tree, nên bạn có thể sửa tiếp, ignore hoặc commit sau.
Git rm –cached khác gì xóa file bình thường?
git rm --cached file bỏ file khỏi Git index nhưng giữ file local trên máy. Xóa file bình thường có thể làm file biến mất khỏi working tree. Với file như .env, thường bạn muốn dùng --cached.
Đã push commit nhầm file thì có nên force push không?
Không nên force push trên branch chung nếu team chưa thống nhất. Với file không nhạy cảm, tạo commit sửa mới thường an toàn hơn. Force push hoặc rewrite history chỉ phù hợp hơn với branch cá nhân và vẫn cần dùng cẩn thận.
Lỡ commit .env rồi xóa commit có đủ an toàn không?
Không đủ nếu file đã push hoặc người khác có thể đã truy cập. Bạn cần rotate hoặc thu hồi secret ngay, rồi mới dọn file khỏi Git history theo policy của repo.
Làm sao biết commit mới nhất có chứa file nhầm?
Chạy git show --stat HEAD để xem danh sách file trong commit mới nhất. Nếu cần xem nội dung cụ thể, dùng git show HEAD -- path/to/file hoặc git diff HEAD~1 HEAD -- path/to/file.
Tóm lại, xử lý git commit nhầm file không khó nếu bạn xác định đúng trạng thái trước: staged, committed, pushed hay secret. Với commit chưa push, amend thường gọn nhất. Với commit đã push, ưu tiên commit sửa hoặc revert. Với secret, rotate trước rồi mới dọn Git. Lần sau, chỉ cần giữ thói quen git status và git diff --staged, bạn sẽ tránh được phần lớn lỗi này.
