আমার ক্ষেত্রে, আমার কাছে একটি my-pluginসংগ্রহশালা এবং একটি main-projectসংগ্রহস্থল ছিল এবং আমি ভান করতে চাই my-pluginযা সর্বদা pluginsসাব-ডিরেক্টরিতে উন্নত ছিল main-project।
মূলত, আমি my-pluginসংগ্রহস্থলের ইতিহাসটি পুনরায় লিখেছিলাম যাতে এটি প্রদর্শিত হয়েছিল যে সমস্ত বিকাশ plugins/my-pluginউপ - ডিরেক্টরিতে ঘটেছিল । তারপর, আমি উন্নয়নের ইতিহাস যোগ my-pluginমধ্যে main-projectইতিহাস, এবং দুই গাছ একসঙ্গে মিশে গিয়ে তৈরি। যেহেতু plugins/my-pluginইতিমধ্যে কোনও ডিরেক্টরি main-projectসংগ্রহস্থলটিতে উপস্থিত ছিল না , এটি ছিল একটি তুচ্ছ নন-বিরোধ। ফলস্বরূপ সংগ্রহস্থল দুটি মূল প্রকল্পের সমস্ত ইতিহাস ধারণ করে এবং এর দুটি শিকড় ছিল।
টি এল; ডিআর
$ cp -R my-plugin my-plugin-dirty
$ cd my-plugin-dirty
$ git filter-branch -f --tree-filter "zsh -c 'setopt extended_glob && setopt glob_dots && mkdir -p plugins/my-plugin && (mv ^(.git|plugins) plugins/my-plugin || true)'" -- --all
$ cd ../main-project
$ git checkout master
$ git remote add --fetch my-plugin ../my-plugin-dirty
$ git merge my-plugin/master --allow-unrelated-histories
$ cd ..
$ rm -rf my-plugin-dirty
দীর্ঘ সংস্করণ
প্রথমে, my-pluginসংগ্রহশালার একটি অনুলিপি তৈরি করুন , কারণ আমরা এই সংগ্রহস্থলের ইতিহাস পুনর্লিখন করব।
এখন, my-pluginসংগ্রহস্থলের মূলটিতে নেভিগেট করুন, আপনার মূল শাখাটি পরীক্ষা করুন (সম্ভবত master), এবং নিম্নলিখিত কমান্ডটি চালান। অবশ্যই, আপনি খেলোয়াড়রা উচিত my-pluginএবং pluginsযাই হোক না কেন আপনার প্রকৃত নাম।
$ git filter-branch -f --tree-filter "zsh -c 'setopt extended_glob && setopt glob_dots && mkdir -p plugins/my-plugin && (mv ^(.git|plugins) plugins/my-plugin || true)'" -- --all
এখন একটি ব্যাখ্যা জন্য। পৌঁছনীয় প্রতিটি প্রতিশ্রুতিতে কমান্ড git filter-branch --tree-filter (...) HEADচালায় । নোট করুন যে এটি প্রতিটি প্রতিশ্রুতিবদ্ধতার জন্য সঞ্চিত ডেটাতে সরাসরি কাজ করে, সুতরাং আমাদের "ওয়ার্কিং ডিরেক্টরি", "সূচক", "মঞ্চায়ন" ইত্যাদির ধারণাগুলি নিয়ে উদ্বিগ্ন হওয়ার দরকার নেই।(...)HEAD
যদি আপনি কোনও filter-branchকমান্ড .gitচালিয়ে যান যা ব্যর্থ হয়, তবে এটি ডিরেক্টরিতে কিছু ফাইল রেখে যাবে এবং পরের বার আপনি চেষ্টা করার পরে filter-branchএটি সম্পর্কে অভিযোগ করবেন, যদি না আপনি -fবিকল্পটি সরবরাহ করেন filter-branch।
প্রকৃত কমান্ড হিসাবে, আমি bashযা চেয়েছিলাম তা করার মতো ভাগ্য আমার ছিল না , তাই পরিবর্তে আমি একটি কমান্ড কার্যকর zsh -cকরতে ব্যবহার করি zsh। প্রথমে আমি extended_globবিকল্পটি সেট করি , যা এটি ^(...)সিন্টেক্সকে সক্ষম করেmv কমান্ডের সেইসাথে glob_dotsবিকল্পটিও, যা আমাকে গ্লোব ( .gitignore) সহ ডটফাইলে (যেমন ) নির্বাচন করতে দেয় ^(...)।
এরপরে, আমি এটি ব্যবহার করি mkdir -p উভয় pluginsএবং plugins/my-pluginএকই সাথে তৈরি কমান্ডটি ।
অবশেষে, সংগ্রহ ব্যতীত মূল ডিরেক্টরিতে সমস্ত ফাইলের সাথে মিলে zsh"নেতিবাচক গ্লোব" বৈশিষ্ট্যটি ^(.git|plugins)ব্যবহার করি.git এবং নতুন তৈরি হওয়া my-pluginফোল্ডার । (বাদ দেওয়া .gitএখানে প্রয়োজনীয় নাও হতে পারে তবে ডিরেক্টরিকে নিজের মধ্যে স্থানান্তরিত করার চেষ্টা করা একটি ত্রুটি))
আমার সংগ্রহশালায়, প্রাথমিক প্রতিশ্রুতিতে কোনও ফাইল অন্তর্ভুক্ত ছিল না, তাই mv আদেশটি প্রাথমিক কমিটের ত্রুটি ফিরিয়েছিল (যেহেতু স্থানান্তরিত করার জন্য কিছুই উপলভ্য ছিল না)। অতএব, আমি || trueএমন একটি যুক্ত করেছি যাতে git filter-branchগর্ভপাত না হয়।
--allবিকল্প বলে filter-branchইতিহাস পুনর্লিখন সব সংগ্রহস্থলের মধ্যে শাখা, এবং অতিরিক্ত --বল করা প্রয়োজনgit পরিবর্তে একটি বিকল্প হিসাবে, পুনর্লিখন শাখা জন্য বিকল্প তালিকা একটি অংশ হিসাবে এটা ব্যাখ্যা করা filter-branchনিজেই।
এখন, আপনার main-projectসংগ্রহস্থল নেভিগেট করুন এবং আপনি যে শাখায় মার্জ করতে চান তা দেখুন check আপনার স্থানীয় কপিটি my-pluginসংগ্রহস্থলের (এর ইতিহাস সংশোধিত সহ) এর main-projectসাথে রিমোট হিসাবে যুক্ত করুন :
$ git remote add --fetch my-plugin $PATH_TO_MY_PLUGIN_REPOSITORY
আপনার প্রতিশ্রুতিবদ্ধ ইতিহাসে এখন দুটি সম্পর্কিত নয় এমন গাছ থাকবে যা আপনি সুন্দরভাবে ব্যবহার করে ভিজ্যুয়ালাইজ করতে পারবেন:
$ git log --color --graph --decorate --all
তাদের মার্জ করতে, ব্যবহার করুন:
$ git merge my-plugin/master --allow-unrelated-histories
নোট করুন যে প্রাক-২.৯.০ গিটে --allow-unrelated-historiesবিকল্পটি বিদ্যমান নেই। আপনি যদি এই সংস্করণগুলির মধ্যে একটি ব্যবহার করে থাকেন তবে কেবলমাত্র বিকল্পটি বাদ দিন: ত্রুটি বার্তা যা --allow-unrelated-historiesপ্রতিরোধ করে was আরো 2.9.0 যোগ।
আপনার কোনও মার্জ সংঘাত থাকা উচিত নয়। যদি আপনি এটি করেন তবে এর অর্থ সম্ভবত হ'ল filter-branchকমান্ডটি সঠিকভাবে কাজ করে না বা ইতিমধ্যে একটি ছিলplugins/my-plugin ডিরেক্টরি রয়েছে main-project।
ভবিষ্যতে কোনও অবদানকারীদের জন্য দুটি শিকড় দিয়ে একটি সংগ্রহশালা তৈরি করার জন্য হ্যাকারি কী চলছে তা ভেবে বিস্ময়কর প্রতিশ্রুতি বার্তা প্রবেশ করার বিষয়টি নিশ্চিত করুন।
উপরের git logকমান্ডটি ব্যবহার করে আপনি নতুন কমিট গ্রাফটি ভিজ্যুয়ালাইজ করতে পারেন, যার দুটি মূল কমিট থাকতে হবে । মনে রাখবেন যে কেবল masterশাখাটি মার্জ হবে । এর অর্থ হ'ল যদি আপনি অন্য my-pluginশাখাগুলিতে গুরুত্বপূর্ণ কাজ করে থাকেন যা আপনি main-projectগাছের সাথে একত্রীকরণ করতে চান , আপনি my-pluginএই মার্জগুলি না করা পর্যন্ত আপনাকে রিমোটটি মোছা থেকে বিরত থাকা উচিত । যদি আপনি এটি না করেন, তবে সেই শাখাগুলি থেকে করা কমিটগুলি এখনও main-projectসংগ্রহশালার মধ্যে থাকবে তবে কিছুগুলি অ্যাক্সেসযোগ্য এবং শেষ অবধি আবর্জনা সংগ্রহের পক্ষে সংবেদনশীল। (এছাড়াও, আপনাকে তাদের এসএএএ দ্বারা উল্লেখ করতে হবে, কারণ একটি রিমোট মোছা তার দূরবর্তী ট্র্যাকিং শাখাগুলি সরিয়ে দেয়))
Allyচ্ছিকভাবে, আপনি যে জিনিসগুলি থেকে রাখতে চান তা মার্জ করার পরে আপনি রিমোটটি ব্যবহার করে my-pluginএটি সরিয়ে ফেলতে পারেন my-plugin:
$ git remote remove my-plugin
my-pluginযার ইতিহাস আপনি বদলেছেন সে অনুলিপি আপনি এখন নিরাপদে মুছতে পারেন । আমার ক্ষেত্রে, আমি my-pluginমার্জ সম্পূর্ণ হওয়ার পরে এবং ধাক্কা দেওয়ার পরেও সত্যিকারের সংগ্রহস্থলটিতে অবমূল্যায়নের বিজ্ঞপ্তি যুক্ত করেছি ।
ম্যাক ওএস এক্স এল ক্যাপিটনে git --version 2.9.0এবং এর সাথে পরীক্ষিত zsh --version 5.2। আপনার মাইলেজ পরিবর্তিত হতে পারে.
তথ্যসূত্র: