जब आपका सारा विकास शाखाओं पर हो तो कैसे रिफैक्ट करें?


24

मेरी कंपनी में, हमारे सभी विकास (बग फिक्स और नई सुविधाएँ) अलग-अलग शाखाओं पर किए गए हैं। जब यह पूरा हो जाता है, तो हम इसे QA को भेज देते हैं जो इसे उस शाखा पर परीक्षण करता है, और जब वे हमें हरी बत्ती देते हैं, तो हम इसे अपनी मुख्य शाखा में विलय कर देते हैं। यह एक दिन और एक वर्ष के बीच कहीं भी ले जा सकता है।

यदि हम किसी शाखा में किसी भी रिफैक्टरिंग को निचोड़ने का प्रयास करते हैं, तो हमें नहीं पता कि यह कब तक "बाहर" रहेगा, इसलिए जब यह वापस मर्ज हो जाता है, तो यह कई संघर्षों का कारण बन सकता है।

उदाहरण के लिए, मान लें कि मैं एक फ़ंक्शन का नाम बदलना चाहता हूं क्योंकि जिस फ़ीचर पर मैं काम कर रहा हूं वह इस फ़ंक्शन का भारी उपयोग कर रहा है, और मैंने पाया कि इसका नाम वास्तव में इसके उद्देश्य के लिए फिट नहीं है (फिर, यह सिर्फ एक उदाहरण है)। इसलिए मैं चारों ओर घूमता हूं और इस फ़ंक्शन के हर उपयोग को ढूंढता हूं, और उन सभी को इसके नए नाम में बदल देता हूं, और सब कुछ पूरी तरह से काम करता है, इसलिए मैं इसे क्यूए को भेज देता हूं।

इस बीच, नया विकास हो रहा है, और मेरा पुनर्नामित फ़ंक्शन उन शाखाओं में से किसी पर मौजूद नहीं है, जिन्हें मुख्य बंद किया जा रहा है। जब मेरा मुद्दा वापस मर्ज हो जाता है, तो वे सभी को तोड़ने जा रहे हैं।

क्या इससे निपटने का कोई तरीका है?

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


आप किस संस्करण नियंत्रण का उपयोग कर रहे हैं? डीवीसीएस और एक केंद्रीकृत सर्वर मॉडल के लिए अलग-अलग दृष्टिकोण हैं। इसके अलावा, किन विकास शाखाओं को बंद किया जा रहा है? यदि एक सुविधा शाखा को स्वीकार किया जाता है, तो अन्य देव शाखाएं कैसे परिवर्तन उठाती हैं?

2
एक तरफ के रूप में, वर्तमान शाखा संरचना का एक चित्र वास्तव में मददगार हो सकता है। यह काफी संभव है कि रिफैक्टरिंग के साथ समस्या की जड़ कुछ के कारण होती है ... अपरंपरागत शाखाओं में बंटी नीतियों (देखें एक उदाहरण के लिए प्रोग्रामर.स्टैकएक्सचेंज .com/questions/210360 )। मैं कुछ विचारों और पृष्ठभूमि प्राप्त करने के लिए vance.com/steve/perforce/Branching_Strategies.html पढ़ने का भी सुझाव दूंगा (यदि मैं इस प्रश्न का उत्तर देने में सक्षम हूं जो एक प्रमुख संदर्भ बिंदु होगा)।

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

1
@ मट्ट्नज़: आप काफी सही कह रहे हैं। वे एक वास्तविक क्यूए टीम नहीं हैं। वे ज्यादातर ग्राहक समर्थन कर रहे हैं। मुझे लगता है कि उनकी बहुत सारी जिम्मेदारियों को वापस देव टीम में स्थानांतरित कर दिया जाना चाहिए क्योंकि वे केवल उन सभी चीजों को संभाल नहीं सकते हैं जो हम उन पर डंप करते हैं, लेकिन यह एक प्रबंधन मुद्दा है और एक लड़ाई जिसे मुझे जीतना बाकी है।
एमपीएन

3
आपने मेरी खुदाई को याद किया। टेस्ट! = क्यूए। क्यूए गुणवत्ता की देखरेख करता है, और इसका उद्देश्य व्यावसायिक परिणामों में सुधार करना है। उन्हें खोजने के द्वारा दोषों की अनुपस्थिति को साबित करने का प्रयास परीक्षण।
मटनज़

जवाबों:


12

कई समस्याएं हैं जो इस वातावरण में चुनौतीपूर्ण बनाने के लिए एक साथ मिश्रण कर रही हैं। इसमें मिश्रित कुछ गैर-तकनीकी समस्याएं हैं ("लेकिन यह एक प्रबंधन मुद्दा है और एक लड़ाई जिसे मुझे जीतना बाकी है")।

लंबे समय से चल रही शाखा को देखने के लिए पहली समस्या है। डेवलपर की दृष्टि से इन परिवर्तनों को ट्रैक करने में इन शाखाओं को कठिनाई होती है। इस पर बात करो:

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

एक और मुद्दा जो इसमें मिला रहा है, वह यह है कि मैंने उपरोक्त बिंदुओं के साथ गठबंधन किया, समय के साथ शाखा की बदलती भूमिका है। यह एक विकास शाखा के रूप में शुरू होता है, जहां डेवलपर्स प्रतिबद्ध होते हैं, और फिर एक परीक्षण क्षेत्र बन जाता है (क्या परीक्षण यहां किया जा रहा है जो पूरे अनुप्रयोग में सार्थक हो सकता है?), जिसे तब स्थिर (और संभवतः जारी) में विलय कर दिया जाता है - क्या यह है? फिर से परीक्षण किया;)।

