গিট সংগ্রহস্থলের ইতিহাসকে ভেঙে ফেলা হচ্ছে


85

আমাদের একটি গিট প্রকল্প রয়েছে যার বেশ বড় ইতিহাস রয়েছে।

বিশেষত, প্রকল্পের শুরুর দিকে প্রকল্পে প্রচুর পরিমাণে বাইনারি সংস্থান ফাইল ছিল, এগুলি এখন কার্যকরভাবে বাহ্যিক সংস্থান হওয়ায় এগুলি এখন সরানো হয়েছে।

যাইহোক, এই ফাইলগুলি পূর্বে প্রতিশ্রুতিবদ্ধ হওয়ার কারণে আমাদের সংগ্রহশালার আকার> 200MB (মোট চেকআউট বর্তমানে 20MB ডলার)।

আমরা যা করতে চাই তা হ'ল ইতিহাসকে "ধস" করা যাতে সংগ্রহশালাটি তার চেয়ে পরবর্তী সংস্করণ থেকে তৈরি হয়েছিল বলে মনে হয়। উদাহরণ স্বরূপ

1-----2-----3-----4-----+---+---+
                   \       /
                    +-----+---+---+
  1. সংগ্রহস্থল তৈরি করা হয়েছে
  2. বাইনারি ফাইলের বড় সেট যুক্ত হয়েছে
  3. বাইনারি ফাইলের বড় সেট সরানো হয়েছে
  4. সংগ্রহস্থলের নতুন উদ্দেশ্যে 'শুরু'

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

এটি কি সম্ভব, না আমরা চিরতরে একটি ফুলে যাওয়া সংগ্রহস্থল রাখার জন্য নষ্ট হই?

উত্তর:


89

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

$ git log --stat       # list all commits and commit messages 

আপনার বাইনারি ফাইলগুলি যুক্ত এবং মুছতে এবং তাদের SHA1 নোট করুন, বলুন 2bcdefএবং মন্তব্য করুন এর জন্য এটি অনুসন্ধান করুন 3cdef3

তারপরে রেপোর ইতিহাস সম্পাদনা করতে, rebase -iআপনার বাইনারিগুলি যুক্ত করেছেন এমন প্রতিশ্রুতিবদ্ধতার পিতামাতার সাথে শুরু করে, এর ইন্টারঅ্যাকটিভ বিকল্পের সাথে কমান্ডটি ব্যবহার করুন । এটি আপনার $ সম্পাদনা চালু করবে এবং আপনি যে কমিটগুলি দিয়ে শুরু করছেন তা দেখতে পাবেন 2bcdef:

$ git rebase -i 2bcdef^    # generate a pick list of all commits starting with 2bcdef
# Rebasing zzzzzz onto yyyyyyy 
# 
# Commands: 
#  pick = use commit 
#  edit = use commit, but stop for amending 
#  squash = use commit, but meld into previous commit 
# 
# If you remove a line here THAT COMMIT WILL BE LOST.
#
pick 2bcdef   Add binary files and other edits
pick xxxxxx   Another change
  .
  .
pick 3cdef3   Remove binary files; link to them as external resources
  .
  .

squash 3cdef3দ্বিতীয় লাইন হিসাবে সন্নিবেশ করুন এবং pick 3cdef3তালিকা থেকে লাইনটি সরান । ইন্টারেক্টিভের জন্য আপনার কাছে এখন ক্রিয়নের একটি তালিকা রয়েছে rebaseযা সেই কমিটগুলি একত্রিত করবে যা আপনার বাইনারিগুলিকে এমন একটি প্রতিশ্রুতিতে যুক্ত করবে এবং মুছে ফেলবে যার পার্থক্য কেবল সেই কমিটগুলির মধ্যে অন্য কোনও পরিবর্তন। এরপরে এটি পরবর্তীকৃত সমস্ত কমিটগুলি পুনরায় প্রয়োগ করা হবে, যখন আপনি এটি শেষ করতে বলবেন:

$ git rebase --continue

এটি এক বা দুই মিনিট সময় নিতে হবে।
আপনার কাছে এখন একটি রেপো রয়েছে যা বাইনারিগুলি আর আসবে না। তবে তারা এখনও স্থান গ্রহণ করবে কারণ ডিফল্টরূপে, গিটগুলি আবর্জনা সংগ্রহের আগে 30 দিনের জন্য পরিবর্তনগুলি রাখে, যাতে আপনি আপনার মন পরিবর্তন করতে পারেন। আপনি যদি এখনই সেগুলি সরাতে চান:

$ git reflog expire --expire=1.minute refs/heads/master
      #all deletions up to 1 minute  ago available to be garbage-collected
$ git fsck --unreachable      # lists all the blobs(files) that will be garbage-collected
$ git prune
$ git gc                      

এখন আপনি ব্লোটটি সরিয়ে ফেলেছেন তবে আপনার বাকি ইতিহাসটি রেখেছেন।


