दिलचस्प पोस्ट
जब id में कोई डॉट शामिल होता है तो jquery के साथ आईडी द्वारा html नोड्स को कैसे चुनना है? एंड्रॉइड स्टूडियो में डेटाबेस फ़ाइल की सामग्री देखें जावा का बूलियन आदिम आकार क्यों परिभाषित नहीं है? क्या किसी को आंतरिक कार्यान्वयन, या केवल सार्वजनिक व्यवहार का परीक्षण करना चाहिए? Google की होस्ट किए गए jQuery का उपयोग करने का सबसे अच्छा तरीका है, लेकिन Google पर मेरी होस्टेड लाइब्रेरी पर वापस आना विफल रहता है अजगर में दिए गए स्ट्रिंग के सभी संभावित क्रमांतरों को ढूँढना मैं सी # में विधि कॉल कैसे रोकूं? अमान्य (खराब / अच्छी तरह से नहीं बनाई गई) XML को कैसे पार्स करना है? बिल्ड लक्ष्य के बाहर जीसीसी डीबग प्रतीक कैसे उत्पन्न करें? एंड्रॉइड स्टूडियो धीमा है (गति कैसे करें)? एचटीटीपी एचटीटीपी के लिए एचटीएसीएक्स का इस्तेमाल कर रहा है नि: शुल्क कैसे मुक्त है पता है कि कैसे? Sed में कमांड में चर का उपयोग कैसे करें? एसक्यूएल विभाजन मूल्यों को कई पंक्तियों में पायथन सूची घटाव ऑपरेशन

जब आप git विलय के बजाय git रिज का उपयोग करते हैं?

git rebase बनाम git merge का उपयोग कब करने की सिफारिश की गई है?

क्या मुझे अभी भी एक सफल रिबेस के बाद विलय करने की आवश्यकता है?

वेब के समाधान से एकत्रित समाधान "जब आप git विलय के बजाय git रिज का उपयोग करते हैं?"

लघु संस्करण

  • मर्ज एक शाखा में सभी परिवर्तन लेता है और एक प्रतिबद्ध में एक और शाखा में उन्हें विलीन करता है।
  • रिबेस का कहना है कि मैं उस बिंदु चाहता हूं जिस पर मैं एक नए शुरुआती बिंदु पर जाना चाहता हूं

तो आप किसी एक का उपयोग कब करते हैं?

मर्ज

  • मान लें कि आपने एक सुविधा विकसित करने के उद्देश्य से एक शाखा बनाई है। जब आप उन परिवर्तनों को मास्टर करने के लिए वापस लेना चाहते हैं, तो आप शायद मर्ज करना चाहते हैं (आप सभी अंतरिम प्रतिबद्धता बनाए रखने की परवाह नहीं करते हैं)

rebase

  • एक दूसरा परिदृश्य होगा यदि आप कुछ विकास करना शुरू कर देंगे और फिर एक और डेवलपर ने असंबंधित परिवर्तन किए। आप संभवत: रेपो से वर्तमान संस्करण से अपने परिवर्तनों को आधार बनाने के लिए खींचें और फिर रिबेस करना चाहते हैं।

