আপনি কীভাবে একটি খারাপ মার্জ ঠিক করেন এবং আপনার ভাল প্রতিশ্রুতিগুলিকে একটি নির্দিষ্ট সংশ্লেষে পুনরায় খেলুন?


407

আমি দুর্ঘটনাক্রমে filename.origএকাধিক কমিটি আগে আমার সংগ্রহশালায় একটি অযাচিত ফাইল ( একীকরণের সমাধানের সময়) প্রতিশ্রুতি দিয়েছিলাম, এখন অবধি আমার নজরে নেই। আমি সংগ্রহস্থলের ইতিহাস থেকে ফাইলটি পুরোপুরি মুছতে চাই।

এটির বদলে ইতিহাসের পুনর্লিখন করা কি filename.origপ্রথম যে কোনও জায়গায় ভাণ্ডারে যুক্ত হয়নি?



সম্পর্কিত সহায়তা. github.com/articles/…
ট্রেভর বয়ড স্মিথ

উত্তর:


297

আপনার পরিস্থিতি যদি প্রশ্নের বর্ণনায় বর্ণিত না হয় তবে দয়া করে এই রেসিপিটি ব্যবহার করবেন না। এই রেসিপিটি কোনও খারাপ মার্জ সংশোধন করার জন্য এবং আপনার ভাল প্রতিশ্রুতিগুলিকে একটি নির্দিষ্ট সংযুক্তিতে পুনরায় খেলতে।

যদিও filter-branchআপনি যা চান তা করবেন, এটি একটি জটিল কমান্ড এবং আমি সম্ভবত এটি দিয়েই বেছে নেব git rebase। এটি সম্ভবত ব্যক্তিগত পছন্দ filter-branchএটি একক, আরও জটিল জটিল কমান্ডে এটি করতে পারে, যেখানে rebaseসমাধানটি একবারে এক ধাপে সমমানের লজিকাল অপারেশনগুলি সম্পাদন করে।

নিম্নলিখিত রেসিপি চেষ্টা করুন:

# create and check out a temporary branch at the location of the bad merge
git checkout -b tmpfix <sha1-of-merge>

# remove the incorrectly added file
git rm somefile.orig

# commit the amended merge
git commit --amend

# go back to the master branch
git checkout master

# replant the master branch onto the corrected merge
git rebase tmpfix

# delete the temporary branch
git branch -d tmpfix

(মনে রাখবেন যে আপনার আসলে কোনও অস্থায়ী শাখার দরকার নেই, আপনি এটি 'বিচ্ছিন্ন হেড' দিয়ে করতে পারেন, তবে অস্থায়ী শাখা ব্যবহার না করে কমান্ডের git commit --amendকাছে সরবরাহের জন্য পদক্ষেপ দ্বারা উত্পন্ন কমিট আইডিটির একটি নোট নেওয়া প্রয়োজন git rebaseনাম।)


6
একটি git rebase -iদ্রুত এবং এখনও সহজ হিসাবে না? it গিট রিবেস -i <sh1-of- নিম> সঠিকটিকে "সম্পাদনা" হিসাবে চিহ্নিত করুন it git rm somefile.orig commit git কমিট --amend $ গিট রিবেস - কনটিনিউ তবে কিছু কারণে আমার এখনও ফাইলটি শেষ কোথাও আছে সময় আমি এটা করেছি। সম্ভবত কিছু অনুপস্থিত।
ওয়ার্নাইট

12
git rebase -iখুব কার্যকর, বিশেষত যখন আপনার একাধিক রিবেস-ওয়াই অপারেশন করতে হয় তবে আপনি যখন কারও কাঁধে ইঙ্গিত করছেন না এবং তাদের সম্পাদকের সাহায্যে তারা কী করছে তা দেখতে পারা যায় তবে সঠিকভাবে বর্ণনা করা আপনার পক্ষে ব্যথা। আমি ভিএম ব্যবহার করি, তবে সকলেই এতে সন্তুষ্ট হবে না: "জিজিজেস্কুয়াশ <এসএসসি> জেডিজেপি: ডাব্লুকিউ" এবং নির্দেশাবলী "বর্তমান দ্বিতীয় লাইনের পরে উপরের লাইনটি সরান এবং লাইন ফোরের প্রথম শব্দটি 'সম্পাদনা' এ পরিবর্তন করুন এখন সংরক্ষণ করুন এবং আসল পদক্ষেপের চেয়ে দ্রুত "প্রস্থান" আরও জটিল মনে হয়। আপনি সাধারণত কিছু --amendএবং ক্রিয়াও শেষ করেন --continue
সিবি বেইলি

