গিট সংগ্রহস্থলে একক বা একাধিক প্রকল্পের মধ্যে নির্বাচন করছেন?


223

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

myProject/
   +-- gui
   +-- core
   +-- api
   +-- implA
   +-- implB

আজ আমাদের প্রতি সংগ্রহস্থল একটি প্রকল্প আছে । এটা স্বাধীনতা দেয়

  • release স্বতন্ত্র উপাদান
  • tag স্বতন্ত্র উপাদান

তবে এটি branchউপাদানগুলির জন্যও জটিল, কারণ প্রায়শই শাখা প্রশাখার apiজন্য সমতুল্য শাখাগুলি coreএবং সম্ভবত অন্যান্য উপাদানগুলির প্রয়োজন হয়।

প্রদত্ত আমরা চাই releaseপৃথক উপাদান আমরা এখনও একটি ব্যবহার দ্বারা অনুরূপ নমনীয়তা পেতে পারেন সংগ্রহস্থলের প্রতি একাধিক প্রকল্প নকশা।

কী অভিজ্ঞতা আছে এবং কীভাবে / কেন আপনি এই সমস্যাগুলিকে সম্বোধন করেছেন?


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

1
প্রতিটি মডিউল পৃথক সংস্করণ নম্বর থাকা প্রয়োজন। এবং আমরা ব্যবহার git-describe
লিকুইজ করুন



আমি অবাক হয়ে দেখলাম যে বিট ( bitsrc.io ) এবং Lerna ( github.com/lerna/lerna ) উল্লেখ নেই! আপনি এখানে আরও শিখতে পারবেন: hackernoon.com/…
Yoni

উত্তর:


199

এর উপরে তিনটি বড় অসুবিধা রয়েছে one project per repository, আপনি যেভাবে উপরে এটি বর্ণনা করেছেন। এগুলি যদি সত্যই স্বতন্ত্র প্রকল্প হয় তবে এগুলি কম সত্য, তবে এর শব্দগুলি থেকে একের পরিবর্তিত হয়ে অন্যের পরিবর্তনের জন্য প্রায়শই প্রয়োজন হয়, যা সত্যই এই সমস্যাগুলিকে অতিরঞ্জিত করতে পারে:

  1. বাগগুলি কখন চালু হয়েছিল এটি আবিষ্কার করা আরও শক্ত। git bisectআপনি যখন আপনার সংগ্রহস্থলগুলিকে সাব-রিপোজিটরিগুলিতে ভাঙ্গা ব্যবহার করেন তখন সরঞ্জামগুলি ব্যবহার করা আরও বেশি কঠিন হয়ে যায়। এটি সম্ভব, এটি ঠিক ততটা সহজ নয়, অর্থ সঙ্কটের সময়ে বাগ-শিকার করা এতটা কঠিন।
  2. কোনও বৈশিষ্ট্যের পুরো ইতিহাস ট্র্যাক করা অনেক বেশি কঠিন। ইতিহাস ট্র্যাভার্সিং কমান্ডগুলির মতো হ'ল git logভাঙা ভাণ্ডার স্ট্রাকচারের সাথে ইতিহাসকে অর্থবহভাবে আউটপুট করবেন না। আপনি সাবমডিউল বা সাবট্রির সাহায্যে বা অন্যান্য স্ক্রিপ্টযোগ্য পদ্ধতির মাধ্যমে কিছু দরকারী আউটপুট পেতে পারেন তবে এটি আপনার পছন্দসই সমস্ত কমিটগুলি টাইপ করা tig --grep=<caseID>বা git log --grep=<caseID>স্ক্যান করার মতো নয়। আপনার ইতিহাস বোঝা শক্ত হয়ে ওঠে, যা আপনার সত্যিকারের প্রয়োজন হলে এটি কম কার্যকর করে তোলে।
  3. নতুন বিকাশকারীরা কোডিং শুরু করার আগে সংস্করণ নিয়ন্ত্রণের কাঠামো শিখতে আরও বেশি সময় ব্যয় করে। প্রতিটি নতুন কাজের জন্য পদ্ধতি বাছাই করা প্রয়োজন, তবে একটি প্রকল্পের ভাণ্ডার ভাঙ্গা মানে তাদের কোডের আর্কিটেকচারের পাশাপাশি ভিসি কাঠামোটিও বেছে নিতে হবে। আমার অভিজ্ঞতা হিসাবে, এটি বিকাশকারীদের পক্ষে নতুন গিটিং করা বিশেষত কঠিন, যারা আরও repতিহ্যবাহী, কেন্দ্রীভূত দোকানগুলি থেকে আসে যা একটি একক সংগ্রহস্থল ব্যবহার করে।

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

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