अपने स्वयं के जवाब के लिए TSamper द्वारा वर्णित पूरक,

  • मर्ज होने से पहले एक रिसाव अक्सर एक अच्छा विचार है, क्योंकि यह विचार है कि आप अपनी शाखा में एकीकृत करते हैं Y और शाखा B का काम जिस पर आप विलय करेंगे।
    लेकिन फिर से, विलय करने से पहले, आप अपनी शाखा में किसी भी विवाद को हल करते हैं (यानी: "रिबेस", जैसा कि "शाखा में बीते समय से शुरू होने वाले मेरे शाखा में मेरे काम को दोहराएं)
    यदि सही ढंग से किया जाता है, तो बाद में आपकी शाखा से शाखा B मर्ज हो सकते हैं तेज़ फॉरवर्ड हो सकते हैं।

  • एक मर्ज प्रभाव सीधे गंतव्य शाखा B , जिसका अर्थ है कि मर्ज बेहतर हो तुच्छ हो, अन्यथा शाखा B एक स्थिर स्थिति में वापस लाने के लिए लंबा हो सकता है (आप सभी संघर्षों को हल करने के लिए समय)


एक रिसाव के बाद विलय का मुद्दा?

मैं बताता हूं कि मामले में, मैं अपनी शाखा पर B को रिज़्यूब करता हूं, बस अपने काम को B से एक और हाल के बिंदु से फिर से चलाने का मौका मिला, लेकिन मेरी शाखा में रहने के दौरान
इस मामले में, B पर मेरे "रीप्लेड" कार्य को लाने के लिए अभी भी एक मर्ज की आवश्यकता है

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

डिफ़ॉल्ट रूप से एक गिट का पेड़ जब हमने मर्ज नहीं किया है और रिबैस नहीं किया है

rebase1

हम रिबैसिंग द्वारा प्राप्त करते हैं:

rebase3

यह दूसरा परिदृश्य है: मैं मास्टर में नए फीचर को वापस कैसे प्राप्त करूं?

मेरा मुद्दा, पहली रिबेस परिदृश्य का वर्णन करके, हर किसी को याद दिलाना है कि एक रीबेस को भी प्रारंभिक कदम के रूप में इस्तेमाल किया जा सकता है ("मास्टर में नई फीचर वापस प्राप्त हो रहा है")
आप नए-सुविधा वाले शाखा में पहले "मास्टर" में लाने के लिए रीबेस का उपयोग कर सकते हैं: रीबैस HEAD master से नए फीचर को फिर से चलाया जाएगा, लेकिन फिर भी नई फीचर शाखा में, प्रभावी ढंग से एक पुराने मास्टर कमेट HEAD-master करने के लिए
इससे आप अपनी शाखा में किसी भी टकराव को हल करने की अनुमति दे सकते हैं (जिसका अर्थ है, अलगाव में, जबकि मास्टर को समानांतर में विकसित करने की इजाजत दे रहा है, यदि आपका विरोध समाधान चरण बहुत लंबा लेता है)।
तब आप मास्टर पर स्विच कर सकते हैं और new-feature (या new-feature को master पर मर्ज कर सकते हैं यदि आप अपनी new-feature शाखा में किए गए कमेट्स को संरक्षित करना चाहते हैं) को मर्ज कर सकते हैं।

इसलिए:

  • "रिज़र्व बनाम मर्ज" को काम पर आयात करने के दो तरीके के रूप में देखा जा सकता है, कहते हैं, master
  • लेकिन अलगाव में विवाद को सुलझाने के लिए पहले "विलय फिर से विलय" एक वैध वर्कफ़्लो हो सकता है, फिर अपने कार्य को वापस लाएं।

यह आसान है, रीबेस के साथ आप अपने काम के लिए नए आधार के रूप में दूसरी शाखा का इस्तेमाल करने के लिए कहते हैं।

यदि आपके पास ब्रांच master उदाहरण के लिए है और आप एक नई सुविधा को लागू करने के लिए एक शाखा बनाते हैं, तो कहते हैं कि आप इसे cool-feature कहते हैं, निश्चित रूप से मास्टर शाखा आपके नए फीचर के लिए आधार है।

अब एक निश्चित बिंदु पर आप master शाखा में लागू की गई नई सुविधा जोड़ना चाहते हैं आप बस master स्विच कर सकते हैं और cool-feature शाखा को मर्ज कर cool-feature :

 $git checkout master $git merge cool-feature 

लेकिन इस तरह से एक नया डमी कमिट जोड़ा गया है, यदि आप स्पेगेटी-इतिहास से बचना चाहते हैं तो आप रिबेस कर सकते हैं:

 $git checkout cool-feature $git rebase master 

और फिर इसे master में मर्ज करें:

 $git checkout master $git merge cool-feature 

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

यहां बहुत सारे उत्तर दिए गए हैं कि मर्जिंग आपके सभी कमानों को एक में बदल देता है, और इसलिए अपने कमानों को संरक्षित करने के लिए रीबेस का उपयोग करने का सुझाव देता है यह गलत है और एक बुरा विचार यदि आपने पहले से ही अपना कमान धक्का दिया है

मर्ज करें आपके कमानों को मिटा नहीं सकते विलय इतिहास को बरकरार रखता है! (बस gitk को देखो) Rebase इतिहास को फिर से लिखता है, जो एक खराब चीज है जो आपने इसे धक्का दे दिया है।

मर्ज का उपयोग करें – जब भी आप पहले से ही पुश कर चुके हों

यहां लीनस (गिट के लेखक) इस पर लेते हैं । यह एक बहुत अच्छा पठन है या आप नीचे एक ही विचार के अपने स्वयं के संस्करण को पढ़ सकते हैं

मास्टर पर एक शाखा रिबसिंग:

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

इसके विपरीत, विषय शाखा को मास्टर में मर्ज करना:

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

टी एल; डॉ

यदि आपके कोई संदेह है, मर्ज का उपयोग करें

संक्षिप्त जवाब

रीबेस और मर्ज के बीच केवल अंतर हैं:

  • इतिहास के परिणामस्वरूप वृक्ष ढांचे (आम तौर पर एक प्रतिबद्ध आलेख को देखते हुए केवल ध्यान देने योग्य) अलग है (एक शाखाएं होंगी, अन्य नहीं)।
  • मर्ज आम तौर पर एक अतिरिक्त प्रतिबद्धता (उदाहरण के पेड़ में नोड) बना देगा।
  • मर्ज और रीबेस अलग-अलग संघर्षों को संभाल लेंगे रिबैस एक ऐसे समय में प्रतिबद्धता पेश करेगा, जहां विलय उन सभी को एक साथ पेश करेगा।

तो संक्षेप में उत्तर के लिए रीसाइज चुनना या उस पर आधारित विलय करना है, जिसे आप अपना इतिहास देखना चाहते हैं

लंबा जवाब

कुछ कारक हैं जिन पर आपको कौन से ऑपरेशन का उपयोग करना है, यह चुनने पर विचार करना चाहिए।

क्या आपकी शाखा आपकी टीम के बाहर अन्य डेवलपर्स के साथ साझा की जा रही शाखा है (जैसे ओपन सोर्स, पब्लिक)?

यदि हां, तो रिसाव न करें। रिबेस ने शाखा को नष्ट कर दिया और उन डेवलपरों को तोड़ दिया / असंगत भंडार होगा जब तक कि वे git pull --rebase उपयोग न git pull --rebase । यह अन्य डेवलपर्स को जल्दी से परेशान करने का एक अच्छा तरीका है

आपकी विकास टीम कितनी कुशल है?

रिबेस एक विनाशकारी ऑपरेशन है। इसका अर्थ है, अगर आप इसे सही तरीके से लागू नहीं करते हैं, तो आप प्रतिबद्ध कार्य खो सकते हैं और / या अन्य डेवलपर के रिपॉजिटरी की स्थिरता को तोड़ सकते हैं।

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

क्या शाखा ही उपयोगी जानकारी का प्रतिनिधित्व करती है

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

मैंने उन टीमों पर भी काम किया है जो शाखा-प्रति-डेवलपर मॉडल का इस्तेमाल करते हैं (हम सब वहां गए हैं)। इस मामले में शाखा ही किसी भी अतिरिक्त जानकारी को व्यक्त नहीं करती है (कमेट पहले ही लेखक है) रीबिंग में कोई नुकसान नहीं होगा

क्या आप किसी भी कारण से मर्ज को वापस करना चाहते हैं?

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

क्या आप टीम पर काम करते हैं? यदि हां, तो क्या आप इस शाखा पर सभी या कुछ भी न कुछ लेने के लिए तैयार हैं?

रिबेश ऑपरेशंस को इसी git pull --rebase साथ git pull --rebase जरूरत है – रिबेस यदि आप अपने आप से काम कर रहे हैं तो आप याद कर सकते हैं कि आपको उचित समय पर उपयोग करना चाहिए। यदि आप किसी टीम में काम कर रहे हैं तो समन्वय करना बहुत कठिन होगा। यही कारण है कि अधिकांश रिबेस वर्कफ़्लोज़ सभी विलयों के git pull --rebase का उपयोग करने की सलाह देते हैं (और सभी git pull --rebase लिए git pull --rebase )।

आम मिथक

मर्ज करें इतिहास को नष्ट कर देता है (स्क्वैश कमेट्स)

मान लें कि आपके पास निम्न मर्ज हैं:

  B -- C / \ A--------D 

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

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

रीबेस सुरक्षित / सरल विलय के लिए अनुमति देता है

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

रीबेस कूलर / सेक्सियर / अधिक पेशेवर है

यदि आप "समय बचाने" के लिए rm -rf करना चाहते हैं, तो हो सकता है कि आप रिसाइज़ करें।

मेरे दो सेंट

मुझे हमेशा लगता है कि किसी दिन मैं एक ऐसी परिस्थिति में आऊंगा जहां जीआईटी रिसाव एक अद्भुत उपकरण है जो समस्या को हल करता है जितना मुझे लगता है कि मैं एक ऐसे परिदृश्य में आया हूँ जहां जीआईटी रेफेल एक अद्भुत उपकरण है जो मेरी समस्या का समाधान करता है। मैंने पांच साल से अधिक समय तक जीआईटी के साथ काम किया है ऐसा नहीं हुआ है।

गन्दा इतिहास मेरे लिए वास्तव में एक समस्या नहीं है। मैं कभी भी एक रोमांचक उपन्यास की तरह मेरे इतिहास को नहीं पढ़ा। अधिकांश समय मुझे एक इतिहास की आवश्यकता है, मैं जीआईटी दोष या जीआईटी का उपयोग किसी भी तरह से द्विगुणित करने के लिए कर रहा हूं। उस मामले में मर्ज कमेट करना मेरे लिए वास्तव में उपयोगी है क्योंकि अगर मर्ज ने इस मुद्दे को पेश किया है जो कि मेरे लिए सार्थक जानकारी है

अपडेट (4/2017)

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

मर्ज का मतलब: एक नया प्रतिबद्ध बनाएं जो मेरे परिवर्तन गंतव्य में विलीन हो जाता है।

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

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

उसने कहा, यदि आपने पहले से शाखा को ऊपर की तरफ काम कर दिया है, तो आपको रिबैस नहीं करना चाहिए बल्कि इसके बजाय मर्ज करना चाहिए। उन शाखाओं के लिए जो अपस्ट्रीम, रीबेस, टेस्ट और मर्ज नहीं किए गए हैं।

एक बार जब आप अपस्ट्रीम को आगे बढ़ाने से पहले अपनी शाखा से कमानों को छुटकारा पाने के लिए रिसाव करना चाहते हैं उदाहरण के लिए: कुछ डिबगिंग कोड शुरू करने वाले कमिट्स और अन्य उस कोड को साफ करते हुए आगे बढ़ता है। ऐसा करने का एकमात्र तरीका इंटरैक्टिव रीबेस प्रदर्शन कर रहा है: git rebase -i <branch/commit/tag>

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

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

UPDATE3: Does one still need to merge after a successful rebase? हाँ आप कीजिए। इसका कारण यह है कि रिसाव में अनिवार्य रूप से प्रतिबद्धों का "स्थानांतरण" शामिल है। जैसा कि मैंने ऊपर कहा है, ये कमिट्स की गणना की जाती है, लेकिन अगर आपके पास 14 शाखाएं शाखाएं हैं, तो मान लें कि आपके रिबेस में कुछ भी गलत नहीं हो जाता है, तो आप 14 कमेंट्स (आगे की बात) रिबेस किया जाता है एक रिबेस से पहले आपकी एक शाखा थी आपके पास उसी लंबाई की एक शाखा होगी जिसके बाद आपके परिवर्तनों को प्रकाशित करने से पहले आपको अभी भी विलय करना होगा दूसरे शब्दों में, जितनी बार आप चाहते हैं, उतनी बार रिबेस करें (फिर से, केवल तभी जब आपने अपने परिवर्तनों को अपस्ट्रीम धक्का नहीं दिया है)। विलय के बाद ही विलय करें।

मर्ज / रिबेस से पहले:

 A <- B <- C [master] ^ \ D <- E [branch] 

git merge master बाद:

 A <- B <- C ^ ^ \ \ D <- E <- F 

git rebase master बाद:

 A <- B <- C <- D' <- E' 

(ए, बी, सी, डी, ई और एफ कमिट हैं)

इस उदाहरण और जीआईटी के बारे में अधिक अच्छी तरह से सचित्र जानकारी यहां पायी जा सकती है: http://excess.org/article/2008/07/ogre-git-tutorial/

यह वाक्य यह हो जाता है:

सामान्य तौर पर दोनों दुनिया का सर्वोत्तम प्राप्त करने का तरीका है आपके द्वारा किए गए स्थानीय परिवर्तनों को रिज़र्व करना है, लेकिन आपने अपनी कहानी को साफ करने के लिए उनको आगे बढ़ाने से पहले ही साझा नहीं किया है, लेकिन कभी भी आपके द्वारा कहीं भी धकेल दिया कुछ भी रिसाव नहीं करें

स्रोत: http://www.git-scm.com/book/en/v2/Git-Branching-Rebasing#Rebase-vs.- मिर्ज

रिसाइज़िंग पृष्ठ पर वास्तव में अच्छी स्पष्टीकरण के रूप में प्रो गिट बुक

असल में एक मर्ज 2 कमिट ले जाएगा और उन्हें गठबंधन।

एक रिसाव सामान्य पूर्वज के पास 2 पर जाएंगे और एक-दूसरे के ऊपर होने वाले बदलावों को बढ़ेगा। यह एक 'क्लीनर' और अधिक रैखिक इतिहास के लिए बनाता है

लेकिन जब आप रिबैस करते हैं तो आप पिछले कमानों को छोड़ देते हैं और नए बनाते हैं। इसलिए आपको सार्वजनिक रूप से एक रेपो रिसाव नहीं करना चाहिए रेपो पर काम करने वाले अन्य लोग आपको नफरत करेंगे

इस कारण के लिए अकेले मैं लगभग अनन्य रूप से मर्ज करता हूं मेरी शाखाएं उस समय के 99% से ज्यादा भिन्न नहीं होती हैं, इसलिए यदि कोई संघर्ष होता है तो यह केवल एक या दो स्थानों में होता है।

यह जवाब व्यापक रूप से गिट फ्लो के आसपास केंद्रित है। तालिकाओं को अच्छे एएससीआईआई जेनरेटर और इस अद्भुत कमान के साथ इतिहास के पेड़ के साथ उत्पन्न किया गया है ( git lg रूप में उपनाम ):

 git log --graph --abbrev-commit --decorate --date=format:'%Y-%m-%d %H:%M:%S' --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%ad%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' 

टेबल्स इतिहास के पेड़ के साथ अधिक सुसंगत होने के लिए रिवर्स कालानुक्रमिक क्रम में हैं। git merge और git merge --no-ff बीच में अंतर भी देखें git merge --no-ff सबसे पहले (आप आमतौर पर git merge --no-ff का उपयोग करना चाहते हैं git merge --no-ff क्योंकि इससे आपका इतिहास वास्तविकता के करीब दिखता है):

git merge

आदेश:

 Time Branch "develop" Branch "features/foo" ------- ------------------------------ ------------------------------- 15:04 git merge features/foo 15:03 git commit -m "Third commit" 15:02 git commit -m "Second commit" 15:01 git checkout -b features/foo 15:00 git commit -m "First commit" 

परिणाम:

 * 142a74a - YYYY-MM-DD 15:03:00 (XX minutes ago) (HEAD -> develop, features/foo) | Third commit - Christophe * 00d848c - YYYY-MM-DD 15:02:00 (XX minutes ago) | Second commit - Christophe * 298e9c5 - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

git merge --no-ff

आदेश:

 Time Branch "develop" Branch "features/foo" ------- -------------------------------- ------------------------------- 15:04 git merge --no-ff features/foo 15:03 git commit -m "Third commit" 15:02 git commit -m "Second commit" 15:01 git checkout -b features/foo 15:00 git commit -m "First commit" 

परिणाम:

 * 1140d8c - YYYY-MM-DD 15:04:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/foo' - Christophe | * 69f4a7a - YYYY-MM-DD 15:03:00 (XX minutes ago) (features/foo) | | Third commit - Christophe | * 2973183 - YYYY-MM-DD 15:02:00 (XX minutes ago) |/ Second commit - Christophe * c173472 - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

git merge बनाम git rebase

पहला बिंदु: सुविधाओं को विकसित करने में हमेशा मर्ज करें, सुविधाओं से कभी भी विकसित न करें । यह रिबज़िंग के स्वर्ण नियम का एक परिणाम है:

git rebase का सुनहरा नियम सार्वजनिक शाखाओं पर इसका कभी इस्तेमाल नहीं करना है

दूसरे शब्दों में :

कभी भी आपके द्वारा कहीं भी धक्का नहीं लगाया जा सकता है

मैं व्यक्तिगत रूप से जोड़ूंगा: जब तक कि यह एक सुविधा शाखा नहीं है और आप और आपकी टीम परिणामों के बारे में जानते हैं

तो git merge बनाम git rebase का प्रश्न लगभग केवल सुविधा शाखाओं में ही लागू होता है (निम्नलिखित उदाहरणों में, --no-ff विलय करने पर, किसी भी --no-ff का हमेशा उपयोग नहीं किया जाता है)। ध्यान दें, क्योंकि मुझे यकीन नहीं है कि एक बेहतर समाधान ( एक बहस मौजूद है ), मैं केवल यह प्रदान करता हूँ कि दोनों आज्ञाओं का व्यवहार कैसे होता है मेरे मामले में, मैं git rebase का उपयोग करना पसंद करता हूं क्योंकि यह एक अच्छा इतिहास पेड़ का उत्पादन करता है 🙂

सुविधा शाखाओं के बीच

git merge

आदेश:

 Time Branch "develop" Branch "features/foo" Branch "features/bar" ------- -------------------------------- ------------------------------- -------------------------------- 15:10 git merge --no-ff features/bar 15:09 git merge --no-ff features/foo 15:08 git commit -m "Sixth commit" 15:07 git merge --no-ff features/foo 15:06 git commit -m "Fifth commit" 15:05 git commit -m "Fourth commit" 15:04 git commit -m "Third commit" 15:03 git commit -m "Second commit" 15:02 git checkout -b features/bar 15:01 git checkout -b features/foo 15:00 git commit -m "First commit" 

परिणाम:

 * c0a3b89 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/bar' - Christophe | * 37e933e - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar) | | Sixth commit - Christophe | * eb5e657 - YYYY-MM-DD 15:07:00 (XX minutes ago) | |\ Merge branch 'features/foo' into features/bar - Christophe | * | 2e4086f - YYYY-MM-DD 15:06:00 (XX minutes ago) | | | Fifth commit - Christophe | * | 31e3a60 - YYYY-MM-DD 15:05:00 (XX minutes ago) | | | Fourth commit - Christophe * | | 98b439f - YYYY-MM-DD 15:09:00 (XX minutes ago) |\ \ \ Merge branch 'features/foo' - Christophe | |/ / |/| / | |/ | * 6579c9c - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo) | | Third commit - Christophe | * 3f41d96 - YYYY-MM-DD 15:03:00 (XX minutes ago) |/ Second commit - Christophe * 14edc68 - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

git rebase

Commands:

 Time Branch "develop" Branch "features/foo" Branch "features/bar" ------- -------------------------------- ------------------------------- ------------------------------- 15:10 git merge --no-ff features/bar 15:09 git merge --no-ff features/foo 15:08 git commit -m "Sixth commit" 15:07 git rebase features/foo 15:06 git commit -m "Fifth commit" 15:05 git commit -m "Fourth commit" 15:04 git commit -m "Third commit" 15:03 git commit -m "Second commit" 15:02 git checkout -b features/bar 15:01 git checkout -b features/foo 15:00 git commit -m "First commit" 

परिणाम:

 * 7a99663 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/bar' - Christophe | * 708347a - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar) | | Sixth commit - Christophe | * 949ae73 - YYYY-MM-DD 15:06:00 (XX minutes ago) | | Fifth commit - Christophe | * 108b4c7 - YYYY-MM-DD 15:05:00 (XX minutes ago) | | Fourth commit - Christophe * | 189de99 - YYYY-MM-DD 15:09:00 (XX minutes ago) |\ \ Merge branch 'features/foo' - Christophe | |/ | * 26835a0 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo) | | Third commit - Christophe | * a61dd08 - YYYY-MM-DD 15:03:00 (XX minutes ago) |/ Second commit - Christophe * ae6f5fc - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

From develop to a feature branch

git merge

Commands:

 Time Branch “develop" Branch "features/foo" Branch "features/bar" ------- -------------------------------- ------------------------------- ------------------------------- 15:10 git merge --no-ff features/bar 15:09 git commit -m “Sixth commit" 15:08 git merge --no-ff development 15:07 git merge --no-ff features/foo 15:06 git commit -m “Fifth commit" 15:05 git commit -m “Fourth commit" 15:04 git commit -m “Third commit" 15:03 git commit -m “Second commit" 15:02 git checkout -b features/bar 15:01 git checkout -b features/foo 15:00 git commit -m “First commit" 

परिणाम:

 * 9e6311a - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/bar' - Christophe | * 3ce9128 - YYYY-MM-DD 15:09:00 (XX minutes ago) (features/bar) | | Sixth commit - Christophe | * d0cd244 - YYYY-MM-DD 15:08:00 (XX minutes ago) | |\ Merge branch 'develop' into features/bar - Christophe | |/ |/| * | 5bd5f70 - YYYY-MM-DD 15:07:00 (XX minutes ago) |\ \ Merge branch 'features/foo' - Christophe | * | 4ef3853 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo) | | | Third commit - Christophe | * | 3227253 - YYYY-MM-DD 15:03:00 (XX minutes ago) |/ / Second commit - Christophe | * b5543a2 - YYYY-MM-DD 15:06:00 (XX minutes ago) | | Fifth commit - Christophe | * 5e84b79 - YYYY-MM-DD 15:05:00 (XX minutes ago) |/ Fourth commit - Christophe * 2da6d8d - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

git rebase

Commands:

 Time Branch “develop" Branch "features/foo" Branch "features/bar" ------- -------------------------------- ------------------------------- ------------------------------- 15:10 git merge --no-ff features/bar 15:09 git commit -m “Sixth commit" 15:08 git rebase development 15:07 git merge --no-ff features/foo 15:06 git commit -m “Fifth commit" 15:05 git commit -m “Fourth commit" 15:04 git commit -m “Third commit" 15:03 git commit -m “Second commit" 15:02 git checkout -b features/bar 15:01 git checkout -b features/foo 15:00 git commit -m “First commit" 

परिणाम:

 * b0f6752 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/bar' - Christophe | * 621ad5b - YYYY-MM-DD 15:09:00 (XX minutes ago) (features/bar) | | Sixth commit - Christophe | * 9cb1a16 - YYYY-MM-DD 15:06:00 (XX minutes ago) | | Fifth commit - Christophe | * b8ddd19 - YYYY-MM-DD 15:05:00 (XX minutes ago) |/ Fourth commit - Christophe * 856433e - YYYY-MM-DD 15:07:00 (XX minutes ago) |\ Merge branch 'features/foo' - Christophe | * 694ac81 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo) | | Third commit - Christophe | * 5fd94d3 - YYYY-MM-DD 15:03:00 (XX minutes ago) |/ Second commit - Christophe * d01d589 - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

Side notes

git cherry-pick

When you just need one specific commit, git cherry-pick is a nice solution (the -x option appends a line that says " (cherry picked from commit…) " to the original commit message body, so it's usually a good idea to use it – git log <commit_sha1> to see it):

Commands:

 Time Branch “develop" Branch "features/foo" Branch "features/bar" ------- -------------------------------- ------------------------------- ----------------------------------------- 15:10 git merge --no-ff features/bar 15:09 git merge --no-ff features/foo 15:08 git commit -m “Sixth commit" 15:07 git cherry-pick -x <second_commit_sha1> 15:06 git commit -m “Fifth commit" 15:05 git commit -m “Fourth commit" 15:04 git commit -m “Third commit" 15:03 git commit -m “Second commit" 15:02 git checkout -b features/bar 15:01 git checkout -b features/foo 15:00 git commit -m “First commit" 

परिणाम:

 * 50839cd - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop) |\ Merge branch 'features/bar' - Christophe | * 0cda99f - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar) | | Sixth commit - Christophe | * f7d6c47 - YYYY-MM-DD 15:03:00 (XX minutes ago) | | Second commit - Christophe | * dd7d05a - YYYY-MM-DD 15:06:00 (XX minutes ago) | | Fifth commit - Christophe | * d0d759b - YYYY-MM-DD 15:05:00 (XX minutes ago) | | Fourth commit - Christophe * | 1a397c5 - YYYY-MM-DD 15:09:00 (XX minutes ago) |\ \ Merge branch 'features/foo' - Christophe | |/ |/| | * 0600a72 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo) | | Third commit - Christophe | * f4c127a - YYYY-MM-DD 15:03:00 (XX minutes ago) |/ Second commit - Christophe * 0cf894c - YYYY-MM-DD 15:00:00 (XX minutes ago) First commit - Christophe 