छोटी सुविधा के साथ समय समाप्त होने के बाद रिफैक्टिंग के लिए अन्य शाखाओं द्वारा उठाया जाना सक्षम होना आसान है।

संपूर्ण पर्यावरण प्राप्त करने के लिए डेवलपर्स को प्रोत्साहित करें। सिर्फ चेरी-पिकिंग परिवर्तन के कारण हो सकता है ... दिलचस्प डेवलपर वातावरण कहता है। जबकि चेरी-पिकिंग के अपने उपयोग हैं, इसके लिए एक शाखा में परिवर्तनों को खींचने का डिफ़ॉल्ट मोड चिंताजनक हो सकता है।

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

डेवलपर्स के लिए कोड की गुणवत्ता का स्वामी होना महत्वपूर्ण है। जबकि सुविधाओं की दिशा बाहर से आती है, और समय आबंटन अक्सर हमारे अपने नहीं होते हैं, कोड की गुणवत्ता कुछ ऐसी होती है जिस पर गर्व करना और उसके लिए समय निकालना आवश्यक है।

तकनीकी ऋण से निपटने के लिए समय आवंटित करने की तलाश में आपको निम्नलिखित प्रश्न उपयोगी लग सकते हैं:

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

अक्सर यह इंगित करना आवश्यक है कि तकनीकी ऋण से निपटने के लिए आरओआई सुविधाओं और विकास टीम से बग फिक्स के लिए तेजी से बदलाव का समय है।


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

3

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

उदाहरण 1. मान लें कि मेरे पास थिंग है, इसे फंक्शन, इंटरफ़ेस, मॉड्यूल, या जो भी हो। और मैं इसे रिफ्लेक्टर करना चाहता हूं। मैं एक ही कोडबेस में थिंग 2 बना रहा हूं, यह थिंग का रिफैक्टेड वर्जन है। जब यह किया जाता है और परीक्षण किया जाता है, तो मैं थिंग 2 के साथ इसे बदलने के लिए, थिंग को संदर्भित करने वाली हर चीज को फिर से तैयार कर रहा हूं। आमतौर पर इस कदम में अपेक्षाकृत कम समय लगता है।

यदि वास्तविक रीफैक्टरिंग में बिना पेंच के टीम के साथ तालमेल रखने में बहुत अधिक समय लगता है, तो मैं सभी प्रासंगिक विशेषताओं को ले रहा हूं, और उन्हें समानांतर में भी रिफैक्ट कर रहा हूं।

उदाहरण 2. मेरे पास नया रेंडरिंग बैकएंड है, जो पुराने के रिफैक्टेड वर्जन है। लेकिन यह पुराने प्रतिपादन दृश्य के साथ संगत नहीं है। इस प्रकार, मुझे रीपेक्ट करने की जरूरत है। और फिर से: एक ही कोडबेस में। जब सब कुछ हो जाता है, तो मैं सिर्फ दृश्यपटल उदाहरण के वर्ग को बदल रहा हूं, आदर्श रूप से यह एक छोटा वचन लेगा।

हाँ, पुनरावर्ती एक निष्कर्ष पर आ सकता है कि सब कुछ समानांतर में किया जाना चाहिए। लेकिन यह आमतौर पर तब होता है जब कोडबेस में बहुत अधिक युग्मन होता है, या यह बहुत तेजी से बदल रहा है।

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

आम तौर पर, विचार नई सुविधाओं को समानांतर में तैयार करने और उन्हें एक छोटे कदम से उपयोग करने के लिए स्विच करने के लिए है।

जॉन कार्मैक इस (या कम से कम परिचित) दृष्टिकोण का उपयोग करता है, शायद उसका ब्लॉग पोस्ट इसे बेहतर बताता है: (लिंक)


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

1

यह तकनीकी पक्ष में एक कठिनाई की तरह लग सकता है जब वास्तव में यह आवश्यकताओं की ओर होता है।

जहाँ विकास विभिन्न शाखाओं में विभिन्न आवश्यकताओं की ओर उन्मुख होता है वही वास्तविक कठिनाई है। टीम के प्रबंधकों और वास्तुकारों को ऐसे निर्णय लेने चाहिए जो विभिन्न व्यावसायिक आवश्यकताओं को सह-अस्तित्व में लाने में सक्षम हों।

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

ZBB का अर्थ है जीरो-आधारित बजट । सह-देवता कहने से मेरा मतलब है कि कुछ लोग समानांतर प्रोग्रामिंग में काम कर रहे हैं।


2
"ZBB" और "Co-Dev" क्या हैं?
gnat

ZBB - en.wikipedia.org/wiki/Zero-based_budgeting । सह-देवता कहने से मेरा मतलब है कि कुछ लोग समानांतर प्रोग्रामिंग में काम कर रहे हैं।
योसी डहरी

1

समस्या मुझे यह लगती है कि आप शाखाओं पर बहुत अधिक समय तक काम कर रहे हैं। संघर्षों की लागत तेजी के साथ बढ़ती है जब हर कोई शाखा पर रहता है, तो बहुत लंबे संघर्षों के साथ आपके पास कोई भी रिफैक्टिंग करने की संभावना कम होती है।


0

आपकी समस्या वह शाखा मॉडल है जिसका आप उपयोग कर रहे हैं। आप एक शाखा में विकसित हो सकते हैं, और जब पूर्ण और QA के लिए तैयार हो जाता है, तो शाखा एक 'मध्यवर्ती ट्रंक' में विलय हो जाती है, जिसे कभी-कभी एकीकरण या परीक्षण कहा जाता है। जब आप अगली विशेषता विकसित करते हैं, तो आप इसके बजाय इस मध्यवर्ती ट्रंक से शाखा कर सकते हैं।

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

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

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