सामान्य नेस्टेड उप-मॉड्यूल के साथ गिट रिपोजिटरी का आयोजन


50

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

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

अनुप्रयोगों की एक जोड़ी की आपूर्ति: studioऔर player, और निर्भर पुस्तकालयों core, graphऔर network, जहां निर्भरता इस प्रकार हैं:

  • core स्टैंडअलोन है
  • graphपर निर्भर करता है core(उप-मॉड्यूल पर ./libs/core)
  • networkपर निर्भर करता है core(उप-मॉड्यूल पर ./libs/core)
  • studioपर निर्भर करता है graphऔर network(कम से उप मॉड्यूल ./libs/graphऔर ./libs/network)
  • playerपर निर्भर करता है graphऔर network(कम से उप मॉड्यूल ./libs/graphऔर ./libs/network)

मान लीजिए कि हम CMake का उपयोग कर रहे हैं और इन परियोजनाओं में से प्रत्येक में यूनिट परीक्षण और सभी कार्य हैं। (सहित प्रत्येक परियोजना studioऔर player) कोड मैट्रिक्स, इकाई परीक्षण, आदि प्रदर्शन करने के लिए स्टैंडअलोन संकलित किया जा करने में सक्षम होना चाहिए

बात यह है कि एक पुनरावर्ती है git submodule fetch, तो आपको निम्नलिखित निर्देशिका संरचना मिलती है:

