कैसे और / या क्यों एसवीएन की तुलना में गिट में विलय बेहतर है?


400

मैंने कुछ स्थानों पर सुना है कि मुख्य कारणों में से एक है कि क्यों वितरित संस्करण नियंत्रण प्रणाली चमकती है, एसवीएन जैसे पारंपरिक उपकरणों की तुलना में बेहतर विलय है। क्या यह वास्तव में अंतर्निहित अंतर के कारण है कि कैसे दो सिस्टम काम करते हैं, या विशिष्ट DVCS कार्यान्वयन जैसे कि Git / Mercurial में SVN से अधिक चतुर विलय एल्गोरिदम हैं?


मुझे अभी भी यहाँ महान उत्तर पढ़ने से पूर्ण उत्तर नहीं मिला। प्रत्यावर्तित - stackoverflow.com/questions/6172037/…
ripper234


यह आपके मॉडल पर निर्भर करता है। सरल मामलों में, svn अक्सर बेहतर होता है क्योंकि यह गलती से 2-वे मर्ज को कॉल नहीं करता है 3-वे मर्ज जैसे git कर सकता है यदि आप किसी एकल विकास शाखा पर पुश / मर्ज / पुल / पुश करते हैं। देखें: svnvsgit.com
एरिक

जवाबों:


556

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

तो क्यों तोड़फोड़ मलबे चूसना था ?

इस उदाहरण को रखें:

      1   2   4     6     8
trunk o-->o-->o---->o---->o
       \
        \   3     5     7
b1       +->o---->o---->o

जब हम b1 के बदलाव को ट्रंक में मर्ज करना चाहते हैं, तो हम निम्नलिखित कमांड जारी करेंगे, जबकि ट्रंक की जाँच करने वाले फ़ोल्डर पर खड़े हैं:

svn merge -r 2:7 {link to branch b1}

… जो b1आपके स्थानीय कार्यशील निर्देशिका से परिवर्तनों को मर्ज करने का प्रयास करेगा । और फिर आप किसी भी संघर्ष को हल करने और परिणाम का परीक्षण करने के बाद परिवर्तन करते हैं। जब आप संशोधन करते हैं तो वृक्ष इस तरह दिखेगा:

      1   2   4     6     8   9
trunk o-->o-->o---->o---->o-->o      "the merge commit is at r9"
       \
        \   3     5     7
b1       +->o---->o---->o

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

           12        14
trunk  …-->o-------->o
                                     "Okay, so when did we merge last time?"
              13        15
b1     …----->o-------->o

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

इस तोड़फोड़ को कम करने के लिए अब शाखा और विलय के लिए मेटा डेटा संग्रहीत करता है। यह सभी समस्याओं को हल करेगा?

और ओह, वैसे, तोड़फोड़ अभी भी बेकार है ...

एक केंद्रीकृत प्रणाली पर, तोड़फोड़ की तरह, आभासी निर्देशिका चूसना। क्यों? क्योंकि हर कोई उन्हें देखने के लिए उपयोग किया है ... यहां तक ​​कि कचरा प्रयोगात्मक हैं। अगर आप प्रयोग करना चाहते हैं तो ब्रांचिंग अच्छा है लेकिन आप हर किसी को और उनके चाची प्रयोग को नहीं देखना चाहते हैं । यह गंभीर संज्ञानात्मक शोर है। आप जितनी अधिक शाखाएँ जोड़ेंगे, आपको उतना अधिक बकवास देखने को मिलेगा।

जितनी अधिक सार्वजनिक शाखाएं होंगी, सभी विभिन्न शाखाओं का ध्यान रखना उतना ही कठिन होगा। तो सवाल आपके पास होगा कि क्या शाखा अभी भी विकास में है या यदि यह वास्तव में मर चुका है जो किसी भी केंद्रीकृत संस्करण नियंत्रण प्रणाली में बताना मुश्किल है।

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

तो DVCS, जैसे Git, Mercurial और Bazaar, ब्रांचिंग और मर्जिंग में सबवर्सन से बेहतर क्यों हैं?

