بازبینی کد میرسد در حالی که سه فایل نیمهکارهاند و فقط یکی حق دارد تکان بخورد. همه را stash کردن و دو فایل دیگر را از نو تایپ کردن — همان تشریفاتی که هیچکس دلش برایش تنگ نمیشود.
TL;DR: git stash push -m "دلیل" -- <path> دقیقاً مسیرهای نامبرده را stash میکند و بقیه درخت کثیف شما را بیکار میگذارد. تغییرات را با git stash pop پس بگیرید (یا یک فایل را از هر stashی جدا کنید با git restore --source stash@{0} -- <path>). حالت pathspec با git 2.13 آمد، منتشرشده در مه ۲۰۱۷ — هر زنجیره ابزار هشت سال اخیر آن را دارد.
git stash push -m "app.conf prod tweak" -- app.conf
git stash list
# stash@{0}: On main: app.conf prod tweak
git stash pop فایل را stash کن، نه درخت را.
در git چطور فقط یک فایل را stash کنم؟
git stash لخت، کل درخت کاری را جارو میکند — هر تغییر ردیابیشده وارد stash میشود و همه چیز به HEAD برمیگردد. وقتی درخت کثیف مخلوط است این شکل غلطی است: یک فایل آماده تحویل است، بقیه صادقانه نیمهتمام. پاسخ فعل push با pathspec است، طبق مستندات git-stash:
# قبل: سه فایل کثیف
$ git status --short
M app.conf
M notes.md
M main.py
# فقط app.conf را stash کن
$ git stash push -m "app.conf prod tweak" -- app.conf
Saved working directory and index state On main: app.conf prod tweak
$ git status --short
M notes.md
M main.py app.conf به حالت کامیتشده برگشت و در stash@{0} نشست؛ notes.md و main.py اصلاً تکانی نخوردند. پیام -m اختیاری است اما لحظهای که git stash list ورودی دوم نشان میدهد، آن سه ثانیه میارزد — stashهایی که «WIP» اسم گرفتهاند بد پیر میشوند.
دو جزئیات کاربردی:
- pathspec بعد از
--میآید. هر چیز بعد از خط تیره دوتایی مسیر است، نه فلگ. همان قراردادgit checkout -- <path>است و تزئینی نیست: در نسخههای قدیمیترgit stash push -- main.pyوgit stash push main.pyفرق داشتند؛ مسیر لخت میتوانست بد خوانده شود. - فایلهای بیردیاب
-uمیخواهند. فایل تازهنفس هیچ تاریخ ردیابیشدهای برای stash کردن ندارد، پسpushساده از آن میگذرد.git stash push -u -- newfile.pyآن را میگیرد؛-aباز هم جلوتر میرود و نادیدهگرفتهها را هم جارو میکند.
چطور فقط بخشی از یک فایل را stash کنم؟
وقتی خود فایل نیمهحاضر است — سه hunk خوب، یک hunk شرمآور — جریان تعاملی آن را ورقه میکند:
git stash -p # یا: git stash push -p Git از هر hunk میگذرد و میپرسد Stash this hunk [y,n,q,a,d,j,g,/,e,p,?]?. برای hunkهایی که به stash میروند y، برای آنهایی که میمانند n. نتیجه stashی است فقط با چیزی که تأیید کردید، و بقیه فایل کثیف در درخت میماند. همان ماشین hunkبهhunk، git add -p را هم میگرداند؛ پس رفلکس مستقیم جابهجا میشود.
git stash push -- <path> | git stash -p | |
|---|---|---|
| دانهبندی | فایل کامل | hunkهای تکی |
| سرعت | یک فرمان، اسکریپتپذیر | تعاملی، hunk به hunk |
| تکرار در CI | بله (مسیرها بهعنوان آرگومان) | خیر — انسان پشت پرامپت لازم است |
| بهترین کاربرد | «این فایل، بقیه نه» | «این تغییر، آن یکی نه» |
| از | git 2.13 (مه ۲۰۱۷) | از مدتها پیش |
قاعده عملی از مدل خود مستندات: اگر مرز، خود فایل است pathspec؛ اگر داخل فایل است -p.
فایل stashشده را چطور پس بگیرم؟
git stash pop بازیابی میکند stash@{0} را و ورودی را پاک میکند. راه معمول — اما pop برای هر stash همه-یا-هیچ است و با تعارض، متوقف میشود و ورودی میماند. دو گزینه ظریفتر:
# ۱. اعمال بدون حذف (بیخطر قابل تکرار)
git stash apply stash@{0}
# ۲. یک فایل را از stash بیرون بکش، ورودی سر جایش بماند
git restore --source stash@{0} -- app.conf
# املا پیش از ۲.۲۳ برای همین کار:
git checkout stash@{0} -- app.conf شکل restore/checkout پاسخ حالت «سه تغییر را با هم stash کردم و حالا فقط یکی لازم است» است — محتوای stashشده آن مسیر را به درخت کاری کپی میکند و stash@{0} سرپا میماند. توجه: نسخه درخت کاری را رونویسی میکند؛ اگر ویرایشهای فعلی روی آن مسیر مهماند، اول diff بگیرید:
git diff stash@{0} -- app.conf stashها روی پشتهای شبیه reflog بهشکل کامیت واقعی ذخیره میشوند — برای همین stash@{0} هر سینتکس commit-ish را میپذیرد، و stashی که بهاشتباه انداخته شده تا نوبت زبالهروبی از reflog برگردانده میشود.
stash کِی ابزار اشتباه است؟
stash دستنویس است، نه شاخه: نامی در git branch ندارد، بازبینی ندارد، diff پیشفرض نشان نمیدهد، و ورودیها بیصدا روی هم تلنبار میشوند تا فراموش شوند. اگر کار در جریان باید از تعویض زمینه بین ماشینها یا روزها جان به در ببرد، روی شاخه کامیتش کنید — تاریخچه همراه بهتر از تلنبار بینام است. وقتی آن کامیتهای پارکشده باید بعداً جای دیگری فرود بیایند، git cherry-pick حملونقل میکند. و اگر هدف پسگرفتن است نه پارک کردن، درخت تصمیمِ خنثیسازی آخرین کامیت حاکم است.
دفتر صادق خرابیها، همه از رفتار مستندشده:
| نشانه | علت | درمان |
|---|---|---|
| فایل بعد از stash غایب است | مسیرهای بیردیاب رد میشوند | git stash push -u -- <path> |
در pop خطای error: Your local changes ... would be overwritten | مسیر بعد از stash عوض شده | وضعیت جدید را کامیت یا stash کن، بعد pop |
| تغییرهای برگشته گم شدند | pop با تعارض متوقف شد | حل کن، بعد git stash apply |
| «کدام stash بود؟» | تلنبار stash بینام | هر بار پیام -m |
یادداشت انتشار مه ۲۰۱۷ که pathspec را به git stash push افزود حالا هشتساله است و بیشتر حافظه عضلانی git stash از آن هم پیرتر. یک بار یادگیری دوباره میارزد: امروز جاروی کل درخت حالت خاص است، نه پیشفرض.
FAQ
در git چطور فقط یک فایل را stash کنم؟
git stash push -m "یادداشت" -- path/to/file — حالت pathspec فقط مسیرهای نامبرده را stash میکند و بقیه فایلهای کثیف را دستنخورده میگذارد. git 2.13 یا جدیدتر لازم است (مه ۲۰۱۷).
چطور یک فایل را از یک stash جدا کنم؟
git restore --source stash@{0} -- path/to/file (یا شکل قدیمیتر git checkout stash@{0} -- path/to/file). نسخه stashشده را به درخت کاری شما کپی میکند بدون آنکه ورودی stash را پاک کند.
چرا git stash فایل جدید من را رد شد؟
فایلهای بیردیاب (untracked) بخشی از stash معمولی نیستند. -u اضافه کنید: git stash push -u -- path/to/file. فایلهای نادیدهگرفتهشده -a میخواهند.
— mrsaynothing
— mrsaynothing
یادداشتهای میدانی درباره AI، لینوکس و self-hosting.
آموزش بعدی با ایمیل
هر نوشته یک ایمیل. درستش کن، برو سراغ بعدی.
این چیست؟یادداشت میدانی از سایت agent-run، #1: ماشین میفرستد، من تأیید میکنم
این نوشتهها را میپسندید؟ این همان کاری است که برای زندگی از آن درمیآورم. استخدامم کنید