بازگشت به وبلاگ

حذف فایل‌های untracked در Git: راهنمای امن git clean

۱۸ شهریور ۱۴۰۵

TL;DR: برای حذف فایل‌های untracked در git دستور git clean -fd را اجرا کنید — ولی همیشه اول با git clean -nd پیش‌نمایش بگیرید، چون clean برای همیشه حذف می‌کند و این فایل‌ها هرگز به سبد بازیافت نمی‌روند. -f برای فایل‌ها، -fd برای فایل‌ها و پوشه‌ها، و -fdx اگر خروجی بیلدِ نادیده‌گرفته‌شده هم باید برود. شایع‌ترین گلایه — «git clean فایل‌های untracked من را حذف نمی‌کند» — تقریباً همیشه یعنی فایل‌ها داخل یک پوشه untracked زندگی می‌کنند (-d را اضافه کنید) یا نادیده‌گرفته‌شده‌اند (-x را اضافه کنید). شلوغی untracked محصول طبیعی آزمایش‌ها و بیلدهاست؛ این راهنما نشان می‌دهد چطور قبل از هر حذف پیش‌نمایش بگیرید، چطور فقط از یک پوشه پاک کنید و کدام ترکیب‌ها را هرگز در مخزنی که برایتان مهم است اجرا نکنید.

منظور از فایل‌های untracked در git status چیست؟

untracked یعنی git فایل را روی دیسک می‌بیند اما هرگز به او گفته نشده ردیابی‌اش کند — نه در index است و نه تاریخچه commit دارد. git status همه‌چیز را در سه سطل می‌چیند:

$ git status --short
 M src/app.ts        # modified: tracked, changed
?? notes.txt         # untracked: new file git doesn't know
?? build/            # untracked directory: entirely new to git

این تفکیک مهم است، چون هر سطل ابزار حذف متفاوتی می‌خواهد. فایل‌های tracked-اما-تغییرکرده با git restore برمی‌گردند یا با commit جمع می‌شوند — git clean به آن‌ها دست نمی‌زند. فقط خطوط ?? قلمرو git clean هستند. فایل‌های نادیده‌گرفته‌شده (هر چیزی که .gitignore می‌گیرد) سطل پنهان چهارم‌اند: حتی به شکل ?? هم ظاهر نمی‌شوند و git clean از آن‌ها رد می‌شود مگر اینکه با -x صریحاً رضایت بدهید.

اگر مشکل واقعی شما یک فایل tracked است که هرگز نباید commit می‌شد، پاک‌کردن ابزار اشتباهی است — آن کار git rm --cached است، یا ریست آخرین commit که در لغو آخرین commit با حفظ تغییرات آمده.

چگونه در Git فایل‌های untracked را حذف کنیم؟

دستور اصلی git clean -f است. بدون -f git از حذف هر چیزی سر باز می‌زند و فقط هشدار می‌دهد — یک ریل ایمنی عامدانه. روتین کامل چنین است:

# 1. See exactly what will be deleted (dry run — deletes nothing)
git clean -nd

# Would remove:
# notes.txt
# build/
# scratch/

# 2. Confirm nothing precious is in the list, then delete for real
git clean -fd

فلگ‌به‌فلگ:

  • -f / --force — الزامی است. واقعاً فایل‌های untracked را حذف می‌کند.
  • -d — داخل پوشه‌های untracked recurse می‌کند. -f تنها فایل‌های untracked سطح بالا را حذف می‌کند و پوشه‌هایی را که از حذفشان امتناع کرده گزارش می‌دهد.
  • -n / --dry-run — نشان می‌دهد چه چیزهایی حذف می‌شد. همیشه اول این را اجرا کنید.
  • -x — فایل‌های نادیده‌گرفته‌شده را هم حذف می‌کند (node_modules، خروجی بیلد، .env).
  • -Xفقط فایل‌های نادیده‌گرفته‌شده را حذف می‌کند و untracked-اما-غیرنادیده‌گرفته را نگه می‌دارد.
  • -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/ — مسیرهای نادیده‌گرفته از دید یک clean ساده نامرئی‌اند. نه در dry-run فهرست می‌شوند و نه در clean حذف. صریحاً رضایت بدهید:

git clean -fdx   # untracked + ignored files and directories

3. یک مخزن git تو‌در‌تو یا submodule سر راه است. git هرگز محتویات مخزن دیگری را از بیرون حذف نمی‌کند. submodule را درست حذف کنید یا --force را دو بار بدهید (git clean -ffd) — و گزینه اول را ترجیح دهید.

اگر dry-run هیچ‌چیز فهرست نکرد ولی git status همچنان ?? نشان می‌دهد، احتمالاً در درخت کاری اشتباهی هستید — git rev-parse --show-toplevel را اجرا کنید و مطمئن شوید داخل همان مخزنی هستید که قصد پاک کردنش را داشتید.

چگونه فقط از یک پوشه مشخص فایل‌های untracked را حذف کنیم؟

با دادن یک مسیر دامنه clean را محدود کنید — بقیه دست‌نخورده می‌ماند:

git clean -fd build/          # only inside build/
git clean -fd src/generated   # one specific tree

پاسخ همین است به «می‌خواهم فایل‌ها و پوشه‌های untracked داخل build/ را حذف کنم ولی یادداشت‌های آشفتگی‌ام در ریشه مخزن بماند». مسیر نسبت به پوشه فعلی شماست، پس اجرا از ریشه مخزن دامنه را کل مخزن می‌کند و اجرا از یک زیرپوشه دامنه را همان زیردرخت.

