git stash: کار نیمهتمام را کنار بگذارید بدون commit الکی
git stash برای کنار گذاشتن تغییرات کثیف working tree، list/show/pop/apply، include-untracked و اشتباههای رایج stash در تیم.
بنیانگذار و مهندس محصول

وسط یک ویژگی هستید، working tree پر از تغییر است، و همزمان باید شاخه را عوض کنید، یک باگ فوری را درست کنید، یا pull بگیرید. Git اجازهٔ switch/checkout روی درخت کثیف را در بسیاری حالات نمیدهد یا میترسد کارتان را خراب کند. اینجا وسوسهٔ «یک commit موقت با پیام WIP» قوی است — اما تاریخچه را شلوغ میکند و بعداً باید با reset/amend جمعش کنید.
git stash دقیقاً برای همین سناریو طراحی شده: وضعیت فعلی working directory و index را ضبط میکند، درخت را به وضعیت HEAD برمیگرداند، و بعداً همان تغییرات را برمیگرداند. طبق مستندات رسمی git-scm، فراخوانی بدون آرگومان معادل stash push است.

پاسخ کوتاه
برای کنار گذاشتن کار نیمهتمام: `git stash push -m "پیام کوتاه"`. برای دیدن فهرست: `git stash list`. برای بازگردانی و حذف از پشته: `git stash pop`. برای بازگردانی بدون حذف: `git stash apply`. فایلهای untracked بهصورت پیشفرض داخل stash نمیروند؛ اگر لازم است `-u` بزنید. stash جایگزین شاخهٔ واقعی برای کار طولانی نیست.
stash صندوق امانات محلی است، نه شاخهٔ مشترک تیم.
مشکلی که stash حل میکند
سه موقعیت کلاسیک:
- Pull/rebase روی درخت کثیف شکست میخورد یا خطرناک است.
- باید سریع به شاخهٔ دیگری بروید و تغییرات فعلی هنوز قابل commit نیستند.
- میخواهید قبل از تست یک تکهٔ staged، بقیهٔ تغییرات را موقتاً کنار بگذارید (keep-index).
در هر سه مورد، هدف «تمیز کردن موقت» است نه ثبت دائمی در تاریخچهٔ شاخه.
stash از نگاه مفهومی
طبق مستندات git-stash، هر ورودی stash در عمل یک commit مخصوص است: درخت working tree را نگه میدارد، والد اول همان HEAD لحظهٔ stash است، و والد دوم وضعیت index را ثبت میکند. به همین دلیل دستورهایی مثل show و apply روی آن معنا دارند. جدیدترین ورودی در refs/stash است و قدیمیترها در reflog همان مرجع دیده میشوند: stash@{0}، stash@{1} و غیره.
bash
git status git stash push -m "wip: form validation" git status git stash list
دستورهای روزمره
ساخت stash
bash
git stash git stash push -m "در حال بازنویسی سرویس پرداخت" git stash push -u -m "شامل فایلهای جدید untracked" git stash push -- path/to/file.js
پیام توصیفی بعداً در list نجاتتان میدهد. pathspec فقط همان فایلها را stash میکند و بقیه را دستنخورده میگذارد — مفید وقتی فقط یک پوشه مزاحم switch است.
مشاهده
bash
git stash list git stash show git stash show -p stash@{0} git stash show -u stash@{0}
بدون -p معمولاً diffstat میبینید؛ با -p پچ کامل. اگر untracked را با -u ذخیره کرده بودید، برای دیدنش در show هم گزینههای مربوط به untracked را بدانید.
بازگردانی: pop در برابر apply
bash
git stash pop git stash apply stash@{1} git stash drop stash@{1}
pop اعمال میکند و در صورت موفقیت از لیست برمیدارد. apply اعمال میکند و نگه میدارد — وقتی میخواهید همان تغییرات را روی چند شاخه امتحان کنید یا قبل از drop مطمئن شوید، امنتر است. اگر conflict رخ دهد، pop ورودی را حذف نمیکند؛ باید تعارض را حل کنید و بعد drop دستی بزنید.
شاخه از روی stash
bash
git stash branch recovery-feature stash@{0}
مستندات رسمی این الگو را وقتی توصیه میکنند که شاخهٔ اصلی آنقدر جلو رفته که apply پر از conflict میشود: شاخهٔ جدید از همان commit پایهٔ stash ساخته میشود و تغییرات روی آن اعمال میشوند؛ معمولاً بدون همان تعارضهای بیمورد.
گزینههای مهم
| گزینه | معنا | چه وقت |
|---|---|---|
| -u / --include-untracked | فایلهای جدید را هم stash و پاک میکند | فایل تازه هنوز add نشده |
| -a / --all | حتی ignored را هم میگیرد | نادر؛ مراقب فایلهای محلی حساس |
| -k / --keep-index | staged را در درخت نگه میدارد | تست commit جزئی |
| -S / --staged | فقط staged را stash میکند | جدا کردن کار نامرتبط |
| -p / --patch | انتخاب تعاملی hunk | جداسازی دقیق |
| --index روی apply/pop | تلاش برای بازسازی index | وقتی staging مهم است |
مثال عملی: باگ فوری وسط ویژگی
bash
# وسط کار روی feature/login git stash push -u -m "wip login form" git switch main git pull git switch -c hotfix/null-crash # ... اصلاح و commit و PR ... git switch feature/login git stash pop
اگر pop conflict داد، فایلها را حل کنید، سپس در صورت نیاز `git stash drop` را دستی بزنید تا ورودی تکراری نماند.
مثال: تست یک بخش staged
bash
git add -p git stash push --keep-index -m "بقیه تغییرات" # تست همان بخش staged git commit -m "feat: validate email" git stash pop
این الگو از مستندات رسمی برای شکستن تغییرات بزرگ به چند commit قابلتست آمده است.
چه وقت stash نکنید
- کار چندروزه یا چندنفره: شاخه بسازید و commitهای کوچک بزنید.
- تغییراتی که باید روی remote پشتیبان شوند: stash بهصورت پیشفرض فقط محلی است (مگر export/import پیشرفته).
- بهجای .gitignore برای مخفی کردن secret: stash امنیتی نیست.
- وقتی نمیدانید چه چیزی stash شده: اول show، بعد apply.
اشتباههای رایج
- فراموش -u و تعجب از باقیماندن فایلهای جدید.
- انباشت دهها stash بدون پیام؛ بعد از دو هفته هیچکس نمیفهمد stash@{7} چیست.
- pop روی شاخهٔ اشتباه و ایجاد conflict درهم.
- فرض اینکه clear قابل برگشت آسان است؛ clear ورودیها را در معرض prune میگذارد.
- stash کردن فایلهایی که نباید commit شوند و بعد add کردن بیدقت همانها.
اگر اشتباهی drop/clear کردید، مستندات یک مسیر بازیابی مبتنی بر `git fsck --unreachable` و جستوجوی commitهای merge با پیام WIP پیشنهاد میکند — قطعی نیست، پس به آن تکیهٔ روزمره نکنید.
stash و همکاری تیمی
همکار شما stash شما را روی ماشین خودش نمیبیند. برای اشتراک کار نیمهتمام، شاخهٔ remote یا draft PR مناسبتر است. اگر ابزار یا اسکریپت نیاز به جابهجایی stash بین کلونها دارد، زیرکمانهای export/import در نسخههای جدیدتر git-stash وجود دارند؛ برای اکثر تیمها شاخه کافی است.
مقایسه با commit موقت WIP
| روش | مزیت | عیب |
|---|---|---|
| stash | تاریخچهٔ شاخه تمیز میماند | محلی؛ فراموشی آسان |
| commit WIP روی همان شاخه | با push پشتیبان میشود | تاریخچه کثیف؛ نیاز به amend/reset |
| شاخهٔ wip جدا | شفاف و قابل اشتراک | مدیریت شاخهٔ اضافه |
چکلیست قبل از stash
- status را بخوانید؛ بدانید untracked دارید یا نه.
- پیام معنادار بگذارید.
- اگر secret در working tree است، stash را جایگزین پاکسازی ندانید.
- بعد از اتمام کار فوری، همان روز pop/apply کنید نه «هفتهٔ بعد».
- ورودیهای کهنه را drop کنید.
خلاصه
git stash ابزار جابهجایی سریع بین کارهای ناتمام و کارهای فوری است: درخت را تمیز میکند بدون اینکه تاریخچهٔ شاخه را با WIP پر کند. قدرت واقعیاش در پیام خوب، دانستن -u، تفاوت pop/apply، و شاخهٔ بازیابی است. برای کار پایدار و مشترک، هنوز شاخه و commit کوچک برنده است.
سوالات متداول
چرا بعد از stash هنوز فایلهای جدید ماندهاند؟
چون untracked پیشفرض ذخیره نمیشود. `git stash push -u` را استفاده کنید.
تفاوت stash و commit چیست؟
commit نقطهٔ تاریخچهٔ شاخه است و معمولاً با دیگران بهاشتراک گذاشته میشود؛ stash پشتهٔ محلی برای بازیابی موقت است.
آیا stash روی remote میرود؟
با push معمولی خیر. برای اشتراک، شاخه بسازید یا از سازوکار export آگاهانه استفاده کنید.
pop تعارض داد؛ حالا چه؟
تعارض را حل و تغییرات را نهایی کنید؛ سپس در صورت باقیماندن ورودی، drop بزنید.
منابع و مراجع
- Git — git-stash Documentation: https://git-scm.com/docs/git-stash
- Git — git-status: https://git-scm.com/docs/git-status
- Git — gitglossary (working tree / index): https://git-scm.com/docs/gitglossary
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




