TL;DR: จะลบไฟล์ untracked ใน git ให้รัน git clean -fd — แต่ต้องพรีวิวด้วย git clean -nd ก่อนเสมอ เพราะ clean ลบถาวรและไฟล์ไม่เข้าถังขยะเลยแม้แต่นิด ใช้ -f กับไฟล์ -fd กับไฟล์และโฟลเดอร์ และ -fdx ถ้า output ของการ build ที่ถูก ignore ควรหายไปด้วย ข้อร้องเรียนอันดับหนึ่ง — “git clean ไม่ยอมลบไฟล์ untracked ของผม” — แทบทุกครั้งหมายความว่าไฟล์อยู่ในโฟลเดอร์ untracked (เพิ่ม -d) หรือมันคือไฟล์ที่ถูก ignore (เพิ่ม -x) ขยะ untracked เป็นผลพลอยได้ปกติของการทดลอง การ build และสคริปต์แถว ๆ repo คู่มือนี้จะโชว์วิธีพรีวิวทุกการลบ ลบเฉพาะไฟล์ในโฟลเดอร์เดียว และคอมโบไหนที่ห้ามรันใน repo ที่คุณรัก
“untracked files” ใน git status หมายถึงอะไร?
untracked คือ git เห็นไฟล์บนดิสก์แต่ไม่เคยถูกสั่งให้ track มัน — ไม่อยู่ใน index และไม่มีประวัติ commit git status จัดทุกอย่างลงสามถัง:
$ git status --short
M src/app.ts # modified: tracked, มีการเปลี่ยนแปลง
?? notes.txt # untracked: ไฟล์ใหม่ที่ git ไม่รู้จัก
?? build/ # โฟลเดอร์ untracked: ใหม่เอี่ยมสำหรับ git การแบ่งแบบนี้สำคัญ เพราะแต่ละถังใช้เครื่องมือลบต่างกัน ไฟล์ tracked-แต่แก้แล้วต้องกู้ด้วย git restore หรือ commit ทับ — git clean จะไม่แตะมัน เฉพาะบรรทัด ?? เท่านั้นที่เป็นอาณาเขตของ git clean ไฟล์ที่ถูก ignore (ทุกอย่างที่ .gitignore จับได้) คือถังที่สี่ที่ซ่อนอยู่: ไม่แม้แต่โผล่เป็น ?? และ git clean ข้ามมันเว้นแต่คุณยินยอมชัดเจนด้วย -x
ถ้าปัญหาจริงของคุณคือไฟล์ tracked ที่ไม่ควรถูก commit ตั้งแต่แรก การ clean ไม่ใช่เครื่องมือที่ใช่ — นั่นเป็นงานของ git rm --cached หรือการย้อน commit ล่าสุดตามที่อธิบายใน git undo last commit: เก็บการเปลี่ยนแปลงไว้
ลบไฟล์ untracked ใน git อย่างไร?
คำสั่งหลักคือ git clean -f ถ้าไม่มี -f git จะปฏิเสธการลบและพิมพ์เตือนอย่างเดียว — ราวกันตกที่ตั้งใจไว้ ขั้นตอนเต็มหน้าตาแบบนี้:
# 1. ดูให้ชัดว่าจะโดนลบอะไร (dry run — ไม่ลบอะไรเลย)
git clean -nd
# Would remove:
# notes.txt
# build/
# scratch/
# 2. ยืนยันว่าไม่มีของมีค่าในรายการ แล้วค่อยลบจริง
git clean -fd อธิบายทีละ flag:
-f/--force— บังคับใช้ ลบไฟล์ untracked จริง ๆ-d— ลงไปในโฟลเดอร์ untracked ด้วย แบบใช้-fเปล่าจะลบได้เฉพาะไฟล์ untracked ชั้นบนสุดและรายงานโฟลเดอร์ที่ไม่กล้าแตะ-n/--dry-run— โชว์ว่าจะถูกลบอะไร รันก่อนทุกครั้ง-x— ลบไฟล์ที่ถูก ignore ด้วย (node_modules, output build,.env)-X— ลบเฉพาะไฟล์ที่ถูก ignore เก็บ untracked-ที่ไม่ถูก-ignore ไว้-i— โหมดโต้ตอบ มีประโยชน์เมื่อรายการ dry-run ยาว
นิสัยที่สมควรเลียนแบบ: ใช้ git clean -nd ให้เหมือน git diff — ดูก่อน commit ก็ดูก่อน clean
ทำไม git clean ไม่ยอมลบไฟล์ untracked ของผม?
สามสาเหตุจริง เรียงตามความถี่ที่กัด:
1. ไฟล์อยู่ในโฟลเดอร์ untracked ด้วย -f เฉย ๆ git ลบไฟล์ untracked ลอย ๆ แต่หยุดหน้าโฟลเดอร์ แถมรายงาน Would remove build/ โดยไม่ลบจริงเลย เพิ่ม -d:
git clean -fd 2. ไฟล์ถูก gitignore node_modules/, dist/, .venv/ — พาธที่ถูก ignore เป็นมองไม่เห็นสำหรับ clean ธรรมดา dry run จะไม่แสดง และ clean จะไม่เอาออก ยินยอมอย่างชัดเจน:
git clean -fdx # untracked + ไฟล์และโฟลเดอร์ที่ถูก ignore 3. git repository ที่ซ้อนอยู่หรือ submodule ยืนขวาง git ไม่เคยลบเนื้อหาของ repo อื่นจากภายนอก ลบ submodule อย่างถูกวิธี หรือส่ง --force สองครั้ง (git clean -ffd) — และเลือกทางแรกดีกว่า
ถ้า dry run ไม่แสดงอะไรเลยทั้งที่ git status ยังโชว์ ?? คุณคงอยู่ใน working tree ผิดตัว — รัน git rev-parse --show-toplevel แล้วเช็กว่าคุณอยู่ใน repo ที่ตั้งใจจะทำความสะอาดจริง
ลบไฟล์ untracked เฉพาะในโฟลเดอร์ที่กำหนดอย่างไร?
กำหนดขอบเขตการ clean ด้วยพาธ — ที่อื่นทั้งหมดไม่ถูกแตะ:
git clean -fd build/ # เฉพาะใน build/
git clean -fd src/generated # ต้นไม้ไฟล์ใดต้นไม้หนึ่งโดยเจาะจง นี่คือคำตอบของ “ผมอยากลบไฟล์และโฟลเดอร์ untracked ใน build/ แต่เก็บโน้ตร่างในราก repo ไว้” พาธจะวัดจากโฟลเดอร์ปัจจุบัน รันจากราก repo คือขอบเขตทั้ง repo รันจากโฟลเดอร์ย่อยคือขอบเขตต้นไม้นั้น
ลบไฟล์ untracked โดยไม่ลบมันจริง ๆ ได้ไหม?
เมื่อ dry run โชว์ไฟล์ที่คุณอาจต้องใช้ทีหลัง อย่าเสี่ยง — เก็บก่อนแล้วค่อย clean:
# ซ่อนไฟล์ untracked (รวมไฟล์ที่ถูก ignore ด้วย -a) โดยไม่ลบ
git stash push --include-untracked
git clean -fd # ต้นไม้สะอาดแล้ว
git stash pop # เอาคืนเมื่อต้องใช้ git stash -u ย้ายไฟล์ untracked ออกจากต้นไม้แต่ยังกู้คืนได้ — นั่นคือความหมายของ “ลบแบบไม่ลบ” ที่คนตามหาจริง ๆ สำหรับพรีวิวที่เก็บไว้ดูได้ git clean -nd > clean-plan.txt ให้รายการแบบเป๊ะก่อนตัดสินใจอะไรทั้งหมด ไม่มี undo หลัง git clean -f: ลบแปลว่าหาย
git clean vs git rm vs git restore: ใช้ตัวไหนเมื่อไร?
| คำสั่ง | แตะอะไร | ลบจากดิสก์ | ใช้เมื่อ |
|---|---|---|---|
git clean -fd | ไฟล์/โฟลเดอร์ untracked | ใช่ | ลบไฟล์ที่ git ไม่เคย track |
git clean -fdx | untracked + ที่ถูก ignore | ใช่ | รีเซ็ตเต็มรูปแบบ รวม node_modules กับ output build |
git rm <file> | ไฟล์ tracked | ใช่ (staged) | ลบไฟล์และบันทึกการลบลงใน git |
git rm --cached <file> | ไฟล์ tracked | ไม่ | เลิก track ไฟล์แต่เก็บไฟล์ไว้บนดิสก์ |
git restore <file> | ไฟล์ tracked | ไม่ | ทิ้งการแก้ไข local เก็บตัวไฟล์ไว้ |
กฎหนึ่งบรรทัด: clean จัดการสิ่งที่ git ไม่รู้จัก; rm กับ restore จัดการสิ่งที่ git รู้จัก การสลับกันของสองฝ่ายคือวิธีที่คนเสียงาน — รัน git clean -fdx ไปพลาง ๆ ทั้งที่เชื่อว่ามันทำงานเหมือน git restore
อะไรที่ห้ามใช้ git clean กับมันโดยเด็ดขาด?
สองนิสัยที่ต้องเว้นเด็ดขาด:
- ห้ามรัน
git clean -fdxโดยไม่คิดใน monorepo หรือ workspace มันลบทุกโฟลเดอร์ที่ถูก ignore — นั่นคือทุกnode_modulesทุก virtualenv ทุก.envในเครื่อง การได้คืนอาจแปลว่าหนึ่งชั่วโมงของการติดตั้งใหม่ และ.envที่ถูกลบอาจกู้คืนไม่ได้เลย - ห้ามทำ alias ใส่ force ติดไปด้วย
git config alias.wipe "clean -fd"ดูคล่องดีจนกว่าคุณจะพิมพ์พาธผิด เก็บ dry run ไว้ห่างแค่หนึ่งกด (git clean -nd) แล้วทำเป็นพิธีสองคำสั่ง ดูก่อนแล้วลบ
ที่ควรรู้เพิ่ม: การทำความสะอาดไฟล์ untracked ก่อน pull ตาม วิธีซิงก์ fork กับ upstream จะทำให้พื้นที่ conflict ของ merge แคบลง — ต้นไม้ที่เรียบร้อยคือประกัน conflict ราคาถูกที่สุดเท่าที่มี: ซิงก์ fork กับ upstream ทีละขั้น
เวิร์กโฟลว์ git clean ที่ปลอดภัย ฉบับย่อ
git status --short # ในต้นไม้มีอะไร?
git clean -nd # พรีวิว: อะไรจะหายไป?
git clean -fd # ลบไฟล์ untracked + โฟลเดอร์
git clean -fdX # (ทางเลือก) เคลียร์เฉพาะ output build ที่ถูก ignore
git status --short # ยืนยัน: working tree สะอาด พรีวิว ลบ ตรวจสอบ — สามสิบวินาที ศูนย์ความเสียใจ และ git status ในที่สุดก็อ่านว่าสะอาดอีกครั้ง
— mrsaynothing
— mrsaynothing
บันทึกหน้างานเรื่อง AI, Linux และ self-hosted
คุยต่อโพสต์นี้บน dev.to dev.to ↗
รับวิธีแก้ฉบับถัดไปทางอีเมล
อีเมลหนึ่งฉบับต่อหนึ่งโพสต์ แก้เสร็จแล้วไปต่อ
นี่คืออะไร?Rsync vs SCP: คำสั่งคัดลอกของ Linux ควรใช้ตัวไหน
ถ้าอ่านแล้วชอบ — ผมสร้างงานแบบนี้เป็นอาชีพ จ้างผม