3
আমি এটি করেছি কিন্তু একই বার্তা সহ একটি নতুন প্রতিশ্রুতি সংশোধিতটির উপরে আবার প্রয়োগ করা হয়েছিল। স্পষ্টতই গিটটি অবাঞ্ছিত ফাইলযুক্ত পুরানো, আনমেনড কমিট এবং অন্য শাখা থেকে স্থির প্রতিশ্রুতিগুলির মধ্যে 3 উপায়ে একীভূত করেছিল এবং তাই ফাইলটি পুনরায় প্রয়োগ করতে পুরানোটির উপরে একটি নতুন প্রতিশ্রুতি তৈরি করেছিল।

6
@UncleCJ: আপনার ফাইলটি কি মার্জ কমিটে যুক্ত হয়েছিল? এটা গুরুত্বপূর্ণ. এই রেসিপিটি খারাপ মার্জ কমিটের সাথে লড়াই করতে ডিজাইন করা হয়েছে। ইতিহাসে যদি আপনার অযাচিত ফাইলটি একটি সাধারণ প্রতিশ্রুতিতে যুক্ত করা হয় তবে এটি কাজ করবে না।
সিবি বেইলি

1
আমি অবাক হয়েছি কীভাবে আমি স্মার্টজিট এবং কোনও টার্মিনাল ব্যবহার করে এটি করতে পারি না! রেসিপি জন্য ধন্যবাদ!
ক্রেগোক্স

209

ভূমিকা: আপনার কাছে 5 টি সমাধান উপলব্ধ

মূল পোস্টারটিতে বলা হয়েছে:

আমি দুর্ঘটনাক্রমে বেশ কয়েকটি কমান্ট আগে আমার সংগ্রহশালায় একটি অযাচিত ফাইলটি প্রতিশ্রুতিবদ্ধ হয়েছিল ... আমি ফাইলটি সম্পূর্ণরূপে ইতিহাসের ইতিহাস থেকে মুছতে চাই।

এটির বদলে ইতিহাসের পুনর্লিখন করা কি filename.origপ্রথম যে কোনও জায়গায় ভাণ্ডারে যুক্ত হয়নি?

গিট থেকে কোনও ফাইলের ইতিহাস পুরোপুরি সরিয়ে ফেলার বিভিন্ন উপায় রয়েছে:

  1. সংশোধন প্রতিশ্রুতি।
  2. হার্ড পুনরায় সেট (সম্ভবত একটি রিবেস ছাড়াও)।
  3. অ ইন্টারেক্টিভ রিবেস।
  4. ইন্টারেক্টিভ রিবেসস।
  5. ফিল্টারিং শাখা।

মূল পোস্টারের ক্ষেত্রে, প্রতিশ্রুতি সংশোধন করা নিজেই কোনও বিকল্প নয়, যেহেতু পরে তিনি আরও বেশ কয়েকটি অতিরিক্ত অঙ্গীকার করেছিলেন, তবে সম্পূর্ণতার জন্য আমি কীভাবে এটি করব তাও ব্যাখ্যা করব, অন্য যে ব্যক্তি ন্যায়সঙ্গত চায় তার জন্যও তাদের পূর্বের প্রতিশ্রুতি সংশোধন করা।

নোট করুন যে এই সমস্ত সমাধানের ক্ষেত্রে ইতিহাসের পরিবর্তন / পুনর্লিখন / অন্যভাবে প্রতিশ্রুতিবদ্ধ জড়িত , সুতরাং যে কোনও ব্যক্তির কমিটগুলির পুরানো অনুলিপিগুলি রয়েছে তাদের সাথে নতুন ইতিহাসের সাথে তাদের ইতিহাস পুনরায় সমন্বয়ের জন্য অতিরিক্ত কাজ করতে হবে।


সমাধান 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

