एक या एक रिपॉजिटरी में एकल या कई परियोजनाओं के बीच चयन?


223

एक gitवातावरण में, जहाँ हमने अधिकांश परियोजनाओं को संशोधित किया है, हम प्रति-भंडार या कई परियोजनाओं में प्रति-भंडार डिज़ाइन समस्या का सामना कर रहे हैं । आइए एक मॉड्यूलर प्रोजेक्ट पर विचार करें:

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

आज हम प्रति भंडार एक परियोजना कर रहे हैं । इससे आजादी मिलती है

  • release अलग - अलग घटक
  • tag अलग - अलग घटक

लेकिन यह भी branchघटकों के लिए बोझिल है क्योंकि अक्सर शाखाओं में बंटने के apiलिए समान शाखाओं की आवश्यकता होती है coreऔर शायद अन्य घटकों की भी।

यह देखते हुए कि हम releaseअलग-अलग घटकों को चाहते हैं, हम अभी भी रिपोजिटरी डिज़ाइन के अनुसार कई परियोजनाओं का उपयोग करके समान लचीलापन प्राप्त कर सकते हैं ।

क्या अनुभव हैं और आपने इन मुद्दों को कैसे / क्यों संबोधित किया?


1
अभी मेरे पास एक समान मुद्दा है। मुझे एक परियोजना के विभिन्न संस्करणों को जारी करने की आवश्यकता है ताकि उन्हें अलग-अलग रिपॉजिटरी में होना चाहिए। हालांकि यह एक बुरा सपना है। यह बहुत अच्छा होगा अगर सिर्फ उप निर्देशिकाओं को शाखा देने का एक तरीका था।
एंड्रयू टी फिनेल

1
प्रत्येक मॉड्यूल के लिए अलग संस्करण संख्याएँ होनी चाहिए। और हम उपयोग करते हैं git-describe
linquize