एक बहुत ही सरल कारण है: ब्रांचिंग एक प्रथम श्रेणी की अवधारणा है । हैं कोई वर्चुअल निर्देशिका डिजाइन और शाखाओं द्वारा DVCS में कठोर वस्तुओं जो यह बस खजाने के तुल्यकालन (यानी के साथ काम करने के लिए इस तरह के होने की जरूरत है कर रहे हैं धक्का और पुल )।

जब आप DVCS के साथ काम करते हैं तो पहली चीज रिपॉजिटरी (git's clone, hg's cloneऔर bzr's branch) को क्लोन करना है । संस्करण नियंत्रण में एक शाखा बनाने के रूप में क्लोनिंग वैचारिक रूप से एक ही बात है। कुछ लोग इसे फोर्किंग या ब्रांचिंग कहते हैं (हालांकि बाद का उपयोग अक्सर सह-स्थित शाखाओं को संदर्भित करने के लिए भी किया जाता है), लेकिन यह केवल एक ही बात है। प्रत्येक उपयोगकर्ता अपना स्वयं का भंडार चलाता है जिसका अर्थ है कि आपके पास प्रति उपयोगकर्ता शाखा चल रही है।

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

विलय का एक बहुत ही सरल उदाहरण यह होगा; कहा जाता है originऔर एक उपयोगकर्ता, ऐलिस, एक केंद्रीय रिपॉजिटरी की कल्पना करें, रिपॉजिटरी को उसकी मशीन पर क्लोन कर रहा है।

         a…   b…   c…
origin   o<---o<---o
                   ^master
         |
         | clone
         v

         a…   b…   c…
alice    o<---o<---o
                   ^master
                   ^origin/master

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

इसके बाद ऐलिस अपने रेपो पर काम करती है, अपने ही भंडार में काम करती है और अपने बदलावों को आगे बढ़ाने का फैसला करती है:

         a…   b…   c…
origin   o<---o<---o
                   ^ master

              "what'll happen after a push?"


         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                   ^origin/master

समाधान बल्कि सरल है, केवल एक चीज जो originरिपॉजिटरी को करने की ज़रूरत है, वह है सभी नए संशोधनों को लेने और इसे नए संशोधन में शाखा में स्थानांतरित करने के लिए (जिसे गिट "फास्ट-फॉरवर्ड" कहते हैं):

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                             ^origin/master

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

तो कैसे आप के बारे में मुझे एक उदाहरण दिखाते हैं जिसमें एक वास्तविक मर्ज है?

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

         a…   b…   c…   f…
bob      o<---o<---o<---o
                        ^ master
                   ^ origin/master

                   "can Bob push his changes?" 

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

अब बॉब originरिपॉजिटरी में सीधे अपने बदलावों को आगे नहीं बढ़ा सकता । अगर सिस्टम यह जाँचता है कि बॉब के संशोधन सीधे तौर पर उतरते हैं origin, जो इस मामले में नहीं आता है, तो यह पता लगाता है । पुश करने के किसी भी प्रयास के परिणामस्वरूप सिस्टम में कुछ उकसाया जाएगा " उह ... मुझे डर है कि आप उसे बॉब नहीं कर सकते ।"

(Git के साथ तो बॉब पुल में करने के लिए और फिर परिवर्तन मर्ज है pull, या एचजी के pullऔर merge, या BzR के merge)। यह दो-चरणीय प्रक्रिया है। पहले बॉब को नए संशोधन लाने होंगे, जो उनकी नकल करेंगे क्योंकि वे originभंडार से हैं। अब हम यह देख सकते हैं कि ग्राफ में परिवर्तन होता है:

                        v master
         a…   b…   c…   f…
bob      o<---o<---o<---o
                   ^
                   |    d…   e…
                   +----o<---o
                             ^ origin/master

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

पुल प्रक्रिया का दूसरा चरण डायवर्जिंग युक्तियों को मर्ज करना और परिणाम के लिए प्रतिबद्ध करना है:

                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+
                             ^ origin/master

उम्मीद है कि मर्ज संघर्ष में नहीं चलेगा (यदि आप उन्हें अनुमान लगाते हैं कि आप दो चरणों को मैन्युअल रूप से fetchऔर साथ में कर सकते हैं merge)। बाद में जो करने की आवश्यकता है, उन परिवर्तनों को फिर से originआगे बढ़ाने के लिए है , जिसके परिणामस्वरूप विलय के बाद तेजी से आगे विलय होगा, originभंडार में नवीनतम का प्रत्यक्ष वंशज है:

                                 v origin/master
                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

                                 v master
         a…   b…   c…   f…       1…
origin   o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

गिट और एचजी में विलय करने का एक और विकल्प है, जिसे रिबेस कहा जाता है , जो बॉब के परिवर्तनों को नवीनतम परिवर्तनों के बाद स्थानांतरित करेगा। चूँकि मैं इस उत्तर को किसी और क्रिया के लिए नहीं चाहता हूँ इसलिए मैं आपको इसके बारे में git , मर्क्यूरियल या बाज़ार डॉक्स पढ़ने दूंगा ।

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

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

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


6
मैं आपकी शाखाओं == शोर तर्क से सहमत नहीं हूँ। बहुत सी शाखाएँ लोगों को भ्रमित नहीं करती हैं क्योंकि मुख्य देव को लोगों को बताना चाहिए कि कौन सी शाखा का उपयोग बड़ी सुविधाओं के लिए किया जाए ... इसलिए दो देवों को शाखा X पर "उड़ते हुए डायनासोर" को जोड़ने के लिए काम करना पड़ सकता है, 3 आपको Y को फेंकने के लिए Y पर काम कर सकते हैं। लोगों पर कार "
श्री बॉय

16
जॉन: हां, छोटी संख्या में शाखाओं के लिए थोड़ा शोर है और प्रबंधनीय है। लेकिन जब आप 50+ शाखाओं और टैगों को तोड़फोड़ या स्पष्ट मामले में देख चुके हों, तो उनमें से अधिकांश आप बता नहीं सकते कि वे सक्रिय हैं या नहीं। साधनों से अलग होने की समस्या; क्यों अपने भंडार में चारों ओर कूड़े है? कम से कम p4 में (चूंकि एक उपयोगकर्ता का "कार्यक्षेत्र" अनिवार्य रूप से एक प्रति-उपयोगकर्ता शाखा है), git या hg आपको हर उस बदलाव के बारे में जानने की अनुमति देता है जो आप तब तक करते हैं जब तक आप उन्हें ऊपर की ओर धकेल नहीं देते, जो एक सुरक्षित है- जब परिवर्तन दूसरों के लिए प्रासंगिक हों, तब पहरा दें।
स्पोइक

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

11
Svn में निष्क्रिय शाखाओं को मारना आसान है, आप उन्हें हटा दें। तथ्य यह है कि लोग अप्रयुक्त शाखाओं को नहीं हटाते हैं इसलिए अव्यवस्था बनाना केवल हाउसकीपिंग की बात है। आप बस Git में बहुत सारी अस्थाई शाखाओं के साथ आसानी से हवा निकाल सकते हैं। मेरे कार्यस्थल में हम मानक लोगों के अलावा एक "अस्थायी-शाखाएँ" शीर्ष-स्तरीय निर्देशिका का उपयोग करते हैं - व्यक्तिगत शाखाएँ और प्रायोगिक शाखाएँ शाखा निर्देशिका को अव्यवस्थित करने की बजाय वहाँ जाती हैं जहाँ "आधिकारिक" कोड की लाइनें रखी जाती हैं (हम नहीं करते हैं) सुविधा शाखाओं का उपयोग करें)।
केन लियू