git pull --rebase

Not sure I can explain it better than Derek Gourlay … Basically, use git pull --rebase instead of git pull 🙂 What's missing in the article though, is that you can enable it by default :

 git config --global pull.rebase true 

git rerere

Again, nicely explained here . But put simple, if you enable it, you won't have to resolve the same conflict multiple times anymore.

Git rebase is used to make the branching paths in history cleaner and repository structure linear.

It is also used to keep the branches created by you private, as after rebasing and pushing the changes to server, if you delete your branch, there will be no evidence of branch you have worked upon. So your branch is now your local concern.

After doing rebase we also get rid of an extra commit which we used to see if we do normal merge.

And yes one still needs to do merge after a successful rebase as rebase command just puts your work on top of the branch you mentioned during rebase say master and makes the first commit of your branch as a direct descendant of the master branch. This means we can now do a fast forward merge to bring changes from this branch to master branch.

Some practical examples, somewhat connected to large scale development where gerrit is used for review and delivery integration.

I merge when i uplift my feature branch to a fresh remote master. This gives minimal uplift work and it's easy to follow the history of the feature development in for example gitk.

 git fetch git checkout origin/my_feature git merge origin/master git commit git push origin HEAD:refs/for/my_feature 

I merge when I prepare a delivery commit.

 git fetch git checkout origin/master git merge --squash origin/my_feature git commit git push origin HEAD:refs/for/master 

