ভূমিকা: আপনার কাছে 5 টি সমাধান উপলব্ধ
মূল পোস্টারটিতে বলা হয়েছে:
আমি দুর্ঘটনাক্রমে বেশ কয়েকটি কমান্ট আগে আমার সংগ্রহশালায় একটি অযাচিত ফাইলটি প্রতিশ্রুতিবদ্ধ হয়েছিল ... আমি ফাইলটি সম্পূর্ণরূপে ইতিহাসের ইতিহাস থেকে মুছতে চাই।
এটির বদলে ইতিহাসের পুনর্লিখন করা কি filename.orig
প্রথম যে কোনও জায়গায় ভাণ্ডারে যুক্ত হয়নি?
গিট থেকে কোনও ফাইলের ইতিহাস পুরোপুরি সরিয়ে ফেলার বিভিন্ন উপায় রয়েছে:
- সংশোধন প্রতিশ্রুতি।
- হার্ড পুনরায় সেট (সম্ভবত একটি রিবেস ছাড়াও)।
- অ ইন্টারেক্টিভ রিবেস।
- ইন্টারেক্টিভ রিবেসস।
- ফিল্টারিং শাখা।
মূল পোস্টারের ক্ষেত্রে, প্রতিশ্রুতি সংশোধন করা নিজেই কোনও বিকল্প নয়, যেহেতু পরে তিনি আরও বেশ কয়েকটি অতিরিক্ত অঙ্গীকার করেছিলেন, তবে সম্পূর্ণতার জন্য আমি কীভাবে এটি করব তাও ব্যাখ্যা করব, অন্য যে ব্যক্তি ন্যায়সঙ্গত চায় তার জন্যও তাদের পূর্বের প্রতিশ্রুতি সংশোধন করা।
নোট করুন যে এই সমস্ত সমাধানের ক্ষেত্রে ইতিহাসের পরিবর্তন / পুনর্লিখন / অন্যভাবে প্রতিশ্রুতিবদ্ধ জড়িত , সুতরাং যে কোনও ব্যক্তির কমিটগুলির পুরানো অনুলিপিগুলি রয়েছে তাদের সাথে নতুন ইতিহাসের সাথে তাদের ইতিহাস পুনরায় সমন্বয়ের জন্য অতিরিক্ত কাজ করতে হবে।
সমাধান 1: সংশোধন কমিটি
আপনি যদি পূর্বের প্রতিশ্রুতিতে দুর্ঘটনাক্রমে কোনও পরিবর্তন (যেমন কোনও ফাইল যুক্ত করা) করেন এবং আপনি যে পরিবর্তনের ইতিহাসের আর অস্তিত্ব চান না, তবে আপনি কেবল ফাইলটি এখান থেকে সরাতে পূর্ববর্তী প্রতিশ্রুতি সংশোধন করতে পারেন:
git rm <file>
git commit --amend --no-edit
সমাধান 2: হার্ড রিসেট (সম্ভবত একটি রিবেস প্লাস)
সমাধান # 1 এর মতো, আপনি যদি কেবল নিজের পূর্ববর্তী প্রতিশ্রুতি থেকে মুক্তি পেতে চান, তবে আপনার পিতা-মাতার সাথে কেবল একটি হার্ড রিসেট করার বিকল্প রয়েছে:
git reset --hard HEAD^
এই আদেশটি আপনার পূর্ববর্তী 1 ম পিতামাতার প্রতিশ্রুতিতে কঠোরভাবে পুনরায় সেট করবে ।
তবে , যদি মূল পোস্টারের মতো আপনি যে পরিবর্তনটি পূর্বাবস্থায় ফিরিয়ে আনতে চান তার পরে আপনি বেশ কয়েকটি কমিট করেছেন তবে আপনি এটি পুনরায় সংশোধন করার জন্য হার্ড রিসেটগুলি ব্যবহার করতে পারেন, তবে এটি করাতে একটি রিবেস ব্যবহারও জড়িত। ইতিহাসে আরও একটি চুক্তি সংশোধন করতে আপনি যে পদক্ষেপগুলি ব্যবহার করতে পারেন তা এখানে:
# Create a new branch at the commit you want to amend
git checkout -b temp <commit>
# Amend the commit
git rm <file>
git commit --amend --no-edit
# Rebase your previous branch onto this new commit, starting from the old-commit
git rebase --preserve-merges --onto temp <old-commit> master
# Verify your changes
git diff master@{1}
সমাধান 3: অ ইন্টারেক্টিভ রিবেস
আপনি কেবল ইতিহাস থেকে কোনও প্রতিশ্রুতি পুরোপুরি সরাতে চাইলে এটি কাজ করবে:
# Create a new branch at the parent-commit of the commit that you want to remove
git branch temp <parent-commit>
# Rebase onto the parent-commit, starting from the commit-to-remove
git rebase --preserve-merges --onto temp <commit-to-remove> master
# Or use `-p` insteda of the longer `--preserve-merges`
git rebase -p --onto temp <commit-to-remove> master
# Verify your changes
git diff master@{1}
সমাধান 4: ইন্টারেক্টিভ রিবেসস
এই সমাধান আপনাকে # 2 এবং # 3 সমাধানের মতো একই জিনিসগুলি সম্পাদন করতে অনুমতি দেবে, যেমন আপনার তাত্ক্ষণিক পূর্বের প্রতিশ্রুতিগুলির চেয়ে ইতিহাসে আরও কমিটগুলি সংশোধন বা সরিয়ে ফেলতে পারে, সুতরাং আপনি যে সমাধানটি ব্যবহার করতে বেছে নিচ্ছেন তা একধরনের আপ। ইন্টারেক্টিভ রিবায়েসগুলি কার্য সম্পাদনের কারণে শত শত কমিটগুলি রিবাজ করার পক্ষে উপযুক্ত নয়, সুতরাং আমি এই ধরণের পরিস্থিতিতে নন-ইন্টারেক্টিভ রিবেস বা ফিল্টার শাখা সমাধান (নীচে দেখুন) ব্যবহার করব।
ইন্টারেক্টিভ রিবেস শুরু করতে, নিম্নলিখিতটি ব্যবহার করুন:
git rebase --interactive <commit-to-amend-or-remove>~
# Or `-i` instead of the longer `--interactive`
git rebase -i <commit-to-amend-or-remove>~
এর ফলে গিটটি প্রতিশ্রুতিবদ্ধ ইতিহাসকে পুনর্হাইকরণ করবে যে প্রতিশ্রুতিটির পিতামাতার প্রতি আপনি সংশোধন করতে বা মুছে ফেলতে চান to এরপরে এটি সম্পাদকের গিটটি যেভাবে সেট করতে সেট করা আছে তার বিপরীতে ক্রমাগত কমিটের একটি তালিকা আপনাকে উপস্থাপন করবে (এটি ডিফল্টরূপে ভিম):
pick 00ddaac Add symlinks for executables
pick 03fa071 Set `push.default` to `simple`
pick 7668f34 Modify Bash config to use Homebrew recommended PATH
pick 475593a Add global .gitignore file for OS X
pick 1b7f496 Add alias for Dr Java to Bash config (OS X)
আপনি যে প্রতিশ্রুতি সংশোধন করতে বা অপসারণ করতে চান তা এই তালিকার শীর্ষে থাকবে। এটি সরাতে, কেবল তালিকায় তার লাইনটি মুছুন। অন্যথায়, প্রতিস্থাপন সঙ্গে 1 "সম্পাদনা" "বাছাই" St লাইন, যেমন:
edit 00ddaac Add symlinks for executables
pick 03fa071 Set `push.default` to `simple`
পরবর্তী, প্রবেশ করুন git rebase --continue
। আপনি যদি প্রতিশ্রুতি সম্পূর্ণরূপে অপসারণ করতে চান, তবে আপনাকে যা করতে হবে তা (যাচাইকরণ ব্যতীত, এই সমাধানের জন্য চূড়ান্ত পদক্ষেপ দেখুন)। অন্যদিকে, আপনি যদি প্রতিশ্রুতিটি পরিবর্তন করতে চান, তবে গিটটি কমিট পুনরায় প্রয়োগ করবে এবং তারপরে রিবেসটি বিরতি দেবে।
Stopped at 00ddaacab0a85d9989217dd9fe9e1b317ed069ac... Add symlinks
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
এই মুহুর্তে, আপনি ফাইলটি সরাতে এবং প্রতিশ্রুতি সংশোধন করতে পারেন, তারপরে রিবেসটি চালিয়ে যেতে পারেন:
git rm <file>
git commit --amend --no-edit
git rebase --continue
এটাই. একটি চূড়ান্ত পদক্ষেপ হিসাবে, আপনি অঙ্গীকারটি পরিবর্তন করেছেন বা এটি পুরোপুরি সরিয়ে দিয়েছেন, আপনার শাখায় পুনর্বাসনের আগে তার অবস্থার সাথে পৃথক করে অন্য কোনও অপ্রত্যাশিত পরিবর্তন আনা হয়নি তা যাচাই করা সর্বদা ভাল ধারণা:
git diff master@{1}
সমাধান 5: ফিল্টারিং শাখা
অবশেষে, আপনি যদি ইতিহাসের থেকে কোনও ফাইলের অস্তিত্বের সমস্ত চিহ্ন মুছে ফেলতে চান তবে এই সমাধানটি সেরা and
git filter-branch --index-filter \
'git rm --cached --ignore-unmatch <file>'
যে সরাবে <file>
সব করে থেকে, রুট থেকে শুরু কমিট। পরিবর্তে যদি আপনি কেবল প্রতিশ্রুতি সীমাটি পুনরায় লিখতে চান HEAD~5..HEAD
তবে আপনি এই উত্তরটিতেfilter-branch
নির্দেশিত হিসাবে
অতিরিক্ত যুক্তি হিসাবে এটি পাস করতে পারেন :
git filter-branch --index-filter \
'git rm --cached --ignore-unmatch <file>' HEAD~5..HEAD
আবার filter-branch
সম্পূর্ণ হওয়ার পরে সাধারণত ফিল্টারিং অপারেশনের আগে আপনার শাখাটিকে পূর্বের অবস্থার সাথে আলাদা করে অন্য কোনও অপ্রত্যাশিত পরিবর্তন নেই তা যাচাই করা ভাল usually
git diff master@{1}
ফিল্টার-ব্রাঞ্চ বিকল্প: বিএফজি রেপো ক্লিনার
আমি শুনেছি বিএফজি রেপো ক্লিনার সরঞ্জামটি তার চেয়ে দ্রুত চলে git filter-branch
, তাই আপনি এটি বিকল্প হিসাবেও দেখতে পারেন। এমনকি এটি কার্যকরভাবে বিকল্প হিসাবে ফিল্টার-শাখার ডকুমেন্টেশনে সরকারীভাবে উল্লেখ করা হয়েছে :
গিট-ফিল্টার-শাখা আপনাকে আপনার গিট ইতিহাসের জটিল শেল-স্ক্রিপ্ট লিখিত পুনর্লিখন তৈরি করতে দেয়, তবে আপনি সম্ভবত বড় ফাইল বা পাসওয়ার্ডের মতো অযাচিত তথ্য মুছে ফেললে আপনার সম্ভবত এই নমনীয়তার প্রয়োজন হবে না । এই ক্রিয়াকলাপগুলির জন্য আপনি বিএফজি রেপো-ক্লিনার বিবেচনা করতে চাইতে পারেন , গিট-ফিল্টার-শাখার একটি জেভিএম ভিত্তিক বিকল্প, সাধারণত সেই ব্যবহারের ক্ষেত্রে কমপক্ষে 10-50x দ্রুত এবং বেশ আলাদা বৈশিষ্ট্যযুক্ত:
কোনও ফাইলের কোনও নির্দিষ্ট সংস্করণ ঠিক একবার পরিষ্কার করা হয় । বিএফজি, গিট-ফিল্টার-শাখার বিপরীতে, কোথায় বা কখন এটি আপনার ইতিহাসের মধ্যে প্রতিশ্রুতিবদ্ধ হয়েছিল তার ভিত্তিতে আপনাকে কোনও ফাইল হ্যান্ডেল করার সুযোগ দেয় না। এই সীমাবদ্ধতা বিএফজির মূল কর্মক্ষমতা সুবিধা দেয়, এবং খারাপ ডেটা পরিষ্কার করার ক্ষেত্রে এটি উপযুক্ত - খারাপ ডেটা কোথায় রয়েছে তা আপনার যত্ন নেই, আপনি কেবল এটি চলে যেতে চান ।
ডিফল্টরূপে বিএফজি মাল্টি-কোর মেশিনগুলির পুরো সুবিধা নেয়, সমান্তরালভাবে ফাইল-গাছ সাফ করে। Git-Filter-শাখা সাফ করে করে ক্রমানুসারে (অর্থাত একটি একক থ্রেডেড পদ্ধতিতে), যদিও এটি হয়
ফিল্টার তাদের নিজস্ব parallellism অন্তর্ভুক্ত লিখতে সম্ভব, স্ক্রিপ্ট প্রতিটি বিরুদ্ধে মৃত্যুদন্ড কার্যকর কমিট।
কমান্ড অপশন শুধু অবাঞ্ছিত নিরীক্ষার যেমন সরানোর কাজ করার Git-Filter শাখা চেয়ে অনেক বেশী নিয়ন্ত্রণমূলক ও নিবেদিত আছেন: --strip-blobs-bigger-than 1M
।
অতিরিক্ত সম্পদ
- প্রো গিট § 6.4 গিট সরঞ্জাম - পুনর্নির্মাণের ইতিহাস ।
- গিট-ফিল্টার-শাখা (1) ম্যানুয়াল পৃষ্ঠা ।
- গিট-কমিট (1) ম্যানুয়াল পৃষ্ঠা ।
- গিট-রিসেট (1) ম্যানুয়াল পৃষ্ঠা ।
- গিট-রিবেস (1) ম্যানুয়াল পৃষ্ঠা ।
- বিএফজি রেপো ক্লিনার ( স্রষ্টার নিজেও এই উত্তরটি দেখুন )।