অতিরিক্ত সম্পদ

  1. প্রো গিট § 6.4 গিট সরঞ্জাম - পুনর্নির্মাণের ইতিহাস
  2. গিট-ফিল্টার-শাখা (1) ম্যানুয়াল পৃষ্ঠা
  3. গিট-কমিট (1) ম্যানুয়াল পৃষ্ঠা
  4. গিট-রিসেট (1) ম্যানুয়াল পৃষ্ঠা
  5. গিট-রিবেস (1) ম্যানুয়াল পৃষ্ঠা
  6. বিএফজি রেপো ক্লিনার ( স্রষ্টার নিজেও এই উত্তরটি দেখুন )।

কি filter-branchহ্যাশ এর পুনঃগণনা কারণ? কোনও দল যদি একটি রেপো নিয়ে কাজ করে যেখানে একটি বড় ফাইল ফিল্টার করা উচিত, তারা কীভাবে এমনটি করবে যাতে প্রত্যেকে একই সাথে রেপোর অবস্থা শেষ করে?
ইয়াকভল

@YakovL। সবকিছু হ্যাশকে পুনরায় গণনা করে। আসলে প্রতিশ্রুতিগুলি পরিবর্তনযোগ্য ut এটি সম্পূর্ণ নতুন ইতিহাস তৈরি করে এবং আপনার শাখার পয়েন্টারটিকে এতে সরিয়ে দেয়। প্রত্যেকের একই ইতিহাস রয়েছে তা নিশ্চিত করার একমাত্র উপায় হ'ল হার্ড রিসেট।
ম্যাড পদার্থবিদ

118

আপনি যদি থেকে কোনও প্রতিশ্রুতি না করেন তবে কেবল git rmফাইল এবং git commit --amend

যদি তোমার থাকে

git filter-branch \
--index-filter 'git rm --cached --ignore-unmatch path/to/file/filename.orig' merge-point..HEAD

থেকে প্রতিটি পরিবর্তন মধ্য দিয়ে যেতে হবে merge-pointথেকে HEAD, তাহলে ডিলিট filename.orig এবং পরিবর্তন পুনর্লিখন। ব্যবহারের --ignore-unmatchঅর্থ হ'ল কমান্ডটি যদি কোনও কারণে ফাইলের নাম.অরিগ পরিবর্তন থেকে অনুপস্থিত থাকে তবে ব্যর্থ হবে না। গিট-ফিল্টার-শাখা ম্যান পৃষ্ঠাতে উদাহরণ বিভাগ থেকে প্রস্তাবিত উপায় এটি

উইন্ডোজ ব্যবহারকারীদের জন্য নোট: ফাইল পাথ অবশ্যই ফরোয়ার্ড স্ল্যাশ ব্যবহার করা উচিত


3
ধন্যবাদ! গিটার ফিল্টার-শাখা আমার পক্ষে কাজ করেছিল যেখানে উত্তর হিসাবে দেওয়া রিবাজে উদাহরণটি দেয় নি: পদক্ষেপগুলি কাজ করে বলে মনে হয়েছিল, কিন্তু তারপরে ধাক্কা ব্যর্থ হয়েছিল। একটি টানছে, তারপরে সাফল্যের সাথে ধাক্কা খেয়েছে, তবে ফাইলটি এখনও ছিল। পুনর্বাসনের পদক্ষেপগুলি পুনরায় করার চেষ্টা করেছিল এবং তারপরে এটি মার্জ সংঘাতের সাথে সমস্ত অগোছালো হয়ে যায়। আমি কিছুটা আলাদা ফিল্টার-শাখা কমান্ডটি ব্যবহার করেছি, যদিও এখানে একটি "উন্নত পদ্ধতি" দেওয়া হয়েছে: github.com/guides/completely-remove-a-file-from- all - revisions git ফিল্টার-শাখা -f --index- ফিল্টার করুন 'গিট আপডেট-ইনডেক্স - ফাইলের নাম সরান' <
সংস্করণ-

1
আমি নিশ্চিত না কোনটি উন্নত পদ্ধতি। গিট অফিসিয়াল ডকুমেন্টেশন git-filter-branchপ্রথম মনে হয়।
ওয়ার্নাইট

5
পরীক্ষা করে দেখুন zyxware.com/articles/4027/... আমি এটা অধিকাংশ সম্পূর্ণ এবং সোজা এগিয়ে সমাধান জড়িত এটিfilter-branch
leontalbot