7
এক অফ টপিক হিসাবে, দুপুরের খাবারের দামের চেয়ে কম, আপনার ল্যাপটপ 20 সালে যা করতে পারে না এমন সিস্টেমে সময় ক্রয়ের চেয়ে রিপোজিটরি ম্যানেজার হিসাবে আরও কিছু উপভোগ্য জিনিস রয়েছে। কখনও কখনও আমি সত্যিই ইন্টারনেট ভালবাসি।
ক্রিস্টোফার

2
কীভাবে আপনি পৃথক রিলিজ হিসাবে পৃথক প্রকল্পগুলি প্রকাশ করবেন? বা আপনার কি কখনও তা করার দরকার নেই? এটাই আমার সমস্যা। আপনার যদি প্রজেক্ট এ এর ​​একটি ভি 1 এবং প্রজেক্ট বি এর ভি 2 তৈরি করতে হয় তবে
অ্যান্ড্রু টি ফিনেল

5
"রেপো প্রতি এক প্রকল্পের" এবং "একাধিক Repos" এর মাঝে চলন্ত জন্য বিবেচনা Git-সাবট্রি (ভাল ব্যাখ্যা stackoverflow.com/a/17864475/15585 )
deterb

1
আমি সাধারণ ব্যবহারের ক্ষেত্রে এটি স্বয়ংক্রিয় করার জন্য একটি স্ক্রিপ্ট লিখেছিলাম: github.com/Oakleon/git-join-repos
chrishiestand

"ভিসি স্ট্রাকচার" কী?
রবার্ট হার্ভে

60

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

আমার বর্তমান অবস্থানে, আমি দশ বছরেরও বেশি ইতিহাসের এক বিহমথ একক-সংগ্রহস্থল সিভিএস সংগ্রহস্থলকে বেশ কয়েকটি গিট সংগ্রহস্থলে স্থানান্তরিত করেছি। এই প্রাথমিক সিদ্ধান্তের পর থেকে, সংগ্রহশালার সংখ্যা বৃদ্ধি পেয়েছে (অন্যান্য দলের ক্রিয়াকলাপের মাধ্যমে), যেখানে আমার সন্দেহ হয় যে আমাদের চেয়ে বেশি হবে অনুকূল হবে। কিছু নতুন ভাড়া ভাণ্ডারগুলি মার্জ করার পরামর্শ দিয়েছে তবে আমি এর বিরুদ্ধে তর্ক করেছি। ওয়েল্যান্ড প্রকল্পের একটি একই অভিজ্ঞতা আছে। আমি সম্প্রতি একটি আলাপে দেখেছি, তারা এক পর্যায়ে 200 টিরও বেশি গিট সংগ্রহস্থল রেখেছিল, যার জন্য নেতৃত্ব ক্ষমা চেয়েছিলেন। তাদের ওয়েবসাইটে তাকিয়ে আমি এখন দেখছি যে তারা 5-এ রয়েছে, যা যুক্তিসঙ্গত বলে মনে হয়। এটি পর্যবেক্ষণ করা জরুরী যে ভাণ্ডারগুলিতে যোগদান এবং বিভাজন একটি পরিচালনাযোগ্য কাজ, এবং এটি পরীক্ষা করা ঠিক (কারণেই) okay