मुझे यह देखकर आश्चर्य हुआ कि बिट ( बिट्र्स इत्यादि ) और लारना ( 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. नए डेवलपर्स वर्जन कोडिंग की संरचना सीखने से पहले अधिक समय व्यतीत करते हैं, इससे पहले कि वे कोडिंग शुरू कर सकें। हर नई नौकरी के लिए प्रक्रियाओं को चुनने की आवश्यकता होती है, लेकिन एक परियोजना भंडार को भंग करने का मतलब है कि उन्हें कोड की वास्तुकला के अलावा कुलपति संरचना को चुनना होगा। मेरे अनुभव में, यह नए डेवलपर्स के लिए विशेष रूप से कठिन है जो अधिक पारंपरिक, केंद्रीकृत दुकानों से आते हैं जो एक एकल भंडार का उपयोग करते हैं।

अंत में, यह एक अवसर लागत गणना है। एक पूर्व नियोक्ता में, हमारे पास हमारा प्राथमिक आवेदन 35 विभिन्न उप-रिपॉजिटरी में विभाजित था। उनमें से शीर्ष पर हमने इतिहास को खोजने के लिए स्क्रिप्ट का एक जटिल सेट इस्तेमाल किया, सुनिश्चित करें कि राज्य (यानी उत्पादन बनाम विकास शाखाएं) उन सभी में समान थीं, और उन्हें व्यक्तिगत रूप से या एन मस्से तैनात करें।

यह बहुत ज्यादा था; हमारे लिए बहुत कम से कम। ओवरहेड प्रबंधन ने हमारी विशेषताओं को कम फुर्तीला बना दिया, तैनाती को बहुत कठिन बना दिया, नए देवों को पढ़ाने में बहुत अधिक समय लगा दिया, और इसके अंत तक, हम मुश्किल से याद कर सकते थे कि हमने पहले स्थान पर भंडार को क्यों खंडित किया। एक सुंदर वसंत का दिन, मैंने EC2 में क्लस्टर गणना समय की एक दोपहर के लिए $ 10 खर्च किए। मैं दो दर्जन git filter-branchकॉल के साथ रेपो को वापस से मिटा देता हूं । हमने कभी पीछे मुड़कर नहीं देखा।


7
एक अलग विषय के रूप में, एक रिपॉजिटरी मैनेजर के रूप में कुछ और सुखद चीजें हैं जो एक सिस्टम पर समय खरीदने की तुलना में हैं जो दो घंटे में आपके लैपटॉप को 20 में क्या नहीं कर सकता है, दोपहर के भोजन की कीमत से कम। कभी-कभी मैं वास्तव में इंटरनेट से प्यार करता हूं।
क्रिस्टोफर

2
आप उन व्यक्तिगत परियोजनाओं को अलग रिलीज़ के रूप में कैसे जारी करेंगे? या क्या आपको कभी ऐसा करने की आवश्यकता नहीं है? यही समस्या है मेरे पास। अगर आपको प्रोजेक्ट A का V1 और प्रोजेक्ट B का V2 बनाने की आवश्यकता है
एंड्रयू टी फिननेल

5
"रेपो प्रति एक परियोजना" और "कई रेपोस" के बीच ले जाने के लिए विचार करना Git-सबट्री (कम से अच्छा स्पष्टीकरण stackoverflow.com/a/17864475/15585 )
deterb

1
मैंने आम उपयोग के मामलों के लिए इसे स्वचालित करने के लिए एक स्क्रिप्ट लिखी: github.com/Oakleon/git-join-repos
chrishiestand

"वीसी संरचना" क्या है?
रॉबर्ट हार्वे

60

क्रिस्टोफर ने एक-प्रोजेक्ट-प्रति-रिपॉजिटरी मॉडल के नुकसान की गणना करने का बहुत अच्छा काम किया। मैं उन कुछ कारणों पर चर्चा करना चाहूंगा जिन पर आप एक बहु-रिपॉजिटरी दृष्टिकोण पर विचार कर सकते हैं। मेरे द्वारा काम किए गए कई वातावरणों में, एक बहु-रिपॉजिटरी दृष्टिकोण एक उचित समाधान रहा है, लेकिन कितने रिपॉजिटरी होने का निर्णय, और जहां कटौती करना हमेशा आसान नहीं होता है।

अपनी वर्तमान स्थिति में, मैंने दस वर्षों के इतिहास के साथ कई गॉट रिपॉजिटरी में एक बीहोम एकल-रिपॉजिटरी सीवीएस रिपॉजिटरी का माइग्रेशन किया। उस प्रारंभिक निर्णय के बाद से, रिपॉजिटरी की संख्या (अन्य टीमों के कार्यों के माध्यम से) बढ़ी है, उस बिंदु तक जहां मुझे संदेह है कि हमारे पास इससे अधिक इष्टतम है। कुछ नए लोगों ने रिपॉजिटरी को मर्ज करने का सुझाव दिया है लेकिन मैंने इसके खिलाफ तर्क दिया है। वायलैंड परियोजना का एक समान अनुभव है। एक बातचीत में मैंने हाल ही में देखा, उनके पास एक बिंदु पर, 200 से अधिक गिट रिपॉजिटरी थीं, जिसके लिए लीड ने माफी मांगी। उनकी वेबसाइट को देखते हुए, मुझे लगता है कि अब वे 5 पर हैं, जो उचित लगता है। यह मानना ​​महत्वपूर्ण है कि रिपॉजिटरी में शामिल होना और विभाजित करना एक प्रबंधनीय कार्य है, और इसका प्रयोग (कारण के भीतर) करना ठीक है।

तो आप कई रिपॉजिटरी कब चाहते हैं?

  1. कुशल होने के लिए एक एकल भंडार बहुत बड़ा होगा।
  2. आपकी रिपॉजिटरीज़ शिथिल रूप से युग्मित, या विघटित हैं।
  3. एक डेवलपर को आमतौर पर केवल एक, या आपके रिपॉजिटरी के छोटे उपसमूह को विकसित करने की आवश्यकता होती है।
  4. आप आमतौर पर रिपॉजिटरी को स्वतंत्र रूप से विकसित करना चाहते हैं, और केवल उन्हें कभी-कभी सिंक्रनाइज़ करने की आवश्यकता होती है।
  5. आप अधिक प्रतिरूपकता को प्रोत्साहित करना चाहते हैं।
  6. अलग-अलग टीमें अलग-अलग रिपॉजिटरी पर काम करती हैं।

यदि पॉइंट 1 होल्ड है तो पॉइंट्स 2 और 3 केवल महत्वपूर्ण हैं। हमारे रिपॉजिटरी को विभाजित करके, मैंने अपने ऑफसाइट सहयोगियों द्वारा प्राप्त विलंब को काफी कम कर दिया, डिस्क की खपत कम कर दी और नेटवर्क ट्रैफ़िक में सुधार किया।

4 और 5 अधिक सूक्ष्म हैं। जब आप ग्राहक और सर्वर के पुनर्खरीद को विभाजित करते हैं, तो इससे ग्राहक और सर्वर कोड के बीच परिवर्तनों का समन्वय करना अधिक महंगा हो जाता है। यह एक सकारात्मक हो सकता है, जिसमें दोनों के बीच एक decoupled इंटरफ़ेस को प्रोत्साहित करता है।

मल्टी-रिपॉजिटरी प्रोजेक्ट्स के डाउनसाइड्स के साथ भी, इस तरह से बहुत सारे सम्मानजनक काम किए जाते हैं - वेलैंड और बूस्ट। मेरा मानना ​​है कि सर्वोत्तम प्रथाओं के बारे में एक आम सहमति अभी तक विकसित नहीं हुई है, और कुछ निर्णय की आवश्यकता है। कई रिपॉजिटरी (git-subtree, git-submodule और अन्य) के साथ काम करने के लिए उपकरण अभी भी विकसित और प्रयोग किए जा रहे हैं। मेरी सलाह है कि प्रयोग करें और व्यावहारिक रहें।


7
यह उत्तर दावे का समर्थन करने के संदर्भ के साथ और भी अधिक उपयोगी होगा: "रिपॉजिटरी में शामिल होना और विभाजन करना एक प्रबंधनीय कार्य है।"
वाइल्डकार्ड

3
एकाधिक रिपॉजिट भी मॉड्यूलरिटी के खिलाफ काम कर सकते हैं क्योंकि वे साझा कोड को बदलना कठिन बनाते हैं। क्रॉस-रेपो निर्भरताएं अधिक कठिन बना देती हैं, कोड को और अधिक आसानी से तोड़ सकती हैं (भले ही आपके पास यह जांचने के लिए अच्छी टूलिंग हो) और रेपो-आउट कोड को तोड़ने का खतरा रिफैक्टिंग इंटरफेस को हतोत्साहित करता है, जो चीजों को बनाने के लिए आपके सबसे शक्तिशाली उपकरणों में से एक है। अधिक मॉड्यूलर।
कर्ट जे। सैम्पसन

MicroServices और DDD डिजाइन के बारे में सब कुछ यहाँ रखता है। आपको साझा कोड कम से कम करना चाहिए।
अरुण

49

जैसा कि हम GitHub का उपयोग करते हैं, हमारे पास वास्तव में एक रेपो में कई परियोजनाएं हैं, लेकिन यह सुनिश्चित करें कि उन परियोजनाओं / मॉड्यूल को ठीक से संशोधित किया गया है (हम -api और -core सम्मेलनों + मावेन + स्थैतिक और रनटाइम चेकिंग का उपयोग करते हैं और यहां तक ​​कि एक दिन बूट करने के लिए OSGi पर जा सकते हैं) ।

इस पर क्या बचता है? यदि हम कई परियोजनाओं में कुछ छोटा कर रहे हैं तो हमें कई पुल अनुरोध जारी करने की आवश्यकता नहीं है। मुद्दे और विकी को केंद्रीकृत रखा जाता है आदि।

हम अभी भी प्रत्येक मॉड्यूल / परियोजना को एक उचित स्वतंत्र परियोजना के रूप में मानते हैं और अपने CI सर्वर आदि में उन्हें अलग से निर्मित और एकीकृत करते हैं।


1
बहुत ही रोचक। मुझे संदेह है कि यह जीथब पर एक सामान्य मॉडल है। यदि आप व्यक्तिगत घटक रिलीज़ का सामना करते हैं, तो क्या आप कुछ ऐसा काम करते हैं submodulesया संपूर्ण रिपॉजिटरी को रिलीज़ / टैग करते हैं?
जोहान Sjöberg

submodules अगर हमारे पास है, लेकिन अभी के लिए हम माता-पिता से नीचे संस्करण।
Martijn Verburg

मेरे वर्तमान नियोक्ता में हम एक समान रणनीति का उपयोग करते हैं, और एक परियोजना में सबसे हालिया प्रतिबद्धताओं के बारे में पैकेज मेटाडेटा कलाकृतियों (यानी के परिणाम git log -1 -- <project_dir>) की विभिन्न अभिव्यक्तियों फ़ाइलों में उपयोग करते हैं । यह वास्तव में काफी शानदार है। यह उत्तर अधिक उत्थान के योग्य है।
क्रिस्टोफर

22

मेरे लिए, एक या एक से अधिक भंडार का उपयोग करने में मुख्य अंतर निम्नलिखित प्रश्नों के उत्तर हैं:

  • क्या एक ही टीम द्वारा विकसित कई भाग, एक ही रिलीज़ चक्र, एक ही ग्राहक हैं? फिर एक रिपॉजिटरी को विभाजित करने के कम कारण हैं।
  • क्या कई भाग एक दूसरे पर अत्यधिक निर्भर हैं? इसलिए विभाजन मॉडल, नियंत्रक और यूआई (भले ही वे अलग-अलग हिस्से हों) एक-दूसरे पर उच्च निर्भरता के कारण बहुत समझदार नहीं हैं। लेकिन अगर 2 भागों में केवल एक छोटी निर्भरता होती है, जिसे एक स्थिर इंटरफ़ेस द्वारा लागू किया जाता है जो केवल हर कुछ वर्षों में बदल जाता है, इसलिए 2 भागों को 2 रिपॉजिटरी में विभाजित करना बुद्धिमान होगा।

एक उदाहरण के रूप में, मेरे पास एक छोटा अनुप्रयोग (केवल क्लाइंट) है, जो एक तोड़फोड़ भंडार की "गुणवत्ता" की जांच करता है। मुख्य कार्यान्वयन है, जो कमांड लाइन से शुरू किया जा सकता है, और जावा 6 के साथ अच्छी तरह से काम करता है। लेकिन मैंने एक यूआई लागू करना शुरू कर दिया है, जो जावा 8 के हिस्से के रूप में जावाएफएक्स का उपयोग करता है। इसलिए मैंने 2 को विभाजित किया है, और एक अन्य बनाया है दूसरा भंडार (एक दूसरी निर्माण प्रक्रिया के साथ), अलग-अलग अनुसूची के साथ, ...

मुझे उपरोक्त उत्तर पसंद हैं (उन्हें वोट दिया), लेकिन मुझे लगता है कि वे पूरी सच्ची कहानी नहीं हैं। इसलिए मैं रिपॉजिटरी को भी विभाजित करने के लिए तर्क जोड़ना चाहता था। तो असली जवाब (जब बिछड़ना है) बीच में कहीं हो सकता है ...


4

यह हो सकता है कि git-subtree (देखें Atlassian ब्लॉग , मध्यम ब्लॉग या कर्नेल लिंक ) आपके लिए एक अच्छा फिट होगा। इसलिए, आपकी प्रत्येक शीर्ष स्तरीय परियोजना संभवत: अलग-अलग संस्करण (नों) में उप-सेट का उपयोग करेगी।


0

आपके उदाहरण से, रिपॉजिटरी को इस बात पर निर्भर करना चाहिए कि वे कितने अन्योन्याश्रित हैं। MicroServices और Domain Driven Design डिजाइन करने के बारे में सभी तर्क यहां लागू होते हैं: कुछ मामलों में डुप्लिकेट कोड स्वीकार्य है, इंटरफेस के साथ काम करते हैं, संगतता को तब तक नहीं तोड़ते हैं जब तक कि आपको वास्तव में नहीं करना है, आदि।

अब मेरे विचार में एक यूआई बैकएंड से स्वतंत्र होना चाहिए। इसलिए यूआई प्रोजेक्ट रिपॉजिटरी में आमतौर पर यूआई कोड और क्लाइंट कंट्रोलर होना चाहिए। क्लाइंट नियंत्रक सेवा नियंत्रकों के साथ एक सार तरीके से कनेक्ट होगा। वे एक सेवा क्लाइंट / एपीआई एब्सट्रैक्शन का उपयोग करेंगे जो कि सेवा से अलग से संस्करणबद्ध है, ताकि ग्राहक (एस) को तोड़े बिना एक सेवा को अपडेट किया जा सके (कई अलग-अलग ग्राहक हो सकते हैं)।

तो एक सेवा स्वयं ही अपनी रिपॉजिटरी होनी चाहिए। मेरे विचार में, सेवा केवल कुछ एकल-बिंदु-थ्रूथ व्यापार तर्क का एक आवरण है। इसलिए व्यावसायिक तर्क आम तौर पर उस सेवा तकनीक से अलग होना चाहिए जो इसे होस्ट करती है। दूसरी ओर, रिपॉजिटरी कार्यान्वयन आम तौर पर व्यावसायिक तर्क से बहुत कसकर जुड़ा होता है, ताकि इसे उसी रिपॉजिटरी में एकीकृत किया जा सके। लेकिन वहां भी आपका माइलेज अलग-अलग हो सकता है।

बेशक, सरल परियोजनाएं जो प्रौद्योगिकी के संदर्भ में बहुत अधिक बदलने या कई स्टैक का समर्थन करने की संभावना नहीं हैं, जहां सभी यूआई को एक ही स्रोत से होस्ट किया जा सकता है क्योंकि बैकएंड और बैकएंड सेवाएं आमतौर पर केवल उसी क्लाइंट द्वारा उपयोग की जाती हैं, जो अधिक लाभ उठा सकती हैं। कसकर एकीकृत रिपोजिटरी।

उस स्थिति में आप शायद केवल एक रिपॉजिटरी में पूर्ण ऊर्ध्वाधर होने के साथ ठीक होंगे, और यह सुनिश्चित करने पर ध्यान केंद्रित करेंगे कि आपके कार्यात्मक डोमेन अपने स्वयं के रिपॉजिटरी में ठीक से अकेले खड़े हैं। फिर भी आपके पास छोटे रिपॉजिटरी के सबसे अधिक फायदे हैं, और थोड़ा उपरि अन्यथा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.