2
@ অ্যাটমিকুলস, আপনি যদি স্থানীয় রেপোকে দূরবর্তী স্থানে চাপানোর চেষ্টা করবেন, গিট প্রথমে রিমোট থেকে টানতে জোর করবে, কারণ এতে স্থানীয়ভাবে আপনার পরিবর্তন নেই। আপনি রিমোটে চাপ দেওয়ার জন্য --ফোর্স পতাকা ব্যবহার করতে পারেন - এটি সেখান থেকে ফাইলগুলি পুরোপুরি সরিয়ে ফেলবে। তবে সতর্কতা অবলম্বন করুন, নিশ্চিত করুন যে আপনি কেবল ফাইলগুলি ব্যতীত অন্য কিছু ওভাররাইট করতে বাধ্য করবেন না।
sol0mka

1
উইন্ডোজ ব্যবহার করার সময় ব্যবহার করার জন্য "এবং না মনে রাখবেন ', বা আপনি একটি অনিচ্ছাকৃতভাবে অক্ষরযুক্ত "খারাপ রিভিশন" ত্রুটি পাবেন।
সিজেড

49

এটি সর্বোত্তম উপায়:
http://github.com/guides/completely-remove-a-file-from- all-revisions

প্রথমে ফাইলগুলির অনুলিপিগুলি ব্যাকআপ করার বিষয়ে নিশ্চিত হন।

সম্পাদনা

নিওনের সম্পাদনা দুর্ভাগ্যক্রমে পর্যালোচনা চলাকালীন বাতিল হয়ে গেছে।
নিও নিওন্স পোস্টটি দেখুন, এটিতে দরকারী তথ্য থাকতে পারে!


উদাহরণস্বরূপ, *.gzগিট সংগ্রহস্থলগুলিতে দুর্ঘটনাক্রমে প্রতিশ্রুতিবদ্ধ সমস্ত ফাইল সরিয়ে ফেলতে :

$ du -sh .git ==> e.g. 100M
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch *.gz' HEAD
$ git push origin master --force
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git gc --prune=now
$ git gc --aggressive --prune=now

এখনও কি আমার কাজ হয়নি? (আমি বর্তমানে গিট সংস্করণে 1.7.6.1 এ আছি)

$ du -sh .git ==> e.g. 100M

কেন নিশ্চিত নয়, যেহেতু আমার কেবলমাত্র একটি মাস্টার শাখা ছিল। যাইহোক, অবশেষে আমি আমার গিট রেপোটি একটি নতুন খালি এবং খালি গিট সংগ্রহস্থলের মধ্যে ঠেলা দিয়ে সত্যই পরিষ্কার করে ফেললাম eg

$ git init --bare /path/to/newcleanrepo.git
$ git push /path/to/newcleanrepo.git master
$ du -sh /path/to/newcleanrepo.git ==> e.g. 5M 

(হ্যাঁ!)

তারপরে আমি এটি একটি নতুন ডিরেক্টরিতে ক্লোন করেছি এবং এটির উপরে গিট ফোল্ডারে সরানো। যেমন

$ mv .git ../large_dot_git
$ git clone /path/to/newcleanrepo.git ../tmpdir
$ mv ../tmpdir/.git .
$ du -sh .git ==> e.g. 5M 

(হ্যাঁ! শেষ পর্যন্ত পরিষ্কার!)

যা ঠিক আছে তা যাচাই করার পরে, আপনি ../large_dot_gitএবং ../tmpdirডিরেক্টরিগুলি মুছতে পারেন (এখন থেকে কয়েক সপ্তাহ বা একমাসে, কেবলমাত্র ক্ষেত্রে ...)


1
"এটি এখনও আমার পক্ষে কাজ করে না?" এর আগে এটি আমার পক্ষে কাজ করেছিল? মন্তব্য
দয়া

দুর্দান্ত উত্তর, তবে --prune-emptyফিল্টার-শাখা কমান্ডে যুক্ত করার পরামর্শ দিন ।
ধারণাগুলি 42

27