I rebase when my delivery commit fails integration for whatever reason and I need to update it towards a fresh remote master.

 git fetch git fetch <gerrit link> git checkout FETCH_HEAD git rebase origin/master git push origin HEAD:refs/for/master 

While merging is definitely the easiest and most common way to integrate changes, it's not the only one: Rebase is an alternative means of integration.

Understanding Merge a Little Better

When Git performs a merge, it looks for three commits:

  • (1) Common ancestor commit If you follow the history of two branches in a project, they always have at least one commit in common: at this point in time, both branches had the same content and then evolved differently.
  • (2) + (3) Endpoints of each branch The goal of an integration is to combine the current states of two branches. Therefore, their respective latest revisions are of special interest. Combining these three commits will result in the integration we're aiming for.

Fast-Forward or Merge Commit

In very simple cases, one of the two branches doesn't have any new commits since the branching happened – its latest commit is still the common ancestor.

यहां छवि विवरण दर्ज करें

In this case, performing the integration is dead simple: Git can just add all the commits of the other branch on top of the common ancestor commit. In Git, this simplest form of integration is called a "fast-forward" merge. Both branches then share the exact same history.

यहां छवि विवरण दर्ज करें

In a lot of cases, however, both branches moved forward individually. यहां छवि विवरण दर्ज करें