10
क्या इसका मतलब यह है कि, v1.5 तोड़फोड़ से कम से कम मर्ज के साथ-साथ गिट सकते हैं?
सैम

29

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

Git डिफ़ॉल्ट रूप से 3-तरफा मर्ज एल्गोरिथ्म का उपयोग करता है, जिसमें एक सामान्य पूर्वज को मर्ज करने के लिए शामिल करना और मर्ज के दोनों तरफ मौजूद ज्ञान का उपयोग करना शामिल है। इससे गिट संघर्षों से बचने में अधिक बुद्धिमान होने की अनुमति देता है।

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


4
क्या आपके पास एक उदाहरण है कि svn में मर्ज संघर्ष है लेकिन git नहीं है?
Gqqnbig

17

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

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

दूसरी ओर, गिट नाम बदलने पर भी नज़र नहीं रखता है, लेकिन इस तथ्य (विलय के समय) के बाद उनका पता लगाता है, और बहुत जादुई तरीके से करता है।

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

लेकिन इस सब के बाद (जो IMHO वे क्या कर रहे हैं, यह समझने की कमी दिखाते हैं), मैं (ठीक हूं, मैं) किसी भी nontrivial शाखाओं में बंटने वाले परिदृश्य में SVN का उपयोग करने के लिए बहुत सावधानी बरतता हूं, और आदर्श रूप से यह देखने की कोशिश करेगा कि Git क्या सोचता है मर्ज परिणाम।

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