7
আপনাকে কেবল মনে রাখতে হবে যে অন্যরা ইতিমধ্যে সেই সংগ্রহশালাটি থেকে সরিয়ে নিয়েছে, পুনর্লিখনের ইতিহাসগুলি তাদের টানকে বিভ্রান্ত করবে। গিট-রিবেস ম্যানুয়ালটি ব্যাখ্যা করে যে কীভাবে এই অন্যান্য পোস্টগুলি পুনরুদ্ধার করা যায়। kernel.org/pub/software/scm/git/docs/git-rebase.html
অটো

এটি ব্যবহারকারীর নির্দিষ্ট সমস্যার জন্য দুর্দান্ত উত্তর, তবে আসল প্রশ্নের জন্য নয়! ডেভিটেনিওর উত্তরটি প্রকৃত প্রশ্নের দুর্দান্ত উত্তর।
স্যাম ওয়াটকিন্স

27

git filter-branchকমপ্লেট নম্বর 4 করতে আপনার শাখার নতুন রুট কমিট করতে আপনি গ্রাফ্ট সহ ব্যবহার করতে পারেন । এতে .git/info/graftsকেবল একটি লাইন দিয়ে ফাইল তৈরি করুন 4 নম্বর প্রতিশ্রুতিতে SHA1 রয়েছে।

আপনি যদি এখন একটি করেন git logবা gitkআপনি দেখতে পাবেন যে এই আদেশগুলি আপনার শাখার মূল হিসাবে 4 নম্বর কমিট প্রদর্শন করবে। তবে আপনার ভান্ডারগুলিতে আসলে কিছুই পরিবর্তিত হবে না। আপনি মুছে ফেলতে পারেন .git/info/graftsএবং আউটপুট git logবা gitkপূর্বের মত হবে। আসলে 4 নম্বর কমিটকে নতুন মূল করতে আপনাকে git filter-branchকোনও যুক্তি ছাড়াই চলতে হবে ।


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

প্রকৃতপক্ষে, সেই সমস্ত কমিটগুলি যে that শাখার অংশ নয়, সেগুলি শারীরিকভাবে মুছে ফেলার কোনও উপায় আছে কি? git gc --prune=0এগুলি পরিষ্কার করার মতো মনে হচ্ছে না।
ভারহোজেন 21

4
@ ওভারহোজেন git gc --prune=nowশারীরিকভাবে সমস্ত কমিটগুলি পরিষ্কার করে দেয় যা আর উল্লেখ করা হয় না। যদি এটি আপনার পক্ষে কাজ করে না, তবে আপনার কাছে কিছু দূরবর্তী ট্র্যাকিং শাখা থাকতে পারে যা এখনও পুরানো মূলকে উল্লেখ করে। এর সাথে git branch -rতালিকাবদ্ধ করুন, তারপরে উদাহরণস্বরূপ দূরবর্তী শাখাটি সরান git branch -rd origin/masterএবং তারপরে git gc --prune=nowআবার চালান ।
কায়াহর

20

আমি দেখেছি জেস্পেরই পোস্টকে ধন্যবাদ git-filter-branch- এটি আসলে আপনি যা চান তা হতে পারে। দেখে মনে হচ্ছে আপনি আপনার পূর্বের কমিটগুলিও বহাল রাখতে পারেন তবে আপনার বড় ফাইলগুলি অপসারণের পরে এগুলি সংশোধন করা ছাড়া। থেকে Git-Filter-শাখা man পৃষ্ঠা :

মনে করুন আপনি কোনও কমিট থেকে কোনও ফাইল (গোপনীয় তথ্য বা কপিরাইট লঙ্ঘন সহ) সরাতে চান:

গিট ফিল্টার-শাখা - ট্রি-ফিল্টার 'আরএম ফাইলের নাম' হেড

নিশ্চিত হন যে পৃষ্ঠাটি পড়ুন ... স্পষ্টতই আপনি এটি আপনার প্রত্যাশার অতিরিক্ত ক্লোন থেকে এটি করতে চান তা নিশ্চিত হওয়ার জন্য এটি প্রত্যাশার মতো কাজ করে।


4
গিথুবের লিঙ্কটি দেখুন ... গিট-ফিল্টার-শাখা কমান্ডের সাথে কিছু শক্তিশালী বিকল্প রয়েছে: help.github.com/articles/remove-
সেনসেটিভ-

5

আপনি git-fast-exportকি খুঁজছেন?

NAME
   git-fast-export - Git data exporter

SYNOPSIS
   git-fast-export [options] | git-fast-import

DESCRIPTION
   This program dumps the given revisions in a form suitable to be piped into git-fast-
   import(1).

   You can use it as a human readable bundle replacement (see git-bundle(1)), or as a kind
   of an interactive git-filter-branch(1).
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.