چگونه فایل‌های untracked را حذف کنیم بدون اینکه واقعاً حذف شوند؟

وقتی dry-run فایل‌هایی نشان می‌دهد که شاید بعداً بخواهید، قمار نکنید — اول نگه دارید، بعد پاک کنید:

# Stash untracked files (including ignored ones with -a) without deleting
git stash push --include-untracked
git clean -fd                      # tree is clean
git stash pop                      # bring them back when needed

git stash -u فایل‌های untracked را از درخت بیرون می‌برد ولی قابل بازیابی نگهشان می‌دارد — همین همان معنای «حذف بدون حذف» است که مردم در واقع دنبالش هستند. برای پیش‌نمایشی که بماند، git clean -nd > clean-plan.txt فهرست دقیق را قبل از هر تعهدی می‌دهد. بعد از git clean -f برگشتی نیست: حذف‌شده یعنی رفته.

git clean در مقابل git rm در مقابل git restore: کدام کی؟

دستوردست می‌زند بهاز دیسک حذف می‌کند؟استفاده وقتی
git clean -fdفایل‌ها/پوشه‌های untrackedبلهحذف فایل‌هایی که git هرگز ردیابی نکرده
git clean -fdxuntracked + نادیده‌گرفتهبلهریست کامل شامل node_modules و خروجی بیلد
git rm <file>فایل‌های trackedبله (stage می‌شود)حذف یک فایل و ثبت حذفش در git
git rm --cached <file>فایل‌های trackedخیرتوقف ردیابی یک فایل با ماندنش روی دیسک
git restore <file>فایل‌های trackedخیردور ریختن ویرایش‌های محلی با ماندن فایل

قاعده یک‌خطی: clean مدیریت می‌کند git از چه چیزی خبر ندارد؛ rm و restore مدیریت می‌کنند آنچه خبر دارد. قاطی‌کردنشان همان‌جایی است که کار گم می‌شود — اجرای git clean -fdx با این باور که مثل git restore رفتار می‌کند.

روی چه چیزهایی هرگز git clean اجرا نکنید؟

دو عادت که باید کلاً دورشان را خط کشید:

  1. هرگز git clean -fdx را کورکورانه در monorepo یا workspace اجرا نکنید. هر پوشه نادیده‌گرفته‌شده را حذف می‌کند — یعنی همه node_modulesها، همه محیط‌های مجازی، همه .envهای محلی در درخت. برگرداندن‌شان می‌تواند یک ساعت نصب مجدد باشد و یک .env حذف‌شده ممکن است اصلاً قابل بازیابی نباشد.
  2. هرگز alias با force تزریق‌شده نسازید. git config alias.wipe "clean -fd" تا وقتی مسیر را غلط تایپ نکرده‌اید احساس بهره‌وری می‌دهد. dry-run را در فاصله یک کلید نگه دارید (git clean -nd) و از آن یک تشریف دو‌دستوری بسازید: اول پیش‌نمایش، بعد حذف.

همچنین بدانید: پاک‌کردن فایل‌های untracked درست قبل از pull، سطح تداخل merge را کوچک نگه می‌دارد — درخت تمیز، ارزان‌ترین بیمه ضدتعارض است: همگام‌سازی fork با upstream، گام‌به‌گام.

گردش‌کار امن git clean، خلاصه

git status --short        # what's in the tree?
git clean -nd             # preview: what WOULD go?
git clean -fd             # delete untracked files + directories
git clean -fdX            # (optional) clear only ignored build output
git status --short        # confirm: working tree clean

پیش‌نمایش، حذف، راستی‌آزمایی — سی ثانیه، صفر پشیمانی، و git status بالاخره باز هم تمیز می‌خواند.

FAQ

چگونه در git فایل‌های untracked را حذف کنم؟

دستور git clean -fd فایل‌ها و پوشه‌های untracked را حذف می‌کند. اول با -n dry-run بگیرید — clean مخرب است و برگشتی ندارد.

آیا git clean فایل‌های نادیده‌گرفته‌شده را هم حذف می‌کند؟

به‌طور پیش‌فرض نه. -x فایل‌های نادیده‌گرفته‌شده را هم اضافه می‌کند و -X فقط همان‌ها را هدف می‌گیرد. بیشتر حادثه‌ها از -x داخل اسکریپت‌ها شروع می‌شود.

چگونه یک فایل untracked را نگه دارم و بقیه را پاک کنم؟

با -e <path> مستثنایش کنید یا قبل از اجرای git clean -fd به .gitignore اضافه‌اش کنید.

— mrsaynothing

— mrsaynothing

یادداشت‌های میدانی درباره AI، لینوکس و self-hosting.

این نوشته را در dev.to بحث کنید dev.to ↗

آموزش بعدی با ایمیل

هر نوشته یک ایمیل. درستش کن، برو سراغ بعدی.

self-hosted · بدون واسطه‌های ثالث · لغو اشتراک با یک کلیک

این چیست؟

rsync در مقابل scp: کدام دستور کپی در Linux را به‌کار ببریم

این نوشته‌ها را می‌پسندید؟ این همان کاری است که برای زندگی از آن درمی‌آورم. استخدامم کنید