हम परियोजनाएं कर रहे हैं, लेकिन हम परियोजनाओं के बीच बहुत सारे कोड का पुन: उपयोग करते हैं और बहुत सारे पुस्तकालय हैं जिनमें हमारा सामान्य कोड है। जैसा कि हम नई परियोजनाओं को लागू करते हैं, हम सामान्य कोड को बाहर करने और पुस्तकालयों में डालने के लिए और अधिक तरीके ढूंढते हैं। पुस्तकालय एक-दूसरे पर निर्भर करते हैं, और परियोजनाएँ पुस्तकालयों पर निर्भर करती हैं। प्रत्येक परियोजना, और उस परियोजना में उपयोग किए जाने वाले सभी पुस्तकालय, उन सभी पुस्तकालयों के समान संस्करण का उपयोग करने की आवश्यकता होती है, जिनका वे उल्लेख कर रहे हैं। यदि हम एक सॉफ्टवेयर जारी करते हैं तो हमें बग को ठीक करना होगा और हो सकता है कि कई वर्षों तक, कभी-कभी दशकों तक नई सुविधाएँ जोड़ें। हमारे पास लगभग एक दर्जन पुस्तकालय हैं, परिवर्तन अक्सर दो से अधिक में कटौती करते हैं, और कई टीमें समानांतर में कई परियोजनाओं पर काम करती हैं, जिससे इन सभी पुस्तकालयों में समवर्ती परिवर्तन होते हैं।
हमने हाल ही में प्रत्येक पुस्तकालय और प्रत्येक परियोजना के लिए git और repositories स्थापित किया है। हम एक सामान्य भंडार के रूप में उपयोग करते हैं, फीचर शाखाओं पर नया सामान बनाते हैं, फिर पुल अनुरोध करते हैं और समीक्षा के बाद ही उन्हें मर्ज करते हैं।
परियोजनाओं में हमें जिन मुद्दों से निपटना पड़ता है, उनमें से कई हमें कई पुस्तकालयों और परियोजना के विशिष्ट कोड में परिवर्तन करने की आवश्यकता होती है। इनमें अक्सर पुस्तकालय इंटरफेस के परिवर्तन शामिल होते हैं, जिनमें से कुछ असंगत होते हैं। (यदि आपको लगता है कि यह गड़बड़ लगता है: हम हार्डवेयर के साथ इंटरफेस करते हैं, और जेनेरिक इंटरफेस के पीछे विशिष्ट हार्डवेयर छिपाते हैं। लगभग हर बार जब हम कुछ अन्य वेंडर के हार्डवेयर को एकीकृत करते हैं, तो हम उन मामलों में भाग लेते हैं जो हमारे वर्तमान इंटरफेस का अनुमान नहीं था, और इसलिए उन्हें परिष्कृत करना होगा।) उदाहरण के लिए, एक परियोजना की कल्पना P1
लाइब्रेरी का उपयोग कर L1
, L2
और L3
। L1
उपयोग भी करता है L2
और L3
, और L2
उपयोग भी करता है L3
। निर्भरता ग्राफ इस तरह दिखता है:
<-------L1<--+
P1 <----+ ^ |
<-+ | | |
| +--L2 |
| ^ |
| | |
+-----L3---+
अब इस परियोजना के लिए एक विशेषता की कल्पना करें P1
और इसमें L3
किस परिवर्तन की आवश्यकता है L3
। अब परियोजनाओं P2
और P3
मिश्रण में जोड़ें , जो इन पुस्तकालयों को भी संदर्भित करता है। हम उन सभी को नए इंटरफ़ेस में बदलने, सभी परीक्षण चलाने और नए सॉफ़्टवेयर को तैनात करने का जोखिम नहीं उठा सकते। तो विकल्प क्या है?
- में नया इंटरफ़ेस लागू करें
L3
- के लिए एक पुल अनुरोध
L3
करें और समीक्षा के लिए प्रतीक्षा करें - परिवर्तन को मर्ज करें
- की एक नई रिलीज़ बनाएँ
L3
- इस सुविधा को नई रिलीज़ के
P1
संदर्भ में बनाकर काम करना शुरू करेंL3
, फिरP1
फ़ीचर की सुविधा शाखा पर लागू करें - एक पुल अनुरोध करें, इसकी समीक्षा करें और विलय कर दें
(मैंने अभी देखा कि मैं स्विच करना भूल गया L1
और L2
नई रिलीज़ के लिए। और मुझे यह भी नहीं पता है कि मुझे यह कहाँ रहना है, क्योंकि इसे समानांतर में करने की आवश्यकता होगी P1
...)
यह एक थकाऊ, त्रुटि-प्रवण, और इस सुविधा को लागू करने के लिए बहुत लंबी प्रक्रिया है, इसके लिए स्वतंत्र समीक्षा की आवश्यकता होती है (जिसकी समीक्षा करना बहुत कठिन है), बिल्कुल भी पैमाने पर नहीं है, और हमें व्यापार से बाहर करने की संभावना है क्योंकि हम इस प्रक्रिया में इतना घिर जाना कि हमें कभी कुछ नहीं करना है।
लेकिन हम बहुत अधिक उपरि के बिना नई परियोजनाओं में नई सुविधाओं को लागू करने की अनुमति देने वाली प्रक्रिया बनाने के लिए ब्रांचिंग और टैगिंग को कैसे नियोजित करते हैं?