গিট ইতিহাসের পুনর্লিখন সমস্ত ক্ষতিগ্রস্থ প্রতিশ্রুতিবদ্ধ আইডিকে পরিবর্তন করার দাবি করেছে এবং সুতরাং প্রকল্পে কাজ করা প্রত্যেকেরই রেপোর পুরানো অনুলিপিগুলি মুছতে হবে এবং আপনি ইতিহাসটি সাফ করার পরে একটি নতুন ক্লোন তৈরি করতে হবে। এটি যত বেশি লোককে অসুবিধে করে তোলে, আপনার এটির জন্য ভাল কারণ প্রয়োজন - আপনার অতিমাত্রায় ফাইল আসলেই কোনও সমস্যা তৈরি করে না, তবে কেবল যদি আপনি এই প্রকল্পে কাজ করে থাকেন তবে আপনি চাইলে গিট ইতিহাসও পরিষ্কার করতে পারেন প্রতি!

এটি যতটা সম্ভব সহজ করার জন্য, আমি গিফেরgit-filter-branch ইতিহাস থেকে ফাইলগুলি সরিয়ে ফেলার জন্য বিশেষভাবে তৈরি করা সহজ, দ্রুত বিকল্প, বিএফজি রেপো-ক্লিনার ব্যবহার করার পরামর্শ দেব recommend এখানে আপনার জীবনকে সহজ করার একটি উপায় হ'ল এটি ডিফল্টরূপে সমস্ত রেফগুলি পরিচালনা করে (সমস্ত ট্যাগ, শাখা ইত্যাদি) তবে এটি 10 - 50x দ্রুতও হয়

আপনার এখানে পদক্ষেপগুলি সাবধানতার সাথে অনুসরণ করা উচিত: http://rtyley.github.com/bfg-repo-cleaner/#usage - তবে মূল বিটটি এই: বিএফজি জারটি ডাউনলোড করুন (জাভা 6 বা উপরে প্রয়োজন) এবং এই আদেশটি চালান :

$ java -jar bfg.jar --delete-files filename.orig my-repo.git

আপনার সম্পূর্ণ সংগ্রহস্থল ইতিহাস স্ক্যান করা হবে, এবং নামের filename.origযে কোনও ফাইল (এটি আপনার সর্বশেষ প্রতিশ্রুতিতে নেই ) সরানো হবে। এটি git-filter-branchএকই জিনিস ব্যবহার করার চেয়ে যথেষ্ট সহজ !

সম্পূর্ণ প্রকাশ: আমি বিএফজি রেপো-ক্লিনার এর লেখক।


4
এটি একটি দুর্দান্ত সরঞ্জাম: একটি একক কমান্ড, এটি খুব পরিষ্কার আউটপুট উত্পন্ন করে এবং একটি লগ ফাইল সরবরাহ করে যা প্রতিটি পুরানো প্রতিশ্রুতিটি নতুনটির সাথে মেলে । আমি জাভা ইনস্টল করতে পছন্দ করি না তবে এটি মূল্যবান।
মাইকমেকানা

এটি আমার জন্য কাজ করা একমাত্র জিনিস তবে এটির মতো কারণ আমি গিট ফিল্টার-শাখা সঠিকভাবে কাজ করছিলাম না। :-)
কেভিন লাब्र্যাঞ্চ

14
You should probably clone your repository first.

Remove your file from all branches history:
git filter-branch --tree-filter 'rm -f filename.orig' -- --all

Remove your file just from the current branch:
git filter-branch --tree-filter 'rm -f filename.orig' -- --HEAD    

Lastly you should run to remove empty commits:
git filter-branch -f --prune-empty -- --all

1
উত্তরগুলির সমস্তগুলি ফিল্টার-শাখার ট্র্যাকের মতো মনে হচ্ছে, এটি আপনার ইতিহাসে সমস্ত শাখা কীভাবে পরিষ্কার করবেন তা হাইলাইট করে।
ক্যামেরন লোয়েল পামার

4

চার্লস বেইলির সমাধানটিতে কেবল এটি যুক্ত করতে, আমি পূর্ববর্তী প্রতিশ্রুতি থেকে অযাচিত ফাইলগুলি সরাতে গিট রিবেস -i ব্যবহার করেছি এবং এটি একটি কবজির মতো কাজ করেছে। পদক্ষেপগুলি:

# Pick your commit with 'e'
$ git rebase -i

# Perform as many removes as necessary
$ git rm project/code/file.txt

# amend the commit
$ git commit --amend

# continue with rebase
$ git rebase --continue

4