সুতরাং আপনি যখন একাধিক সংগ্রহস্থল চান?

  1. একটি একক সংগ্রহস্থল দক্ষ হওয়ার জন্য খুব বড় হবে।
  2. আপনার ভাণ্ডারগুলি আলগাভাবে মিলিত হয় বা ডিকোপলড হয়।
  3. একজন বিকাশকারী সাধারণত সাধারণত একটি বা আপনার সংগ্রহস্থলের একটি ছোট উপসেট বিকাশ করতে প্রয়োজন।
  4. আপনি সাধারণত সংগ্রহস্থলগুলি স্বতন্ত্রভাবে বিকাশ করতে চান এবং কেবলমাত্র সেগুলি মাঝে মধ্যে সিঙ্ক্রোনাইজ করা প্রয়োজন।
  5. আপনি আরও পরিমিততা উত্সাহ করতে চান।
  6. বিভিন্ন টিম বিভিন্ন স্টোরের কাজ করে।

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

4 এবং 5 আরও সূক্ষ্ম হয়। আপনি যখন ক্লায়েন্ট এবং সার্ভার বলার ভাণ্ডারগুলি বিভক্ত করেন তখন ক্লায়েন্ট এবং সার্ভার কোডের মধ্যে পরিবর্তনগুলি সমন্বয় করা এটি আরও ব্যয়বহুল হয়ে যায়। এটি ইতিবাচক হতে পারে, এতে উভয়ের মধ্যে ডিকোপলড ইন্টারফেসকে উত্সাহ দেওয়া হয়।

এমনকি বহু-সংগ্রহস্থল প্রকল্পগুলির ডাউনসাইড সহ, প্রচুর সম্মানজনক কাজ সেভাবেই করা হয় - ওয়েলল্যান্ড এবং উত্সাহটি মাথায় আসে। আমি বিশ্বাস করি না যে সর্বোত্তম অনুশীলনগুলির বিষয়ে conক্যমত্যটি এখনও বিকশিত হয়েছে, এবং কিছু রায় প্রয়োজন। একাধিক ভাণ্ডার (গিট-সাবট্রি, গিট-সাবমডিউল এবং অন্যান্য) এর সাথে কাজ করার সরঞ্জামগুলি এখনও বিকাশ এবং পরীক্ষা-নিরীক্ষা করা হচ্ছে। আমার পরামর্শটি হ'ল পরীক্ষা করা এবং ব্যবহারিক হওয়া।


7
এই উত্তরটি সমর্থন করার জন্য একটি রেফারেন্সের সাথে আরও সহায়ক হবে: "ভাণ্ডারগুলিতে যোগদান এবং বিভাজন একটি পরিচালনাযোগ্য কাজ" "
ওয়াইল্ডকার্ড

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

মাইক্রো সার্ভিস এবং ডিডিডি ডিজাইন সম্পর্কে সমস্ত কিছু এখানে ধারণ করে। আপনার ভাগ করা কোডটি ছোট করা উচিত।
অরউইন

49

আমরা যেমন গিটহাব ব্যবহার করি, আমাদের কাছে একটি রেপোতে একাধিক প্রকল্প রয়েছে তবে সেই প্রকল্পগুলি / মডিউলগুলি যথাযথভাবে মডিউলাইজড হয়েছে তা নিশ্চিত করে (আমরা -পি এবং-কোরীয় কনভেনশনগুলি + মাভেন + স্ট্যাটিক এবং রানটাইম চেকিং ব্যবহার করি এবং বুট করার জন্য একদিন ওএসজিও যেতে পারি) ।

এটি কী বাঁচায়? ওয়েল, যদি আমরা একাধিক প্রকল্পের মধ্যে ছোট কিছু পরিবর্তন করি তবে আমাদের একাধিক পুল অনুরোধ জারি করতে হবে না। ইস্যু এবং উইকি কেন্দ্রীয়ভাবে রাখা হয় ইত্যাদি।

আমরা এখনও প্রতিটি মডিউল / প্রকল্পকে একটি যথাযথ স্বাধীন প্রকল্প হিসাবে বিবেচনা করি এবং সেগুলি আমাদের সিআই সার্ভার ইত্যাদিতে আলাদাভাবে তৈরি এবং সংহত করি integ


1
অনেক আগ্রহব্যাঞ্জক. আমি সন্দেহ করতে পারি এটি গিথুবের একটি সাধারণ মডেল। যদি আপনি স্বতন্ত্র উপাদান প্রকাশের মুখোমুখি হন, আপনি কি submodulesপুরো রিপোজিটরির মতো কিছু প্রকাশ করেন বা প্রকাশ / ট্যাগ করেন?
জোহান সিজবার্গ

