मर्ज (संस्करण नियंत्रण)

संस्करण नियंत्रण में, विलय (जिसे एकीकरण भी कहा जाता है) एक मौलिक ऑपरेशन है जो फ़ाइलों के संस्करण-नियंत्रित संग्रह में किए गए कई परिवर्तनों को समेटता है। अधिकतर, यह तब आवश्यक होता है जब किसी फ़ाइल को दो स्वतंत्र शाखाओं में संशोधित किया जाता है और बाद में विलय कर दिया जाता है। परिणाम फ़ाइलों का एक एकल संग्रह है जिसमें परिवर्तनों के दोनों सेट शामिल हैं।

कुछ मामलों में, मर्ज स्वचालित रूप से किया जा सकता है, क्योंकि परिवर्तनों को फिर से बनाने के लिए पर्याप्त इतिहास जानकारी है, और परिवर्तन में संघर्ष नहीं होता है। अन्य मामलों में, व्यक्ति को यह तय करना होगा कि परिणामी फ़ाइलों में वास्तव में क्या होना चाहिए। कई संशोधन नियंत्रण सॉफ़्टवेयर टूल में मर्ज क्षमताएं शामिल हैं।

विलय के प्रकार
मर्ज दो प्रकार के होते हैं: असंरचित और संरचित।

असंरचित विलय
असंरचित मर्ज कच्चे पाठ पर काम करता है, आमतौर पर पाठ की पंक्तियों को परमाणु इकाइयों के रूप में उपयोग करता है। इयूनिक्स टूल्स (डिफ/पैच) और सीवीएस टूल्स (एसवीएन, गिट) इसका उपयोग करते हैं। यह सीमित है, क्योंकि पाठ की एक पंक्ति स्रोत कोड की संरचना का प्रतिनिधित्व नहीं करती है।

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

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

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

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

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

जो अनुभाग तीनों फ़ाइलों में अलग-अलग हैं, उन्हें विरोध की स्थिति के रूप में चिह्नित किया जाता है और उपयोगकर्ता को समाधान के लिए छोड़ दिया जाता है।

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

पुनरावर्ती तीन-तरफ़ा मर्ज
तीन-तरफ़ा मर्ज आधारित संशोधन नियंत्रण उपकरण व्यापक हैं, लेकिन तकनीक मूल रूप से मर्ज किए जाने वाले संस्करणों के एक सामान्य पूर्वज को खोजने पर निर्भर करती है।

कुछ अजीब मामले हैं, विशेष रूप से क्रिस-क्रॉस मर्ज, जहां संशोधित संस्करणों का एक अद्वितीय अंतिम सामान्य पूर्वज मौजूद नहीं है।

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

(Git का पुनरावर्ती मर्ज कार्यान्वयन अन्य अजीब मामलों को भी संभालता है, जैसे एक फ़ाइल को एक संस्करण में संशोधित किया जा रहा है और दूसरे में नाम बदला जा रहा है, लेकिन वे इसके तीन-तरफ़ा मर्ज कार्यान्वयन के विस्तार हैं; विलय के लिए तीन संस्करण खोजने की तकनीक का हिस्सा नहीं हैं।)

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

फ़ज़ी पैच एप्लिकेशन
पैच (कंप्यूटिंग) एक फ़ाइल है जिसमें फ़ाइल में परिवर्तनों का विवरण होता है। यूनिक्स दुनिया में, पाठ फ़ाइलों में परिवर्तनों को diff -u द्वारा निर्मित प्रारूप में पैच के रूप में प्रसारित करने की परंपरा रही है। इस प्रारूप का उपयोग पैच (यूनिक्स) द्वारा किसी टेक्स्ट फ़ाइल, या टेक्स्ट फ़ाइलों वाली निर्देशिका संरचना में परिवर्तनों को फिर से लागू करने (या हटाने) के लिए किया जा सकता है।

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

जैसे CVS की शुरुआत diff3 पर स्क्रिप्ट के एक सेट के रूप में हुई, GNU आर्क की शुरुआत पैच पर स्क्रिप्ट के एक सेट के रूप में हुई। हालाँकि, फ़ज़ी पैच एप्लिकेशन एक अपेक्षाकृत अविश्वसनीय तरीका है, कभी-कभी ऐसे पैच को गलत तरीके से लागू किया जाता है जिनका संदर्भ बहुत कम होता है (विशेष रूप से वे जो एक नई फ़ाइल बनाते हैं), कभी-कभी दोनों डेरिवेटिव द्वारा किए गए विलोपन को लागू करने से इनकार कर देते हैं।

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

पैच कम्यूटेशन के लिए आवश्यक है कि व्युत्पन्न फ़ाइलों में किए गए सटीक परिवर्तन संग्रहीत हों या उनका पुनर्निर्माण किया जा सके। इन सटीक परिवर्तनों से यह गणना करना संभव है कि उनमें से एक को दूसरे पर पुनः आधारित करने के लिए कैसे बदला जाना चाहिए। उदाहरण के लिए, यदि पैच A फ़ाइल F की पंक्ति 7 के बाद पंक्ति एफ, क्योंकि ए में जोड़ी गई लाइन लाइन नंबरों को एक से ऑफसेट कर देती है।

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

यूनिक्स कार्यक्रम  पैचुटिल्स पैकेज से diff -u द्वारा उत्पादित पारंपरिक पैच (कंप्यूटिंग) के लिए पैच कम्यूटेशन लागू होता है।

बुनाई मर्ज
वीव मर्ज एक एल्गोरिदम है जो दो फ़ाइलों के लिए एक सामान्य पूर्वज का उपयोग नहीं करता है। इसके बजाय, यह ट्रैक करता है कि फ़ाइलों के व्युत्पन्न संस्करणों में एकल पंक्तियाँ कैसे जोड़ी और हटाई जाती हैं, और इस जानकारी पर मर्ज की गई फ़ाइल तैयार करता है।

व्युत्पन्न फ़ाइलों में प्रत्येक पंक्ति के लिए, वेव मर्ज निम्नलिखित जानकारी एकत्र करता है: कौन सी पंक्तियाँ इसके पहले होती हैं, कौन सी पंक्तियाँ इसका अनुसरण करती हैं, और क्या इसे किसी भी व्युत्पन्न के इतिहास के किसी चरण में हटा दिया गया था। यदि किसी भी व्युत्पन्न में किसी बिंदु पर लाइन हटा दी गई है, तो उसे मर्ज किए गए संस्करण में मौजूद नहीं होना चाहिए। अन्य पंक्तियों के लिए, उन्हें मर्ज किए गए संस्करण में मौजूद होना चाहिए।

पंक्तियों को एक क्रम में क्रमबद्ध किया जाता है, जहां प्रत्येक पंक्ति उन सभी पंक्तियों के बाद होती है जो इतिहास में किसी बिंदु पर उसके पहले आई थीं, और उन सभी पंक्तियों के पहले होती हैं जो इतिहास में किसी बिंदु पर उसके बाद आई थीं। यदि ये बाधाएँ सभी पंक्तियों के लिए कुल क्रम नहीं देती हैं, तो जिन पंक्तियों में एक-दूसरे के संबंध में कोई क्रम नहीं है, वे ऐसे जोड़ हैं जो संघर्ष करते हैं।

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

यह भी देखें

 * फ़ाइल तुलना टूल की तुलना
 * अंतर
 * शाखाकरण (संशोधन नियंत्रण)