To make an integration, Git will have to create a new commit that contains the differences between them – the merge commit.

यहां छवि विवरण दर्ज करें

Human Commits & Merge Commits

Normally, a commit is carefully created by a human being. It's a meaningful unit that wraps only related changes and annotates them with a comment.

A merge commit is a bit different: instead of being created by a developer, it gets created automatically by Git. And instead of wrapping a set of related changes, its purpose is to connect two branches, just like a knot. If you want to understand a merge operation later, you need to take a look at the history of both branches and the corresponding commit graph.

Integrating with Rebase

Some people prefer to go without such automatic merge commits. Instead, they want the project's history to look as if it had evolved in a single, straight line. No indication remains that it had been split into multiple branches at some point.

यहां छवि विवरण दर्ज करें

Let's walk through a rebase operation step by step. The scenario is the same as in the previous examples: we want to integrate the changes from branch-B into branch-A, but now by using rebase.

यहां छवि विवरण दर्ज करें

We will do this in three steps

  1. git rebase branch-A // syncs the history with branch-A
  2. git checkout branch-A // change the current branch to branch-A
  3. git merge branch-B // merge/take the changes from branch-B to branch-A

First, Git will "undo" all commits on branch-A that happened after the lines began to branch out (after the common ancestor commit). However, of course, it won't discard them: instead you can think of those commits as being "saved away temporarily".

यहां छवि विवरण दर्ज करें

Next, it applies the commits from branch-B that we want to integrate. At this point, both branches look exactly the same.

यहां छवि विवरण दर्ज करें

In the final step, the new commits on branch-A are now reapplied – but on a new position, on top of the integrated commits from branch-B (they are re-based). The result looks like development had happened in a straight line. Instead of a merge commit that contains all the combined changes, the original commit structure was preserved.

यहां छवि विवरण दर्ज करें

Finally you get a clean branch branch-A with no unwanted and auto generated commits.

Note: Taken from the awesome post by git-tower . The disadvantages of rebase is also a good read in the same post.