git stash: কাজ সাময়িক সরিয়ে রাখা এবং আবার ফিরিয়ে আনা
git stash কমিট-না-করা পরিবর্তনগুলো আলাদা জায়গায় সরিয়ে ওয়ার্কিং ফোল্ডারকে শেষ কমিটের অবস্থায় ফিরিয়ে দেয়, যাতে অন্য কাজে যাওয়া যায়। পরিবর্তন ফিরিয়ে আনতে git stash pop (প্রয়োগ ও তালিকা থেকে মুছে ফেলা) বা git stash apply (প্রয়োগ, কিন্তু রেখে দেওয়া) ব্যবহার করুন; git unstash নামে আলাদা কমান্ড নেই।
git stash কেন দরকার
সাধারণ পরিস্থিতি: কাজের মাঝখানে আছেন, ফাইল বদলেছে, কমিট করার সময় হয়নি — ঠিক তখন অন্য ব্রাঞ্চে একটি জরুরি বাগ ঠিক করতে বলা হলো। ব্রাঞ্চ বদলানো যাচ্ছে না, অথবা বদলানোর আগে পরিবর্তন হারানোর ভয় আছে। git stash সব কমিট-না-করা পরিবর্তন "পকেটে" রেখে দেয় এবং ওয়ার্কিং ফোল্ডারকে শেষ কমিটের অবস্থায় ফিরিয়ে দেয়।
$ git stash
Saved working directory and index state WIP on feature/login: 3f2a1c4 লগইন ফর্ম
$ git status
On branch feature/login
nothing to commit, working tree clean
এখন ব্রাঞ্চ বদলে বাগ ঠিক করে ফিরে এসে সরিয়ে রাখা জিনিস তুলতে পারবেন। প্রতিটি সংরক্ষণ stash স্ট্যাকে একটি এন্ট্রি হয়ে থাকে; Git একে বিশেষ ধরনের কমিট হিসেবে রাখে, তাই ডেটা নিরাপদ এবং কোনো ব্রাঞ্চের ওপর নির্ভর করে না।
পরিবর্তন সংরক্ষণের মূল উপায়
স্পষ্ট বর্ণনাসহ
ডিফল্ট বার্তা "WIP on ব্রাঞ্চ" এক সপ্তাহ পরে কিছুই বোঝায় না। বর্ণনা দিন:
git stash push -m "ফর্ম ভ্যালিডেশন, ই-মেইল এখনো শেষ হয়নি"
আর্গুমেন্ট ছাড়া git stash মানে git stash push। পুরোনো রূপ git stash save "বার্তা" এখনো কাজ করে, তবে নতুন ক্ষেত্রে push -m ব্যবহার করুন।
নতুন ফাইলসহ
ডিফল্টভাবে stash শুধু ট্র্যাক করা ফাইল নেয় — যেগুলো বদলেছে বা ইনডেক্সে যোগ হয়েছে। যে নতুন ফাইল কখনো git add হয়নি, সেগুলো ওয়ার্কিং ফোল্ডারেই থাকে। এটি প্রায়ই বিস্ময়ের কারণ।
git stash -u # --include-untracked: ট্র্যাক না করা ফাইলও
git stash -a # --all: .gitignore-এর ফাইলসহ
-a ব্যবহারে সাবধান: তাতে node_modules, বিল্ড ও লোকাল কনফিগও চলে যাবে। সাধারণত -u-ই যথেষ্ট।
শুধু কিছু পরিবর্তন
git stash push -m "কনফিগ" src/config.js # শুধু নির্দিষ্ট ফাইল
git stash -p # অংশ বেছে নেওয়া, ইন্টারঅ্যাক্টিভভাবে
git stash --staged # শুধু ইনডেক্সে থাকা অংশ (Git 2.35+)
git stash --keep-index # সব সরানো, কিন্তু ইনডেক্স ফোল্ডারে রাখা
--keep-index কমিটের আগে কাজে আসে: শুধু যা কমিট করবেন তা ফোল্ডারে রেখে টেস্ট চালান এবং নিশ্চিত হন যে কমিটটি নিজে নিজে সম্পূর্ণ।
পরিবর্তন ফিরিয়ে আনা
Git-এ git unstash কমান্ড নেই — সরিয়ে রাখা জিনিস খুঁজতে এই নামে অনেকে সার্চ করেন। এর জন্য আছে দুটি কমান্ড।
| কমান্ড | কী করে | স্ট্যাকের এন্ট্রি |
|---|---|---|
git stash pop | শেষ সরিয়ে রাখা পরিবর্তন প্রয়োগ করে | কনফ্লিক্ট ছাড়া প্রয়োগ হলে মুছে যায় |
git stash apply | শেষ সরিয়ে রাখা পরিবর্তন প্রয়োগ করে | থেকে যায় |
git stash pop stash@{2} | নির্দিষ্ট এন্ট্রি প্রয়োগ করে | মুছে যায় |
git stash apply --index | ইনডেক্স ও ওয়ার্কিং ফোল্ডারের বিভাজনও ফিরিয়ে আনে | থেকে যায় |
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: src/auth.js
modified: src/form.js
Dropped refs/stash@{0} (8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)
লক্ষ করুন: ডিফল্টভাবে stash-এর সময় ইনডেক্সে থাকা জিনিসও সাধারণ পরিবর্তন হিসেবে ফিরে আসে। ইনডেক্সের অবস্থা রাখা জরুরি হলে --index যোগ করুন।
pop না apply
প্রতিদিনের কাজে pop সুবিধাজনক: তুলে নিন, আর ভাবতে হয় না। apply বেছে নিন, যখন একই পরিবর্তন একাধিক ব্রাঞ্চে প্রয়োগ করতে চান বা মসৃণভাবে হবে কি না নিশ্চিত নন — এন্ট্রিটি বীমা হিসেবে থাকে, পরে git stash drop দিয়ে মুছলেই চলে।
সরিয়ে রাখা জিনিসের তালিকা
$ git stash list
stash@{0}: On feature/login: ফর্ম ভ্যালিডেশন, ই-মেইল এখনো শেষ হয়নি
stash@{1}: WIP on main: 9b7e0d2 নির্ভরতা আপডেট
stash@{2}: On feature/api: ক্যাশ নিয়ে পরীক্ষা
স্ট্যাক কাজ করে "শেষে রাখা, আগে তোলা" নিয়মে: stash@{0} সবসময় সবচেয়ে নতুন এন্ট্রি, আর প্রতিটি push ও drop-এর পরে নম্বর সরে যায়।
| কমান্ড | উদ্দেশ্য |
|---|---|
git stash show | শেষ এন্ট্রির পরিবর্তনের সংক্ষিপ্ত পরিসংখ্যান |
git stash show -p stash@{1} | নির্দিষ্ট এন্ট্রির সম্পূর্ণ diff |
git stash drop stash@{1} | একটি এন্ট্রি মোছা |
git stash clear | সব এন্ট্রি একবারে মোছা |
git stash branch নাম stash@{0} | যে কমিটে stash করা হয়েছিল সেখান থেকে ব্রাঞ্চ বানিয়ে এন্ট্রি প্রয়োগ ও মুছে ফেলা |
git stash show-এর ডিফল্ট আউটপুট পরিসংখ্যান না দেখিয়ে সম্পূর্ণ diff ও ট্র্যাক-না-করা ফাইল দেখাতে চাইলে stash.showPatch ও stash.showIncludeUntracked সেটিং আছে।
ধাপে ধাপে: কাজের মাঝে জরুরি বাগ
- বর্তমান কাজ নতুন ফাইলসহ সরান:
git stash push -u -m "লগইন: খসড়া"। - মূল ব্রাঞ্চে যান এবং সংশোধনের জন্য ব্রাঞ্চ বানান:
git switch main,git pull,git switch -c hotfix/null-email। - বাগ ঠিক করুন, কমিট করুন, রিভিউয়ে পাঠান।
- কাজে ফিরুন:
git switch feature/login। - পরিবর্তন তুলুন:
git stash pop।git statusদিয়ে দেখুন সব ঠিক আছে কি না।
এই পরিস্থিতিতে অনেকে এখন git worktree ব্যবহার করেন: একই রিপোজিটরির দ্বিতীয় ওয়ার্কিং ফোল্ডার থাকলে কিছুই সরাতে হয় না। কিন্তু পাঁচ মিনিটের জন্য দ্রুত সরে যেতে stash এখনো সহজ।
stash প্রয়োগের সময় কনফ্লিক্ট
stash-এর পর ব্রাঞ্চে যদি একই লাইনগুলো বদলে যায়, প্রয়োগ কনফ্লিক্টে শেষ হবে:
$ git stash pop
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
The stash entry is kept in case you need it again.
এই ক্ষেত্রে এন্ট্রি মুছে যায় না, pop হলেও না। ফাইলের কনফ্লিক্ট সাধারণভাবে মিটিয়ে git add দিয়ে সমাধান চিহ্নিত করুন (অথবা ইনডেক্সে রাখতে না চাইলে git restore --staged), তারপর অপ্রয়োজনীয় হয়ে যাওয়া এন্ট্রিটি git stash drop দিয়ে মুছুন।
কনফ্লিক্ট জটিল হলে সহজ পথ: git stash branch tmp-login। Git যে কমিটে stash করা হয়েছিল সেখান থেকে ব্রাঞ্চ বানায় — সেখানে পরিবর্তন কনফ্লিক্ট ছাড়া প্রয়োগ হয়, আর মূল ব্রাঞ্চের সঙ্গে পরে সাধারণ merge করে নেওয়া যায়।
মুছে যাওয়া stash ফেরানো
ভুল করে git stash drop বা clear দিলেও সবকিছু হারায় না। এন্ট্রিটি একটি কমিট ছিল, এবং আবর্জনা সংগ্রাহক মোছার আগ পর্যন্ত সেটি "ঝুলন্ত" অবজেক্ট হিসেবে খুঁজে পাওয়া যায়:
git fsck --no-reflog | grep "dangling commit"
git show 8c1d2e3 # যাচাই করুন, এটিই সেই stash কি না
git stash apply 8c1d2e3
একটু আগে drop বা pop করে থাকলে হ্যাশটি কমান্ডের আউটপুটেই আছে — Dropped refs/stash@{0} (...) লাইনে। সেটি সরাসরি git stash apply-এ দিন।
stash ভেতরে কীভাবে কাজ করে
কাঠামো জানলে ডেটা হারানোর ভয় কমে। প্রতিটি stash এন্ট্রি একটি সাধারণ কমিট, যাকে refs/stash রেফারেন্স নির্দেশ করে। এর দুটি প্যারেন্ট: যে HEAD কমিটে আপনি ছিলেন, এবং ইনডেক্সের অবস্থার আলাদা একটি কমিট। -u ব্যবহার করলে তৃতীয় প্যারেন্ট যোগ হয়, যেখানে ট্র্যাক-না-করা ফাইল থাকে। stash@{N} তালিকা আসলে refs/stash রেফারেন্সের জার্নাল (reflog)।
এর কয়েকটি ব্যবহারিক ফল আছে। যেকোনো কমিট-গ্রহণকারী কমান্ডে stash দেওয়া যায়: git diff stash@{0}, git show stash@{0}:src/auth.js (এন্ট্রির একটি ফাইলের কনটেন্ট), অথবা git checkout stash@{0} -- src/auth.js — পুরো এন্ট্রি প্রয়োগ না করে একটি ফাইল তুলতে। মুছে যাওয়া এন্ট্রিও আবর্জনা সংগ্রহের আগ পর্যন্ত অবজেক্ট ডেটাবেসে থাকে।
stash এবং অন্যান্য Git কমান্ড
কিছু কমান্ড নিজেরাই পরিবর্তন সরিয়ে নিতে পারে। git rebase --autostash ও git pull --rebase --autostash শুরুর আগে কমিট-না-করা পরিবর্তন সরায় এবং শেষে ফিরিয়ে আনে। এটি স্থায়ী করতে rebase.autoStash true ও merge.autoStash true সেটিং দিন। ফেরানোর সময় কনফ্লিক্ট হলে Git এন্ট্রিটি সাধারণ stash স্ট্যাকে রেখে দেয় এবং জানিয়ে দেয়।
git switch দিয়ে ব্রাঞ্চ বদলাতেও সবসময় stash লাগে না: আপনার পরিবর্তন যদি ব্রাঞ্চ-ভেদে আলাদা ফাইল না ছোঁয়, Git সেগুলো সঙ্গে নিয়ে যায়। stash লাগে যখন Git বলে "Your local changes would be overwritten by checkout", অথবা পরিবর্তনগুলো অন্য ব্রাঞ্চে নিতে চান না।
সাধারণ ভুল
- নতুন ফাইল সরেনি। সেগুলো ট্র্যাক হয় না,
-uলাগবে। - stash-কে দীর্ঘমেয়াদি গুদাম বানানো। এক মাস পরে তালিকায় দশটি নামহীন "WIP on main", কেউ জানে না কী আছে। দীর্ঘ কাজের জন্য আলাদা ব্রাঞ্চে কমিট করুন — অন্তত সেটি push করা যায়।
- কনফ্লিক্টের পরে এন্ট্রি থেকে যাওয়ার কথা ভুলে যাওয়া, এবং পরে আবার প্রয়োগ করা। কনফ্লিক্ট মেটানোর পর সবসময়
dropকরুন। - stash সার্ভারের সঙ্গে মেলে না। এটি শুধু আপনার লোকাল রিপোজিটরিতে থাকে,
git pushএটি পাঠায় না। প্রজেক্ট ফোল্ডার মুছে গেলে stash-ও যাবে। - ভুল এন্ট্রি প্রয়োগ।
pop-এর আগেgit stash listওgit stash show -pদেখে নিন।
সারসংক্ষেপ
git stash দ্রুত রাস্তা, যাতে কমিট-না-করা কাজ না হারিয়ে ওয়ার্কিং ফোল্ডার খালি করা যায়: সরাতে git stash push -u -m "বর্ণনা", ফেরাতে git stash pop। বীমা চাইলে apply ব্যবহার করুন, গোলমাল এড়াতে git stash list ও show -p দেখুন, আর stash-কে গুদাম বানাবেন না — দীর্ঘ কাজের জন্য আছে কমিট ও ব্রাঞ্চ। কাজের মাঝে সরে যাওয়ার কৌশল কোর্সে হাতেকলমে অনুশীলন করা হয়।
সাধারণ প্রশ্ন
stash কি অন্য ব্রাঞ্চে প্রয়োগ করা যায়?
হ্যাঁ, stash কোনো ব্রাঞ্চের সঙ্গে বাঁধা নয়: কাঙ্ক্ষিত ব্রাঞ্চে গিয়ে git stash pop বা apply চালান। পরিবর্তনগুলো না মিললে সাধারণ কনফ্লিক্ট দেখা দেবে।
git stash কি ইনডেক্সের অবস্থা সংরক্ষণ করে?
করে, কিন্তু সাধারণ pop বা apply-এ সব অ-স্টেজ পরিবর্তন হিসেবে ফিরে আসে। ইনডেক্সসহ ফেরাতে git stash apply --index ব্যবহার করুন।
stash-এ কয়টি এন্ট্রি রাখা যায়?
কোনো কঠোর সীমা নেই, তবে reflog-এর মেয়াদ পেরোনো এন্ট্রি আবর্জনা সংগ্রহে মুছে যেতে পারে। বাস্তবে স্ট্যাকে কয়েকটি তাজা এন্ট্রিই রাখুন।
শুধু একটি ফাইল কীভাবে stash করব?
দুই ড্যাশের পরে পাথ দিন বা push-এর সঙ্গে দিন: git stash push -m বর্ণনা -- src/config.js। stash-এ শুধু ওই ফাইল যাবে, বাকি পরিবর্তন ফোল্ডারেই থাকবে।
stash আর অস্থায়ী কমিটের পার্থক্য কী?
কমিট একটি ব্রাঞ্চে থাকে, সার্ভারে পাঠানো যায় এবং পরে amend বা rebase করা যায়। stash শুধু লোকালভাবে আলাদা স্ট্যাকে থাকে এবং সংক্ষিপ্ত সরে যাওয়ার জন্য উপযোগী।
“শূন্য থেকে আত্মবিশ্বাসী ডেভেলপার পর্যন্ত গিট” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
কোর্সে যান