studio/
studio/libs/                    (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/         (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/       (sub-module depth: 2)
studio/libs/network/libs/core/

ध्यान दें कि परियोजना coreमें दो बार क्लोन किया जाता है studio। इस व्यर्थ डिस्क स्थान के अलावा, मुझे बिल्ड सिस्टम की समस्या है क्योंकि मैं coreदो बार निर्माण कर रहा हूं और मुझे संभावित रूप से दो अलग-अलग संस्करण मिलेंगे core

सवाल

मैं उप-मॉड्यूल को कैसे व्यवस्थित करूं ताकि मुझे सामान्य नेस्टेड उप-मॉड्यूल की कई प्रतियां प्राप्त किए बिना संस्करण निर्भरता और स्टैंडअलोन बिल्ड मिल जाए?

संभावित समाधान

यदि पुस्तकालय निर्भरता कुछ हद तक एक सुझाव है (अर्थात "संस्करण एक्स के साथ काम करने के लिए जाना जाता है" या "केवल संस्करण एक्स को आधिकारिक तौर पर" फैशन "का समर्थन किया जाता है और संभावित आश्रित अनुप्रयोग या लाइब्रेरी जो भी संस्करण पसंद करते हैं, उसके निर्माण के लिए जिम्मेदार होते हैं, फिर मैं निम्नलिखित परिदृश्य की कल्पना कर सकता हूं:

  • के लिए बिल्ड सिस्टम है graphऔर networkउन्हें बताएं कि कहां ढूंढना है core(जैसे संकलक के माध्यम से पथ शामिल है)। दो बिल्ड लक्ष्य, "स्टैंडअलोन" और "निर्भरता" को परिभाषित करें, जहां "स्टैंडअलोन" "निर्भरता" पर आधारित है और इसमें स्थानीय coreउप-मॉड्यूल को इंगित करने के लिए शामिल पथ को जोड़ता है ।
  • एक अतिरिक्त निर्भरता का परिचय दें: studioपर core। फिर, studioबनाता है core, coreउप-मॉड्यूल की अपनी प्रतिलिपि में शामिल पथ सेट करता है , फिर बनाता है graphऔर network"निर्भरता" मोड में।

परिणामी फ़ोल्डर संरचना इस प्रकार है:

studio/
studio/libs/                    (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/         (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/       (empty folder, sub-modules not fetched)

हालाँकि, इसके लिए कुछ बिल्ड सिस्टम मैजिक की आवश्यकता होती है (मुझे पूरा विश्वास है कि यह सीएमके के साथ किया जा सकता है) और संस्करण अपडेट के हिस्से पर थोड़ा सा मैनुअल काम (अपडेट graphको अपडेट करने coreऔर सभी परियोजनाओं में networkएक संगत संस्करण प्राप्त करने की भी आवश्यकता हो सकती है core) ।

इस पर कोई विचार?


ध्यान दें कि यह समस्या cmake के लिए विशिष्ट नहीं है: यह किसी भी सिस्टम सहित किसी भी निर्माण प्रणाली के लिए मौजूद है! (यानी जब यह इरादा है कि सुपर-प्रोजेक्ट सिर्फ लाइब्रेरी स्रोतों को जोड़ते हैं; जिसमें हेडर-ओनली लाइब्रेरी शामिल हैं)
एमएम

जवाबों:


5

मुझे इस पार्टी में बहुत देर हो चुकी है, लेकिन आपके सवाल का अभी भी पूरा जवाब नहीं मिल रहा है, और यह Google का एक बहुत ही प्रमुख हिट है।

मुझे C ++ / CMake / Git / Submodules के साथ ठीक वैसी ही समस्या है और मुझे MATLAB / Git / Submodules के साथ भी ऐसी ही समस्या है, जिसे कुछ अतिरिक्त विचित्रता मिलती है क्योंकि MATLAB संकलित नहीं है। मुझे यह वीडियो हाल ही में आया था , जो "समाधान" का प्रस्ताव देता है। मुझे समाधान पसंद नहीं है, क्योंकि यह अनिवार्य रूप से सबमॉड्यूल्स को दूर फेंकने का मतलब है, लेकिन यह समस्या को खत्म करता है। यह वैसा ही है जैसा @errordeveloper अनुशंसा करता है। प्रत्येक प्रोजेक्ट में कोई सबमॉड्यूल नहीं है। एक परियोजना का निर्माण करने के लिए, इसे बनाने के लिए एक सुपर-प्रोजेक्ट बनाएं और इसे अपनी निर्भरता के लिए एक भाई के रूप में शामिल करें।

तो आपकी परियोजना के विकास की graphतरह लग सकता है:

buildgraph/graph
buildgraph/core

और फिर स्टूडियो के लिए आपका प्रोजेक्ट हो सकता है:

buildstudio/studio
buildstudio/graph
buildstudio/network
buildstudio/core

सुपर-प्रोजेक्ट सिर्फ एक मुख्य CMakeLists.txtऔर सबमॉड्यूल का एक समूह है। लेकिन किसी भी परियोजना में कोई भी सबमॉड्यूल नहीं है।

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


1

मुझे लगता है कि जब आप दोनों graphऔर networkसबमॉड्यूल्स को एकीकृत करते हैं studio, तो आपको हमेशा coreइतिहास में दिए गए समय पर एक ही संस्करण होना चाहिए studio। मैं simlink हैं studio/libs/coreमें submodule studio/libs/{graph,network}/libs

अपडेट करें:

मैंने आपके द्वारा बताई गई निर्भरता के साथ कई रिपॉजिटरी का क्रेट किया:

./core      <--- (v2)
./graph
./graph/libs
./graph/libs/core  <--- (v2)
./graph/.gitmodules
./network
./network/libs
./network/libs/core  <--- (v1)
./network/.gitmodules
./studio
./studio/libs
./studio/libs/graph
./studio/libs/graph/libs
./studio/libs/graph/libs/core <--- (v1)
./studio/libs/graph/.gitmodules
./studio/libs/network
./studio/libs/network/libs
./studio/libs/network/libs/core  <--- (v1)
./studio/libs/network/.gitmodules
./studio/studio
./studio/.gitmodules

v1और के v2दो अलग-अलग संस्करण हैं coregraphसंस्करण 2 को संभालता है, जबकि networkकुछ काम की आवश्यकता होती है और संस्करण 1 पर अटक जाती है । काम करने के कार्यक्रम के लिए studio, coreदोनों बिंदुओं के स्थानीय एम्बेडेड संस्करण v1। अब, बिल्ड परिप्रेक्ष्य के अलावा, सबमॉड्यूल के साथ सब कुछ अच्छा काम करता है।

अब मैं निम्नलिखित निर्देशिका को हटा सकता हूं:

./studio/libs/network/libs/core

और इसे एक प्रतीकात्मक लिंक से प्रतिस्थापित करें:

./studio/libs/network/libs/core@ -> ../../graph/libs/core/

मैं स्थानीय रूप से यह परिवर्तन करता हूं और coreअंदर के दो अलग-अलग संस्करण होने की क्षमता खो देता studioहूं, लेकिन मैं केवल coreएक बार निर्माण करता हूं । जब v2मैं करने के लिए उन्नयन के लिए तैयार हूँ, मैं कर सकता हूँ:

 git submodule update # (--rebase ?)

... स्टूडियो / लीब / नेटवर्क के अंदर।


प्रतीकात्मक लिंक विचार ने मेरे दिमाग को पार कर दिया, लेकिन यह एक गैर-समाधान है। यदि आप graph/libs/coreबाहर से लिंक करते हैं, तो आप सबमॉड्यूल का उपयोग नहीं कर रहे हैं। यदि आप studio/libs/coreउप-मॉड्यूल के स्वयं के पुस्तकालयों में से एक से लिंक करते हैं, तो आप किसको चुनते हैं, graphया network? इसके अलावा, क्या होता है जब यह तीन या अधिक परतों में गहरा होता है? अंत में, यदि coreसंशोधन की एक सीमा हो सकती है तो क्या होगा । यह स्पष्ट नहीं है कि आप के किसी भी प्रकार से लिंक करना चाहते है coreकि graphऔर networkप्रयोग कर रहे हैं।
एंड्रे कारन

"कौन सा आप चयन करते हैं ?" : coreमूल coreलाइब्रेरी से प्राप्त एक सबमॉड्यूल होगा , एक ऐसे संस्करण में अपडेट किया जाएगा जो दोनों के लिए अनुकूल हो graphऔर network(आपको तय करना होगा कि कौन सा अच्छा है)। प्रतीकात्मक लिंक स्थानीय graphऔर networkसबमॉड्यूल (अनफ़िटेड) में जोड़े जाएंगे।
coredump

1
सांकेतिक लिंक आप में जोड़ने के लिए प्रस्ताव graphऔर networkअपने स्वयं के भंडार (जैसे कहीं में और बाहर बिंदु होगा studioपरियोजना)। वे कैसे जानते हैं कि प्रतीकात्मक लिंक का उपयोग करने के लिए अपने स्वयं के उप-मॉड्यूल का उपयोग कब करना है? शायद आपको अपनी सोच को प्रदर्शित करने के लिए एक उदाहरण जोड़ना चाहिए।
आंद्रे कैरन 3

0

मैं इसे केवल एक के उप-मॉड्यूल की गहराई तक समतल कर दूंगा और इसमें एक भंडार होगा जो सभी मॉड्यूल को उप-मॉड्यूल के रूप में रखेगा और README और बिल्ड स्क्रिप्ट के अलावा और कुछ नहीं होगा। इसकी निर्भरता को जोड़ने वाले प्रत्येक पैकेज के लिए एक अलग बिल्ड स्क्रिप्ट होगी। अन्यथा आपके पास पैकेज के लिए एक अलग रेपो हो सकता है।


1
मुझे यकीन नहीं है कि यह मेरे पोस्ट में स्पष्ट था, लेकिन मेरे पास कई एप्लिकेशन हैं जो एक ही पुस्तकालयों पर निर्भर हैं और मैं अनुप्रयोगों के लिए पुस्तकालयों के लिए बिल्ड स्क्रिप्ट की नकल नहीं करना चाहता।
एंड्रे कैरन

3
आपको अपने जवाब को विस्तृत रूप से प्रदर्शित करना चाहिए कि यह विभिन्न मुद्दों को कैसे संबोधित करता है। यह मेरे लिए बिल्कुल स्पष्ट नहीं है कि आप निर्भरता को कैसे लिंक करते हैं, जो कि संदर्भ के आधार पर निर्भर पुस्तकालयों के समान स्थान पर नहीं है।
आंद्रे कारन

0

मैं सबमॉडल्स का उपयोग नहीं करूंगा।

यह लुभावना है, वही जिसका उपयोग svn-externals के मामले में किया जाता है। हालाँकि, क्या आप सुनिश्चित कर सकते हैं कि उन सभी परियोजनाओं को जो आप एक वर्ष में एक ही स्थान पर हैं। पाँच में क्या?

इसलिए, मैं बस अपनी परियोजना में सभी आवश्यक निर्भरता की प्रतिलिपि बना रहा हूं। इसका मतलब है कि जब तक मेरा रेपो वैध है, मैं सटीक स्थिति की जांच कर सकता हूं।

मूल रूप से, मेरे पास एक फ़ोल्डर संरचना इस प्रकार है:

myproject/... [sources etc]
ext/ [third-party dependencies]


e.g. ext/boost, ext/cppunit

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

इसके अलावा, यहाँ वर्णित के रूप में सबमॉड्यूल के साथ समस्याओं का एक गुच्छा है


मुझे यकीन है कि वे सही स्थान पर हैं क्योंकि मैं उन सभी को बनाए रख रहा हूं :-) इसके अलावा, पुनर्वितरण स्थितियों के कारण परियोजनाओं की प्रतिलिपि बनाने के बारे में सावधान रहें।
एंड्रे कैरन

ठीक है, यह समस्या को कम करता है। और लाइसेंसिंग: हां, आपको सावधान रहना होगा, लेकिन यह पूरी तरह से अलग समस्या है।
विल्बर्ट

0

यहां बिल्कुल वैसी ही समस्या का सामना करना पड़ रहा है। समाधानों में से एक कुछ रेपो के लिए हो सकता है libsकि पकड़ होगा core, network, graphsubmodules और बस CMakeLists कि libs जहां इसकी निर्भरता को खोजने के लिए के प्रत्येक बता जाएगा। अब प्रत्येक एप्लिकेशन libsसबमॉडल के रूप में होगा और केवल आवश्यक कामों का उपयोग करेगा ।

प्रत्येक कार्य का परीक्षण 2 तरीकों से किया जा सकता है:

  • अलग-अलग एप्लिकेशन के रूप में core_testing, graph_testing, network_testing रखें
  • परीक्षण किए गए सर्वरों में परीक्षण किए गए कामों को तैनात करें और सेमीक का उपयोग करके परीक्षण चलाते समय उन्हें ढूंढें

क्या यह सभी अन्य सभी देयताओं को उपलब्ध नहीं कराता है?
एंड्रे कारन

डिफ़ॉल्ट रूप से, हाँ। लेकिन यह लिबास-स्तरीय cmakelists में तय किया जा सकता है। अगर graphइसके बारे में जानने की जरूरत नहीं है network- networkसब graph-ir को पास- संबंधी सामान न दें
मैक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.