संक्षेप में: Git SVN की तुलना में संशोधनों को संग्रहीत करने के लिए बहुत सरल डेटा मॉडल का उपयोग करता है, और इस प्रकार यह प्रतिनिधित्व => व्यावहारिक रूप से बेहतर विलय के साथ सामना करने की कोशिश करने के बजाय वास्तविक मर्ज एल्गोरिदम में बहुत अधिक ऊर्जा डाल सकता है।


11

एक बात जिसका अन्य उत्तरों में उल्लेख नहीं किया गया है, और वह वास्तव में डीवीसीएस का एक बड़ा लाभ है, यह है कि आप अपने परिवर्तनों को आगे बढ़ाने से पहले स्थानीय स्तर पर प्रतिबद्ध कर सकते हैं। एसवीएन में, जब मैंने कुछ बदलाव किया, जिसमें मैं जांच करना चाहता था, और किसी ने पहले ही इस बीच एक ही शाखा पर एक प्रतिबद्ध किया था, इसका मतलब यह था कि मुझे svn updateइससे पहले कि मैं प्रतिबद्ध कर सकता था। इसका अर्थ है कि मेरे परिवर्तन, और दूसरे व्यक्ति के परिवर्तन अब एक साथ मिल गए हैं, और मर्ज को समाप्त करने का कोई तरीका नहीं है (जैसे git resetयाhg update -C ), क्योंकि वापस जाने के लिए कोई प्रतिबद्ध नहीं है। यदि मर्ज गैर-तुच्छ है, तो इसका मतलब है कि मर्ज परिणाम को साफ करने से पहले आप अपनी सुविधा पर काम करना जारी नहीं रख सकते।

लेकिन फिर, शायद यह केवल उन लोगों के लिए एक फायदा है जो अलग-अलग शाखाओं का उपयोग करने के लिए बहुत विनम्र हैं (यदि मुझे सही याद है, तो हमारे पास केवल एक शाखा थी जिसका उपयोग कंपनी में विकास के लिए किया गया था जहां मैंने एसवीएन का उपयोग किया था)।


10

संपादित करें: यह मुख्य रूप से प्रश्न के इस हिस्से को संबोधित कर रहा है :
क्या यह वास्तव में अंतर्निहित अंतर के कारण है कि दो सिस्टम कैसे काम करते हैं, या विशिष्ट DVCS कार्यान्वयन जैसे कि Git / Mercurial में SVN की तुलना में चतुर विलय एल्गोरिदम हैं?
टीएल; डीआर - उन विशिष्ट उपकरणों में बेहतर एल्गोरिदम हैं। वितरित होने से कुछ वर्कफ़्लो लाभ होते हैं, लेकिन विलय के लाभों के लिए रूढ़िवादी है।
END EDIT

मैंने स्वीकृत उत्तर पढ़ा। यह सिर्फ सादा गलत है।

एसवीएन विलय एक दर्द हो सकता है, और यह बोझिल भी हो सकता है। लेकिन, इसे अनदेखा करें कि यह वास्तव में एक मिनट के लिए कैसे काम करता है। ऐसी कोई जानकारी नहीं है कि Git रखता है या प्राप्त कर सकता है कि SVN भी नहीं रखता है या प्राप्त नहीं कर सकता है। इससे भी महत्वपूर्ण बात, कोई कारण नहीं है कि संस्करण नियंत्रण प्रणाली की अलग (कभी-कभी आंशिक) प्रतियों को रखने से आपको अधिक वास्तविक जानकारी मिलेगी। दो संरचनाएं पूरी तरह से बराबर हैं।