সহজ উপায় আমি দেখেছি করে গিয়েছিলেন leontalbot, যা একটি আছে (একটি মন্তব্য হিসাবে) পোস্ট Anoopjohn দ্বারা প্রকাশিত । আমি মনে করি একটি উত্তর হিসাবে এটির নিজের জায়গার মূল্য রয়েছে:

(আমি এটিকে ব্যাশ স্ক্রিপ্টে রূপান্তর করেছি)

#!/bin/bash
if [[ $1 == "" ]]; then
    echo "Usage: $0 FILE_OR_DIR [remote]";
    echo "FILE_OR_DIR: the file or directory you want to remove from history"
    echo "if 'remote' argument is set, it will also push to remote repository."
    exit;
fi
FOLDERNAME_OR_FILENAME=$1;

#The important part starts here: ------------------------

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch $FOLDERNAME_OR_FILENAME" -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

if [[ $2 == "remote" ]]; then
    git push --all --force
fi
echo "Done."

সমস্ত ক্রেডিট যায় Annopjohnএবং leontalbotএটি নির্দেশ করার জন্য।

বিঃদ্রঃ

সচেতন থাকুন যে স্ক্রিপ্টটিতে বৈধতা অন্তর্ভুক্ত নেই, তাই নিশ্চিত হন যে আপনি ভুল করবেন না এবং কিছু ভুল হয়ে যাওয়ার ক্ষেত্রে আপনার ব্যাকআপ রয়েছে। এটি আমার পক্ষে কাজ করেছিল, তবে এটি আপনার পরিস্থিতিতে কাজ করবে না। সতর্কতার সাথে এটি ব্যবহার করুন (কী চলছে তা জানতে চাইলে লিঙ্কটি অনুসরণ করুন)।


3

অবশ্যই, git filter-branchযেতে উপায়।

দুঃখের বিষয়, এটি সম্পূর্ণরূপে filename.origআপনার রেপো থেকে অপসারণ করার পক্ষে যথেষ্ট নয় , কারণ এটি এখনও ট্যাগ, রিফ্লগ এন্ট্রি, রিমোট এবং অন্যান্য দ্বারা রেফারেন্স করা যেতে পারে।

আমি এই সমস্ত উল্লেখগুলিও মুছে ফেলার এবং পরে আবর্জনা সংগ্রহকারীকে কল করার পরামর্শ দিচ্ছি। আপনি এই ওয়েবসাইট git forget-blobথেকে স্ক্রিপ্টটি এক ধাপে এই সমস্ত করতে ব্যবহার করতে পারেন ।

git forget-blob filename.orig


1

যদি আপনি সর্বশেষতম প্রতিশ্রুতিটি পরিষ্কার করতে চান তবে আমি গিট সংস্করণ 2.14.3 (অ্যাপল গিট -98) দিয়ে চেষ্টা করেছি:

touch empty
git init
git add empty
git commit -m init

# 92K   .git
du -hs .git

dd if=/dev/random of=./random bs=1m count=5
git add random
git commit -m mistake

# 5.1M  .git
du -hs .git

git reset --hard HEAD^
git reflog expire --expire=now --all
git gc --prune=now

# 92K   .git
du -hs .git

git reflog expire --expire=now --all; git gc --prune=nowকরা খুব খারাপ জিনিস। আপনি যদি ডিস্কের জায়গার বাইরে চলে না যান তবে গিট আবর্জনা কয়েক সপ্তাহের পরে এই
কমিটগুলি

যে ইশারা জন্য ধন্যবাদ। আমার রেপো অনেক বড় বাইনারি ফাইল সহ জমা দেওয়া হয়েছিল এবং প্রতি রাতে পুরোপুরি রেপো ব্যাক আপ করা হয়। সুতরাং আমি এটি থেকে প্রতিটি বিট চেয়েছিলাম;)
ক্লার্কট্টফু


-1

আপনি এটি ব্যবহার করতে পারেন:

git reset HEAD file/path


3
যদি ফাইলটি কোনও প্রতিশ্রুতিতে যুক্ত করা হয় তবে এটি সূচি থেকে ফাইলটিকে সরিয়ে দেয় না, এটি কেবল সূচীটি ফাইলের হেড সংস্করণে পুনরায় সেট করে।
সিবি বেইলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.