TL;DR: để xoá untracked files trong git, chạy git clean -fd — nhưng luôn xem trước bằng git clean -nd, vì clean xoá vĩnh viễn và chúng không bao giờ ghé thùng rác. Dùng -f cho tệp, -fd cho tệp và thư mục, và -fdx nếu cả build output đã gitignore cũng phải biến mất. Lời than phiền phổ biến nhất — “git clean is not removing my untracked files” — gần như luôn nghĩa là các tệp nằm trong một thư mục untracked (thêm -d) hoặc chúng là ignored files (thêm -x). Đống lộn xộn untracked là sản phẩm phụ bình thường của việc thử nghiệm, build và các script chạy kèm clone; bài hướng dẫn này chỉ cách xem trước từng lần xoá, xoá tệp trong đúng một thư mục, và những tổ hợp nào không bao giờ được chạy trong một repo bạn coi trọng.
“Untracked files” trong git status nghĩa là gì?
Untracked nghĩa là git thấy tệp trên đĩa nhưng chưa từng được bảo track nó — nó không nằm trong index và không có lịch sử commit. git status xếp mọi thứ vào ba giỏ:
$ git status --short
M src/app.ts # modified: đã track, đã thay đổi
?? notes.txt # untracked: tệp mới mà git chưa biết
?? build/ # thư mục untracked: hoàn toàn mới với git Sự phân biệt đó quan trọng vì mỗi giỏ cần một công cụ dọn khác nhau. Tệp đã-track-nhưng-đã-thay-đổi được hoàn tác bằng git restore hoặc xoá đi bằng commit — git clean sẽ không đụng vào chúng. Chỉ những dòng ?? mới là lãnh địa của git clean. Ignored files (mọi thứ khớp với .gitignore) là giỏ thứ tư ẩn: chúng thậm chí không hiện thành ??, và git clean bỏ qua chúng trừ khi bạn chọn rõ ràng với -x.
Nếu vấn đề thật của bạn là một tệp đã track mà lẽ ra không bao giờ nên commit, dọn dẹp là công cụ sai — đó là việc của git rm --cached, hoặc reset commit gần nhất như bài git undo last commit: giữ lại các thay đổi đã nói.
Làm sao xoá untracked files trong git?
Lệnh lõi là git clean -f. Thiếu -f, git từ chối xoá bất cứ thứ gì và chỉ in một cảnh báo — một thanh chắn an toàn có chủ đích. Quy trình đầy đủ như sau:
# 1. Xem chính xác cái gì sẽ bị xoá (dry run — không xoá gì cả)
git clean -nd
# Sẽ xoá:
# notes.txt
# build/
# scratch/
# 2. Chắc chắn không có gì quý trong danh sách, rồi xoá thật
git clean -fd Từng cờ một:
-f/--force— bắt buộc. Thực sự xoá untracked files.-d— đi sâu vào các thư mục untracked.-ftrần chỉ xoá untracked files ở cấp trên cùng và báo tên những thư mục nó từ chối đụng.-n/--dry-run— cho thấy cái gì sẽ bị xoá. Luôn chạy cái này trước.-x— xoá cả ignored files (node_modules, build output,.env).-X— chỉ xoá ignored files, giữ lại những thứ untracked-nhưng-không-bị-ignore.-i— chế độ interactive; hữu ích khi danh sách dry-run dài.
Một thói quen đáng chép: coi git clean -nd như git diff — bạn xem trước khi commit, thì cũng xem trước khi clean.
Vì sao git clean không xoá untracked files của tôi?
Ba nguyên nhân có thật, xếp theo tần suất gặp:
1. Các tệp nằm trong một thư mục untracked. Chỉ với -f, git xoá các untracked files lẻ tẻ nhưng dừng ở thư mục, thậm chí báo Would remove build/ mà không xoá trong lần chạy thật. Thêm -d:
git clean -fd 2. Các tệp đã bị gitignore. node_modules/, dist/, .venv/ — các đường dẫn bị ignore vô hình với một lần clean trần. Dry run sẽ không liệt kê chúng, và clean cũng sẽ không xoá chúng. Phải chọn rõ ràng:
git clean -fdx # untracked + ignored files và thư mục 3. Một git repository lồng nhau hoặc submodule cản đường. Git không bao giờ xoá nội dung repo khác từ bên ngoài. Gỡ submodule đúng cách hoặc truyền --force hai lần (git clean -ffd), và nên chọn cách đầu.
Nếu dry run không liệt kê gì nhưng git status vẫn hiện các mục ??, bạn có lẽ đang ở sai working tree — chạy git rev-parse --show-toplevel và kiểm tra bạn đang ở trong repo định dọn.
Làm sao chỉ xoá untracked files trong một thư mục cụ thể?
Giới hạn phạm vi clean bằng cách truyền một đường dẫn — mọi thứ khác được để yên:
git clean -fd build/ # chỉ bên trong build/
git clean -fd src/generated # một cây thư mục cụ thể Đây là câu trả lời cho “tôi muốn xoá untracked files và thư mục trong build/ nhưng giữ lại ghi chép nháp ở gốc repo”. Đường dẫn tính tương đối theo thư mục hiện tại, nên chạy từ gốc repo là phạm vi cả repo; chạy từ một thư mục con là phạm vi cây con đó.
Làm sao dọn untracked files mà không xoá chúng?
Khi dry run cho thấy những tệp có khi bạn còn cần, đừng đánh bạc — giữ lại trước, clean sau:
# Stash untracked files (kể cả ignored với -a) mà không xoá
git stash push --include-untracked
git clean -fd # cây đã sạch
git stash pop # mang chúng trở lại khi cần git stash -u đưa untracked files ra khỏi cây nhưng vẫn giữ chúng phục hồi được — đó chính là ngữ nghĩa “remove without deleting” mà mọi người thực sự tìm kiếm. Muốn một bản xem trước giữ được, git clean -nd > clean-plan.txt cho bạn danh sách chính xác trước khi cam kết bất cứ điều gì. Không có undo sau git clean -f: đã xoá là mất.
git clean vs git rm vs git restore: cái nào dùng lúc nào?
| Lệnh | Đụng vào | Xoá khỏi đĩa | Dùng khi |
|---|---|---|---|
git clean -fd | Untracked files/thư mục | Có | Xoá tệp git chưa từng track |
git clean -fdx | Untracked + ignored | Có | Reset toàn bộ gồm cả node_modules, build output |
git rm <file> | Tracked files | Có (đã staged) | Xoá tệp và ghi lại việc xoá trong git |
git rm --cached <file> | Tracked files | Không | Ngừng track một tệp, giữ nó trên đĩa |
git restore <file> | Tracked files | Không | Vứt các chỉnh sửa local, giữ lại tệp |
Quy tắc một dòng: clean quản lý thứ git không biết; rm và restore quản lý thứ git biết. Nhầm lẫn giữa chúng là cách người ta mất đồ — chạy git clean -fdx trong khi cứ tưởng nó hành xử như git restore.
Khi nào tuyệt đối không chạy git clean?
Hai thói quen cần né ngay từ đầu:
- Không bao giờ chạy
git clean -fdxmột cách mù quáng trong monorepo hay workspace. Nó xoá mọi thư mục bị ignore — tức là mọinode_modules, mọi virtualenv, mọi.envlocal trong cây. Lấy lại chúng có thể đồng nghĩa với một tiếng cài lại, và một.envđã xoá có khi không thể phục hồi. - Không bao giờ tạo alias clean có sẵn force.
git config alias.wipe "clean -fd"cảm giác hiệu quả cho tới khi bạn gõ nhầm đường dẫn. Giữ dry run cách một phím (git clean -nd) và biến nó thành nghi thức hai lệnh: xem trước rồi xoá.
Cũng đáng biết: dọn untracked files ngay trước một pull [sync a fork with upstream] giúp mặt trận merge gọn — cây thư mục ngăn nắp là bảo hiểm xung đột rẻ nhất có thể: sync a fork with upstream từng bước.
Quy trình git clean an toàn, bản gọn
git status --short # trong cây có gì?
git clean -nd # xem trước: cái gì SẼ bị xoá?
git clean -fd # xoá untracked files + thư mục
git clean -fdX # (tuỳ chọn) dọn chỉ build output bị ignored
git status --short # xác nhận: working tree sạch Xem trước, xoá, xác minh — ba mươi giây, không hối hận, và git status cuối cùng cũng đọc sạch sẽ trở lại.
— mrsaynothing
— mrsaynothing
Ghi chú thực địa về AI, Linux và self-hosting.
Thảo luận bài này trên dev.to dev.to ↗
Nhận how-to tiếp theo qua email
Một email mỗi bài viết. Sửa xong rồi đi tiếp.
cái này là gì?Rsync vs scp: Nên dùng lệnh copy Linux nào
Thích kiểu viết này? Tôi build như vậy để kiếm sống. thuê tôi