मान लें कि आप "कुछ चतुर बात" करना चाहते हैं "Git" बेहतर है "। और आप बात कर रहे हैं SVN में जाँच की।

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

दिन के अंत में, कोई भी संस्करण नियंत्रण प्रणाली मुझे जाने देगी

1. Generate a set of objects at a given branch/revision.
2. Provide the difference between a parent child branch/revisions.

इसके अतिरिक्त, विलय के लिए यह जानना भी उपयोगी (या महत्वपूर्ण) है

3. The set of changes have been merged into a given branch/revision.

Mercurial , Git और Subversion (अब मूल रूप से, पहले svnmerge.py का उपयोग करके) सभी तीनों जानकारी प्रदान कर सकते हैं। डीवीसी के साथ मौलिक रूप से कुछ बेहतर प्रदर्शन करने के लिए, कृपया कुछ चौथे जानकारी को इंगित करें जो एसवीएन / केंद्रीकृत वीसी में उपलब्ध नहीं है।

यह कहना है कि वे बेहतर उपकरण नहीं हैं!


1
हाँ, मैंने विवरण में प्रश्न का उत्तर दिया है, शीर्षक नहीं। svn और git की समान जानकारी तक पहुँच होती है (वास्तव में आमतौर पर svn में अधिक होती है), इसलिए svn जो कुछ भी करता है वह कर सकता है। लेकिन, उन्होंने अलग-अलग डिज़ाइन निर्णय लिए, और इसलिए यह वास्तव में नहीं है। DVC / केंद्रीकृत पर प्रमाण यह है कि आप एक केंद्रीकृत कुलपति के रूप में git चला सकते हैं (शायद थोड़े नियमों के साथ) और आप वितरित svn (लेकिन यह पूरी तरह से बेकार है) चला सकते हैं। हालाँकि, यह सभी लोगों के लिए बहुत अधिक अकादमिक है - git और hg ब्रांचिंग और मर्ज़ को svn से बेहतर बनाते हैं। टूल का चयन करते समय वास्तव में यही मायने रखता है :-)।
पीटर

5
संस्करण 1.5 तक तोड़फोड़ ने सभी आवश्यक जानकारी संग्रहीत नहीं की। 1.5 एसवीएन के साथ संग्रहीत जानकारी संग्रहीत थी अलग है: गिट एक मर्ज कमिट के सभी माता-पिता को संग्रहीत करते हैं, जबकि तोड़फोड़ संग्रहीत करता है कि क्या संशोधन पहले से ही शाखा में विलय कर दिए गए थे।
जकूब नारबस्की

4
एक उपकरण जो एक svn भंडार पर फिर से लागू करना मुश्किल है git merge-base। गिट के साथ, आप कह सकते हैं "शाखाएं और संशोधन x पर बी विभाजन"। लेकिन svn स्टोर्स "फ़ाइलों को फू से बार में कॉपी किया गया था", इसलिए आपको वर्कआउट करने के लिए उन आंकड़ों का उपयोग करने की आवश्यकता है जो बार के लिए कॉपी एक प्रोजेक्ट के भीतर फ़ाइलों की प्रतिलिपि बनाने के बजाय एक नई शाखा बना रहे थे। चाल यह है कि svn में एक संशोधन संशोधन संख्या और आधार पथ द्वारा परिभाषित किया गया है । भले ही ज्यादातर समय "ट्रंक" मान लेना संभव हो, यह वास्तव में शाखाएं होने पर काटता है।
डगलस

