git cherry-pick: একটি নির্দিষ্ট কমিট অন্য ব্রাঞ্চে কীভাবে নেবেন
git cherry-pick একটি নির্দিষ্ট কমিটের পরিবর্তন নিয়ে বর্তমান ব্রাঞ্চে একটি নতুন কমিট বানায়, যার ডিফ ও বার্তা একই কিন্তু হ্যাশ ভিন্ন। লক্ষ্য ব্রাঞ্চে যান এবং git cherry-pick হ্যাশ চালান; কনফ্লিক্ট হলে ফাইল ঠিক করে git add ও git cherry-pick --continue দিন।
git cherry-pick একটি নির্দিষ্ট কমিটের পরিবর্তন বর্তমান ব্রাঞ্চে আনে, পুরো ব্রাঞ্চ merge না করেই। Git নির্বাচিত কমিটের ডিফ তার প্যারেন্টের তুলনায় হিসাব করে, সেটি আপনার HEAD-এ প্রয়োগ করে এবং একটি নতুন কমিট বানায়: একই বার্তা ও লেখক, কিন্তু ভিন্ন হ্যাশ, কারণ প্যারেন্ট ভিন্ন।
সাধারণ পরিস্থিতি: একটি feature ব্রাঞ্চে আপনি বাগ ঠিক করেছেন, আর সেই ঠিকটি জরুরিভাবে রিলিজ ব্রাঞ্চে দরকার, যেখানে feature এখনো প্রস্তুত নয়। পুরো ব্রাঞ্চ merge করা যাবে না, কিন্তু একটি কমিট নেওয়া যাবে।
একটি কমিট অন্য ব্রাঞ্চে কীভাবে নেবেন
প্রথমে প্রয়োজনীয় কমিটের হ্যাশ খুঁজুন, তারপর যে ব্রাঞ্চে নিতে চান সেখানে যান এবং cherry-pick চালান।
# ১. feature ব্রাঞ্চে কমিট খুঁজুন
git log --oneline feature
a1b2c3d ছাড়ের হিসাবে শূন্য দিয়ে ভাগের সমস্যা ঠিক করা
9f8e7d6 নতুন পেমেন্ট স্ক্রিন যোগ করা
# ২. লক্ষ্য ব্রাঞ্চে যান
git switch release-1.4
# ৩. কমিট নিন
git cherry-pick a1b2c3d
[release-1.4 4e5f6a7] ছাড়ের হিসাবে শূন্য দিয়ে ভাগের সমস্যা ঠিক করা
Date: Mon Oct 5 14:12:03 2026 +0300
1 file changed, 3 insertions(+), 1 deletion(-)
লক্ষ্য করুন: নতুন কমিট পেয়েছে 4e5f6a7 হ্যাশ, a1b2c3d নয়। এরা দুটি ভিন্ন অবজেক্ট, কিন্তু পরিবর্তন একই। মূল ব্রাঞ্চ feature বদলায় না।
হ্যাশের বদলে কমিটের যেকোনো রেফারেন্সও দেওয়া যায়: git cherry-pick feature ব্রাঞ্চের শেষ কমিট নেবে, git cherry-pick feature~2 শেষ থেকে তৃতীয়টি।
একাধিক কমিট নেওয়া
তালিকা দিয়ে
হ্যাশগুলো তালিকা করে দেওয়া যায়; Git সেগুলো দেওয়া ক্রমে প্রয়োগ করে এবং ততগুলো নতুন কমিট বানায়।
git cherry-pick a1b2c3d 7c8d9e0 3f4a5b6
ক্রম গুরুত্বপূর্ণ: দ্বিতীয় কমিট প্রথমটির ওপর নির্ভর করলে এবং আপনি উল্টো ক্রমে দিলে কনফ্লিক্ট বা ভাঙা কোড আসবে। পুরনো থেকে নতুনের দিকে দেওয়াই নিরাপদ।
রেঞ্জ দিয়ে
পরপর আসা কমিটের জন্য রেঞ্জ সিনট্যাক্স আছে। এখানে একটি ফাঁদ আছে, যাতে প্রায় সবাই পড়ে: A..B মানে "B থেকে পৌঁছানো যায় কিন্তু A থেকে নয়" এমন কমিটগুলো, অর্থাৎ A নিজে রেঞ্জে থাকে না।
# A-এর পরের কমিট থেকে B পর্যন্ত (B সহ) নেবে
git cherry-pick A..B
# A সহ এবং B পর্যন্ত সব নেবে
git cherry-pick A^..B
feature-এ যা আছে কিন্তু main-এ নেই সব নিতে git cherry-pick main..feature লেখা সুবিধাজনক। তবে কমিট অনেক হলে ভাবুন: হয়তো আপনার rebase বা merge দরকার, cherry-pick নয়।
git cherry-pick-এর কয়েকটি ফ্ল্যাগ
| ফ্ল্যাগ | কী করে | কখন দরকার |
|---|---|---|
-x | বার্তায় "(cherry picked from commit …)" লাইন যোগ করে | প্রকাশ্য ব্রাঞ্চের মধ্যে ঠিক স্থানান্তরে — উৎস বোঝা যায় |
-n, --no-commit | পরিবর্তন ইনডেক্স ও ওয়ার্কিং ফোল্ডারে দেয়, কমিট করে না | কয়েকটি কমিট একটিতে মেলাতে, বা কমিটের আগে ঠিক করতে |
-e, --edit | বার্তা বদলানোর জন্য এডিটর খোলে | লক্ষ্য ব্রাঞ্চের জন্য বার্তা মানানসই করতে |
-s, --signoff | Signed-off-by লাইন যোগ করে | DCO প্রয়োজন এমন প্রকল্পে |
-m 1 | merge কমিটের "মূল" প্যারেন্ট নির্দিষ্ট করে | merge কমিট স্থানান্তরে |
--ff | HEAD যদি নির্বাচিত কমিটের প্যারেন্ট হয়, ব্রাঞ্চ সামনে নেয় | বিরল; অনুলিপি তৈরি এড়াতে |
--allow-empty | শুরুতেই খালি কমিট স্থানান্তরের অনুমতি দেয় | সেবামূলক খালি কমিট |
-x কেন দরকার
ছয় মাস পরে কেউ রিলিজ ব্রাঞ্চে একটি সংশোধন দেখবে এবং জানতে চাইবে সেটি কোথা থেকে এল। -x যোগ করা লাইনটি সরাসরি উত্তর দেয়:
git cherry-pick -x a1b2c3d
git log -1
ছাড়ের হিসাবে শূন্য দিয়ে ভাগের সমস্যা ঠিক করা
(cherry picked from commit a1b2c3d4e5f60718293a4b5c6d7e8f9012345678)
উৎস কমিট যদি ইতিমধ্যে প্রকাশ্য হয়, তখন -x ব্যবহার করুন। নিজের লোকাল ব্রাঞ্চ থেকে নেওয়া হলে, যা পরে মুছবেন, তখন লিংক কোথাও যাবে না, তাই ফ্ল্যাগের দরকার নেই।
কয়েকটি কমিট একটিতে মেলানো: -n
git cherry-pick -n a1b2c3d 7c8d9e0
git status # দুই কমিটের পরিবর্তন ইনডেক্সে
git commit -m "ছাড়ের হিসাবের সংশোধনগুলো"
cherry-pick-এ কনফ্লিক্ট এবং তা মেটানো
কনফ্লিক্ট ঘটে, যখন কমিটের পরিবর্তন বর্তমান কোডে বসে না: লক্ষ্য ব্রাঞ্চে একই লাইনগুলো ইতিমধ্যে অন্যভাবে আছে। Git থামে এবং জানায়।
git cherry-pick a1b2c3d
Auto-merging src/discount.js
CONFLICT (content): Merge conflict in src/discount.js
error: could not apply a1b2c3d... ছাড়ের হিসাবে শূন্য দিয়ে ভাগের সমস্যা ঠিক করা
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
এরপর তিনটি পথ:
- মেটান ও চালিয়ে যান। ফাইল খুলুন,
<<<<<<<,=======,>>>>>>>চিহ্নগুলো সরান, সঠিক রূপটি রাখুন, তারপরgit add src/discount.jsওgit cherry-pick --continue। - কমিটটি বাদ দিন। তালিকার সময়
git cherry-pick --skipসমস্যাজনক কমিট বাদ দিয়ে পরেরটিতে যায়। - সব বাতিল করুন।
git cherry-pick --abortব্রাঞ্চকে অপারেশন শুরুর আগের অবস্থায় ফেরায়।
আরও আছে git cherry-pick --quit: এটি অপারেশন থামায়, কিন্তু ইতিমধ্যে প্রয়োগ হওয়া কমিটগুলো এবং ফাইলের বর্তমান অবস্থা রেখে দেয়। তালিকার অর্ধেক সফলভাবে নিয়ে বাকিটা হাতে করতে চাইলে কাজে লাগে।
একই কনফ্লিক্ট বারবার এলে (যেমন কয়েকটি রিলিজ ব্রাঞ্চে নিয়মিত সংশোধন নিলে) git config rerere.enabled true চালান: Git মনে রাখবে আপনি কীভাবে কনফ্লিক্ট মিটিয়েছেন, এবং পরের বার নিজেই একই সমাধান দেবে।
merge কমিট স্থানান্তর
merge কমিটের দুটি প্যারেন্ট থাকে, আর Git জানে না কোনটির তুলনায় ডিফ হিসাব করবে। ইঙ্গিত না দিলে ত্রুটি আসে:
git cherry-pick 5d6e7f8
error: commit 5d6e7f8 is a merge but no -m option was given.
-m 1 বলে: প্রথম প্যারেন্টের তুলনায় পরিবর্তন হিসাব করো। সাধারণত সেটি সেই ব্রাঞ্চ, যেখানে মেশানো হয়েছিল। এতে মেশানো শাখার সব পরিবর্তন একটি কমিটে আসবে।
git cherry-pick -m 1 5d6e7f8
মনে রাখবেন, এরপর Git ব্রাঞ্চটিকে মেশানো বলে গণ্য করবে না: ভবিষ্যতে merge করলে একই পরিবর্তন আবার প্রয়োগের চেষ্টা করতে পারে।
git cherry-pick ও git apply: পার্থক্য
git apply প্রায়ই cherry-pick-এর পাশে মনে পড়ে, কারণ দুটিই "পরিবর্তন প্রয়োগ" করে। কিন্তু তারা ভিন্ন ইনপুটে কাজ করে।
| git cherry-pick | git apply | |
|---|---|---|
| উৎস | রিপোজিটরিতে থাকা কমিট | প্যাচ ফাইল (ডিফ) |
| কমিট বানায় | হ্যাঁ (-n ছাড়া) | না, শুধু ফাইল বদলায় (--index দিলে ইনডেক্সও) |
| লেখক ও বার্তা রাখে | হ্যাঁ | না, প্যাচে থাকে না |
| কনফ্লিক্ট | মার্কারসহ তিন-পক্ষীয় merge | ডিফল্টে শুধু বাতিল; --3way দিলে মার্কার |
| একই রিপোজিটরি লাগে | হ্যাঁ, কমিট লোকালি থাকতে হবে | না, প্যাচ যেকোনো উপায়ে পাঠানো যায় |
git apply-এর উদাহরণ, যখন কমিট আপনার রিপোজিটরিতে নেই, কিন্তু সহকর্মী ফাইলে ডিফ পাঠিয়েছেন:
# সহকর্মী করেন
git diff main..fix-discount > fix.patch
# আপনি যাচাই ও প্রয়োগ করেন
git apply --check fix.patch # প্যাচ বসবে কি না দেখা
git apply fix.patch # ওয়ার্কিং ফোল্ডারে প্রয়োগ
git apply --3way fix.patch # গরমিল হলে কনফ্লিক্ট মার্কারসহ
লেখক ও বার্তাসহ পুরো কমিট পাঠাতে চাইলে git format-patch ও git am জোড়াটি ব্যবহার করুন: প্রথমটি কমিটগুলো ফাইলে রাখে, দ্বিতীয়টি সেগুলো থেকে কমিট বানায়। অর্থাৎ এটি "ইমেইলে cherry-pick"।
অন্য রিপোজিটরি থেকেও cherry-pick সম্ভব: সেটিকে remote হিসেবে যোগ করুন, git fetch চালান, তারপর কমিটগুলো হ্যাশ দিয়ে পাওয়া যাবে।
কখন cherry-pick ভালো নয়
cherry-pick ডুপ্লিকেট তৈরি করে: একই পরিবর্তন ইতিহাসে দুটি হ্যাশের অধীনে থাকে। অল্প মাত্রায় এটি স্বাভাবিক, তবে কিছু পরিস্থিতিতে ক্ষতিকর।
- কয়েক ডজন কমিট স্থানান্তর। প্রায় পুরো ব্রাঞ্চ নিলে এটি rebase বা merge-এর কাজ। cherry-pick দীর্ঘ ডুপ্লিকেট ইতিহাস ও বেশি কনফ্লিক্ট দেবে।
- দুই দিকে স্থানান্তর। একটি কমিট feature থেকে main-এ নেওয়া হলো, তারপর feature main-এ merge হলো। Git সাধারণত সামলায় (পরিবর্তন মিলে যায়), কিন্তু পরে লাইন বদলে থাকলে অকারণ কনফ্লিক্ট আসবে।
- নির্ভরশীল কমিট। একটি কমিট দুটি আগের কমিটে যোগ হওয়া ফাংশন ব্যবহার করে। cherry-pick শুধু সেই একটি কমিট নেবে, লক্ষ্য ব্রাঞ্চে কোড বিল্ড হবে না। স্থানান্তরের পর সবসময় বিল্ড ও টেস্ট চালান।
হটফিক্সের ভালো চর্চা: সংশোধন সবচেয়ে পুরনো সমর্থিত ব্রাঞ্চে করুন, তারপর নতুনগুলোতে "উপরের দিকে" merge করুন। তখন cherry-pick শুধু ব্যতিক্রম হিসেবে লাগে।
cherry-pick বাতিল করা
অপারেশন এখনো চললে (কনফ্লিক্ট অবস্থায়) — git cherry-pick --abort। কমিট তৈরি হয়ে গেছে কিন্তু সার্ভারে যায়নি, তাহলে সরান:
git reset --hard HEAD~1
কমিট যদি ইতিমধ্যে শেয়ার্ড ব্রাঞ্চে push হয়ে গিয়ে থাকে, তাহলে ইতিহাস লেখা যাবে না, উল্টো একটি কমিট বানান:
git revert 4e5f6a7
আর reset করে মত বদলালে হারানো কমিট git reflog-এ পাওয়া যায়।
কমিট আগেই স্থানান্তরিত হয়েছে কি না যাচাই
হ্যাশ ভিন্ন বলে সাধারণ git branch --contains সাহায্য করে না। Git পরিবর্তনের বিষয়বস্তু (patch-id) দিয়ে কমিট তুলনা করতে পারে:
git cherry -v release-1.4 feature
- a1b2c3d ছাড়ের হিসাবে শূন্য দিয়ে ভাগের সমস্যা ঠিক করা
+ 9f8e7d6 নতুন পেমেন্ট স্ক্রিন যোগ করা
বিয়োগ চিহ্ন মানে release-1.4-এ সমতুল্য পরিবর্তন আছে, যোগ চিহ্ন মানে নেই। বিকল্প: git log --cherry-pick --oneline release-1.4...feature, যা যমজ কমিটগুলো লুকায়। -x ব্যবহার করে থাকলে বার্তায় খুঁজতে পারেন: git log --grep="cherry picked from commit a1b2c3d"।
সারসংক্ষেপ
git cherry-pick একটি সূক্ষ্ম সরঞ্জাম: রিলিজে হটফিক্স নেওয়া, পরিত্যক্ত ব্রাঞ্চ থেকে কাজের কমিট তোলা, ভুল ব্রাঞ্চে করা কমিট ঠিক জায়গায় আনা। তিনটি কথা মনে রাখুন: নতুন কমিটের হ্যাশ নতুন হয়, A..B রেঞ্জে A থাকে না, এবং প্রকাশ্য ব্রাঞ্চে -x যোগ করুন। কমিট নয়, ফাইলের ডিফ নিতে হলে git apply। Rebase, stash, cherry-pick ও ট্যাগ Git কোর্সে বাস্তব উদাহরণে বিস্তারিত শেখানো হয়।
সাধারণ প্রশ্ন
cherry-pick কি উৎস ব্রাঞ্চ বদলায়?
না। মূল কমিট যেখানে ছিল সেখানেই থাকে, এবং বর্তমান ব্রাঞ্চে নতুন হ্যাশসহ তার একটি কপি আসে।
রিমোট ব্রাঞ্চের কমিট কি cherry-pick করা যায়?
হ্যাঁ। git fetch চালান, তারপর কমিটটি হ্যাশ দিয়ে বা origin/ব্রাঞ্চ-নাম দিয়ে পাওয়া যাবে এবং git cherry-pick-এ দেওয়া যাবে।
cherry-pick-এর পর কমিটের হ্যাশ কেন ভিন্ন?
হ্যাশ প্যারেন্ট, কমিটের সময় ও ট্রির বিষয়বস্তুর ওপর নির্ভর করে। কপির প্যারেন্ট আলাদা এবং কমিটারের সময়ও আলাদা, তাই হ্যাশও আলাদা।
cherry-pick-এ কি মূল লেখক থাকে?
হ্যাঁ, লেখক ও লেখার তারিখ মূল কমিট থেকে আসে, আর কমিটার হন আপনি বর্তমান সময়ে।
cherry-pick বলছে কমিট খালি, কী করব?
এর মানে এই পরিবর্তন ব্রাঞ্চে আগে থেকেই আছে। git cherry-pick --skip দিয়ে বাদ দিন, অথবা git commit --allow-empty দিয়ে খালি কমিট হিসেবে রাখুন।
“শূন্য থেকে আত্মবিশ্বাসী ডেভেলপার পর্যন্ত গিট” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
কোর্সে যান