সাবমডিউলগুলি যদি আমাদের করতে হয় তবে আপাতত আমরা পিতামাতার কাছ থেকে নীচে সংস্করণ করব।
মার্টিজন ভার্গবার্গ

আমার বর্তমান নিয়োগকর্তায় আমরা একটি অনুরূপ কৌশল ব্যবহার করি, এবং একটি প্রকল্পের সর্বাধিক সাম্প্রতিক প্রতিশ্রুতি সম্পর্কে প্যাকেজ মেটাডেটা বিভিন্ন শিল্পকর্মের ফাইল হিসাবে প্রকাশ করা হয় (অর্থাত্ ফলাফল git log -1 -- <project_dir>)। এটা সত্যিই বেশ দুর্দান্ত। এই উত্তরটি আরও উন্নয়নের দাবিদার।
ক্রিস্টোফার

22

আমার জন্য, এক বা একাধিক সংগ্রহস্থল ব্যবহারের মূল পার্থক্য হ'ল নিম্নলিখিত প্রশ্নের উত্তর:

  • একই দল দ্বারা নির্মিত একাধিক অংশ, একই রিলিজ চক্র, একই গ্রাহক আছে? তারপরে একটি সংগ্রহস্থল বিভক্ত করার কম কারণ রয়েছে।
  • একাধিক অংশ আছে অত্যন্ত একে অপরের ওপর নির্ভরশীল? সুতরাং বিভক্ত মডেল, নিয়ামক এবং ইউআই (একে অপরের উপর উচ্চ নির্ভরতার কারণে) খুব বুদ্ধিমান নয়। তবে 2 টি অংশে যদি কেবলমাত্র একটি ছোট নির্ভরতা থাকে, যা স্থিতিশীল ইন্টারফেস দ্বারা প্রয়োগ করা হয় যা প্রতি কয়েক বছর পরেই পরিবর্তিত হয়, সুতরাং 2 অংশগুলিকে 2 সংগ্রহস্থলে বিভক্ত করা বুদ্ধিমানের কাজ হবে।

উদাহরণ হিসাবে, আমার কাছে একটি ছোট অ্যাপ্লিকেশন রয়েছে (কেবল ক্লায়েন্ট), এটি সাবভার্সন সংগ্রহস্থলের "গুণমান" পরীক্ষা করে। মূল বাস্তবায়ন রয়েছে, যা কমান্ড লাইন থেকে শুরু করা যেতে পারে, এবং জাভা with এর সাথে ভালভাবে কাজ করবে But তবে আমি একটি ইউআই প্রয়োগ করতে শুরু করেছি, যা জাভা ৮ এর অংশ হিসাবে জাভাএফএক্স ব্যবহার করে, তাই আমি ২ টি বিভক্ত করেছি এবং একটি তৈরি করেছি দ্বিতীয় সংগ্রহস্থল (একটি দ্বিতীয় নির্মাণ প্রক্রিয়া সহ), বিভিন্ন সময়সূচী সহ, ...

আমি উপরের উত্তরগুলি (তাদের ভোট দিয়েছি) পছন্দ করি তবে আমি মনে করি তারা সম্পূর্ণ সত্য ঘটনা নয়। সুতরাং আমি পাশাপাশি ভাণ্ডার ভাণ্ডার যুক্তি যুক্ত করতে চেয়েছিলেন। সুতরাং আসল উত্তরটি (কখন বিভক্ত হবে) মাঝখানে কোথাও হতে পারে ...


4

এটি গিট-সাবট্রি হতে পারে ( আটলশিয়ান ব্লগ , মিডিয়াম ব্লগ বা কার্নেলের লিঙ্কটি দেখুন ) আপনার কাছে এটির জন্য উপযুক্ত fit সুতরাং, আপনার প্রতিটি শীর্ষ স্তরের প্রকল্প সম্ভবত বিভিন্ন সংস্করণ (গুলি) এ সাবট্রিগুলির একটি সেট ব্যবহার করবে।


0

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

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

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

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

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

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