বেশিরভাগ পূর্ববর্তী উত্তরগুলি বিপজ্জনকভাবে ভুল!
এটা করো না:
git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch
পরের বার হিসাবে আপনি চালিত git rebase(বা git pull --rebase) সেই 3 টি কমিট চুপচাপ বাদ দেওয়া হবে newbranch! (নীচে ব্যাখ্যা দেখুন)
পরিবর্তে এটি করুন:
git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
- প্রথমে এটি 3 অতি সাম্প্রতিক কমিটগুলি বাদ দেয় (
--keepপছন্দ মতো --hardতবে নিরাপদ, যেমন আপত্তিজনক পরিবর্তনগুলি ছুঁড়ে ফেলার পরিবর্তে ব্যর্থ হয়)।
- তারপর এটি কাঁটাচামচ বন্ধ
newbranch।
- তারপরে এটি চেরি-পিকগুলি সেই 3 টি প্রতিশ্রুতি ফিরে আসে
newbranch। যেহেতু সেগুলি আর কোনও শাখার দ্বারা রেফারেন্স করা হয় না, এটি গিটের রিফ্লোগ ব্যবহার করে : HEAD@{2}এটি প্রতিশ্রুতি যা HEAD2 ক্রিয়াকলাপ আগে উল্লেখ করা হয়েছিল, অর্থাৎ আমরা আগে 1. পরীক্ষা করে দেখেছিnewbranch এবং ২ git resetটি কমিট বাতিল করার জন্য ব্যবহৃত হয়েছিল।
সতর্কতা: রিফ্লোগটি ডিফল্টরূপে সক্ষম করা হয়েছে, তবে আপনি যদি ম্যানুয়ালি এটিকে অক্ষম করে থাকেন (যেমন "বেয়ার" গিট সংগ্রহস্থল ব্যবহার করে), আপনি চালানোর পরে 3 টি প্রত্যাবর্তন ফিরে পেতে সক্ষম হবেন না git reset --keep HEAD~3।
এমন একটি বিকল্প যা রিফ্লগের উপর নির্ভর করে না:
# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3
(যদি আপনি পছন্দ করেন তবে লিখতে পারেন @{-1}- পূর্বে চেক আউট শাখা - পরিবর্তে oldbranch)
প্রযুক্তিগত ব্যাখ্যা
কেন git rebaseপ্রথম উদাহরণের পরে 3 টি কমিট বাতিল করবেন ? এটি কারণ git rebaseকোনও যুক্তি ছাড়াই --fork-pointডিফল্টরূপে বিকল্পটি সক্ষম করে , যা প্রবাহের শাখাকে জোর-ধাক্কা দেওয়ার বিরুদ্ধে দৃ ref় হতে চেষ্টা করার জন্য স্থানীয় রেফলগ ব্যবহার করে।
মনে করুন আপনি এম 1, এম 2, এম 3 দিয়ে থাকে তখন আপনি মূল / মাস্টারকে শাখা থেকে বের করে দিয়েছেন, তারপরে তিনটি প্রতিশ্রুতিবদ্ধ করেছেন:
M1--M2--M3 <-- origin/master
\
T1--T2--T3 <-- topic
তবে তারপরে কেউ এম 2 মুছে ফেলার জন্য জোর-পুশিং উত্স / মাস্টার দ্বারা ইতিহাস পুনর্লিখন করেছেন:
M1--M3' <-- origin/master
\
M2--M3--T1--T2--T3 <-- topic
আপনার স্থানীয় রিফ্লগ ব্যবহার করে, git rebaseআপনি দেখতে পাচ্ছেন যে আপনি উত্স / মাস্টার শাখার পূর্বের অবতার থেকে কাঁটাচামচ হয়ে গেছেন এবং সুতরাং এম 2 এবং এম 3 কমিটগুলি আসলে আপনার বিষয় শাখার অংশ নয়। সুতরাং এটি যুক্তিসঙ্গতভাবে ধরে নিয়েছে যে যেহেতু এম 2 টি উজানের শাখা থেকে সরানো হয়েছে, তাই বিষয় শাখাটি পুনরায় সাজানোর পরে আপনি আপনার বিষয় শাখায় আর চান না:
M1--M3' <-- origin/master
\
T1'--T2'--T3' <-- topic (rebased)
এই আচরণটি বোধগম্য হয় এবং অব্যাহতি দেওয়ার সময় সাধারণত সঠিক জিনিস।
নিম্নলিখিত কারণগুলি ব্যর্থ হওয়ার কারণ:
git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch
কারণ তারা রিফলগটিকে ভুল অবস্থায় ফেলে। গিট দেখায় newbranchযে 3 টি কমিটস অন্তর্ভুক্ত একটি সংশোধনীতে প্রবাহ শাখাটি কাঁটাচামচ করেছে, তারপরে reset --hardকমিটগুলি অপসারণের জন্য প্রবাহের ইতিহাসটি আবারও লিখেছেন, এবং পরবর্তী সময় আপনি যখন git rebaseএটি চালাবেন তখন এগুলি উজান থেকে সরানো অন্য কোনও প্রতিশ্রুতির মতোই তাদের বাতিল করে দেবে।
তবে এই বিশেষ ক্ষেত্রে আমরা চাই যে এই 3 টি কমিটকে বিষয় শাখার অংশ হিসাবে বিবেচনা করা হবে। এটি অর্জনের জন্য, আমাদের পূর্ববর্তী সংশোধনীতে 3 টি কমিট অন্তর্ভুক্ত নয় এমন উজানের প্রান্তটি কাঁটাচামচ করা উচিত। আমার প্রস্তাবিত সমাধানগুলি এটাই করে, সুতরাং তারা উভয়ই সঠিক অবস্থায় রিফলগটি রেখে দেয়।
আরও বিশদের --fork-pointজন্য গিট রিবেস এবং গিট মার্জ-বেস ডক্সের সংজ্ঞা দেখুন।