2
पुन: "कोई जानकारी नहीं है कि git रखता है या प्राप्त कर सकता है कि svn भी नहीं रखता है या प्राप्त नहीं कर सकता है।" - मैंने पाया कि एसवीएन को याद नहीं था कि चीजें कब मिलाई गई थीं। यदि आप ट्रंक से काम को अपनी शाखा में खींचना पसंद करते हैं और आगे और पीछे जाते हैं तो विलय कठिन हो सकता है। Git में इसके रिविजन ग्राफ में प्रत्येक नोड जानता है कि यह कहां से आया है। इसमें दो माता-पिता और कुछ स्थानीय परिवर्तन होते हैं। मुझे विश्वास है कि एसवीएन से अधिक विलय करने में सक्षम होना चाहिए। यदि आप एसवीएन में विलय करते हैं और शाखा को हटाते हैं तो शाखा इतिहास खो जाता है। यदि आप GIT में विलीन हो जाते हैं और उस शाखा को हटा देते हैं जिसका ग्राफ बना रहता है, और इसके साथ "दोष" प्लगइन होता है।
रिचर्ड कोरफील्ड

1
क्या यह मामला नहीं है कि स्थानीय रूप से git और mercurial के पास सभी आवश्यक जानकारी है, हालांकि, svn को जानकारी प्राप्त करने के लिए स्थानीय और केंद्रीय दोनों डेटा को देखने की आवश्यकता है?
वारेन ड्यू

8

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

मैं अभी भी एसवीएन का भारी उपयोग करता हूं, लेकिन मैंने जितने बार Git का उपयोग किया है उससे बहुत खुश हूं।

यदि आपके पास समय हो तो एक अच्छा पाठ: मैंने Git को क्यों चुना


यही मैंने भी पढ़ा, और यही मैं गिन रहा था, लेकिन यह व्यवहार में नहीं है।
रॉल्फ

Git फ़ाइलों की सामग्री को ट्रैक करता है, यह केवल सामग्री को परिवर्तनों के रूप में दिखाता है
फेरीबग

6

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

वितरित संस्करण नियंत्रण के साथ, वितरित भाग वास्तव में सबसे दिलचस्प हिस्सा नहीं है। दिलचस्प बात यह है कि ये सिस्टम परिवर्तनों के संदर्भ में सोचते हैं, न कि संस्करणों के संदर्भ में।

लेख यहाँ पढ़ें ।


5
उन लेखों में से एक था जो मैं यहाँ पोस्ट करने से पहले सोच रहा था। लेकिन "परिवर्तनों के संदर्भ में सोचता है" एक बहुत ही अस्पष्ट विपणन-ध्वनि शब्द है (याद रखें कि जोएल की कंपनी अब डीवीसीएस बेचती है)
मिस्टर बॉय

2
मैंने सोचा था कि यह अस्पष्ट था ... मैंने हमेशा सोचा था कि संस्करण (या संशोधन) के बजाय बदलाव एक अभिन्न अंग थे, जो मुझे आश्चर्यचकित करते हैं कि कुछ प्रोग्रामर परिवर्तनों के संदर्भ में नहीं सोचते हैं।
Spoike

एक ऐसी प्रणाली के लिए जो वास्तव में "परिवर्तनों के संदर्भ में सोचती है", डारक्स की जाँच करें
मैक्स

@ मोम: यकीन है, लेकिन जब धक्का को धक्का लगता है, तो गिट बचाता है जहां डार्क्स मूल रूप से तोड़फोड़ के रूप में दर्दनाक है, जब यह वास्तव में विलय की बात आती है।
ट्रिपल डे

Git के तीन नुकसान यह है कि यह डॉक्युमेंट्स मैनेजमेंट की तरह बायनेरिज़ के लिए बहुत अच्छा नहीं है, जहाँ यह बहुत संभावना नहीं है कि लोग ब्रांच और मर्ज करना चाहेंगे) यह मानता है कि आप हर किसी को क्लोन करना चाहते हैं c) यह क्लोन में भी सब कुछ के इतिहास को स्टोर करता है। अक्सर बदलते बायनेरिज़ के कारण क्लोन ब्लोट होता है। मुझे लगता है कि उन उपयोग के मामलों के लिए एक केंद्रीकृत वीसीएस कहीं बेहतर है। विशेष रूप से मर्जिंग और ब्रांचिंग के लिए नियमित विकास के लिए Git कहीं बेहतर है।
ताला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.