Git rebase बनाम Git मर्ज का उपयोग करने की अनुशंसा कब की जाती है?
क्या मुझे एक सफल छूट के बाद भी विलय करने की आवश्यकता है?
Git rebase बनाम Git मर्ज का उपयोग करने की अनुशंसा कब की जाती है?
क्या मुझे एक सफल छूट के बाद भी विलय करने की आवश्यकता है?
जवाबों:
तो आप एक का उपयोग कब करते हैं?
init
एक नया रेपो, add
फ़ाइल और के साथ एक निर्देशिका बनाएँ commit
। एक नई सुविधा शाखा की जांच करें ( checkout -b feature
।) पाठ फ़ाइल को बदलें, प्रतिबद्ध करें और दोहराएं ताकि सुविधा शाखा पर दो नए कमिट हों। तब checkout master
और merge feature
। में log
, मैं मास्टर पर अपनी प्रारंभिक प्रतिबद्धता देखता हूं, उसके बाद दोनों को फीचर से मिला दिया गया। यदि आप merge --squash feature
, फीचर को मास्टर में विलय कर चुके हैं , लेकिन प्रतिबद्ध नहीं हैं, तो मास्टर पर एकमात्र नई प्रतिबद्धता वही होगी जो आप स्वयं बनाते हैं।
यह आसान है। रिबेस के साथ आप अपने काम के नए आधार के रूप में एक और शाखा का उपयोग करने के लिए कहते हैं।
यदि आपके पास, उदाहरण के लिए, एक शाखा है master
, तो आप एक नई सुविधा को लागू करने के लिए एक शाखा बनाते हैं, और कहते हैं कि आप इसे नाम देते हैं cool-feature
, निश्चित रूप से मास्टर शाखा आपकी नई सुविधा के लिए आधार है।
अब एक निश्चित बिंदु पर आप master
शाखा में लागू नई सुविधा को जोड़ना चाहते हैं । आप बस शाखा में जा सकते हैं master
और विलय कर सकते हैं cool-feature
:
$ git checkout master
$ git merge cool-feature
लेकिन इस तरह एक नई डमी कमिट जुड़ जाती है। यदि आप स्पेगेटी-इतिहास से बचना चाहते हैं, तो आप रिबेट कर सकते हैं :
$ git checkout cool-feature
$ git rebase master
और फिर इसे मर्ज करें master
:
$ git checkout master
$ git merge cool-feature
इस बार, चूंकि विषय शाखा में मास्टर प्लस के समान ही हैं, नई सुविधा के साथ कमिट होते हैं, तो मर्ज सिर्फ एक फास्ट-फॉरवर्ड होगा।
but this way a new dummy commit is added, if you want to avoid spaghetti-history
- यह कैसा बुरा है?
Sean Schofield
इसे एक टिप्पणी में डालता है: "Rebase भी अच्छा है क्योंकि एक बार यू अंततः अंततः मास्टर में उर सामान को मर्ज करता है (जो कि पहले से वर्णित के रूप में तुच्छ है) आपने इसे यूर प्रतिबद्ध इतिहास के" शीर्ष "पर बैठाया है। ऐसी परियोजनाएँ जहाँ सुविधाएँ लिखी जा सकती हैं, लेकिन कई सप्ताह बाद विलय हो जाती हैं, आप उन्हें केवल मास्टर में मर्ज नहीं करना चाहते हैं क्योंकि उन्हें इतिहास में मास्टर तरीके से "भरवां" मिलता है। व्यक्तिगत रूप से मुझे गिट लॉग को देखने और देखने में सक्षम होना पसंद है। "शीर्ष" पर हाल ही की सुविधा सही है। नोट करें कि प्रतिबद्ध तारीखें संरक्षित हैं - रिबास उस जानकारी को नहीं बदलता है। "
merge
, rebase
, fast-forward
, आदि) एक निर्देशित अचक्रीय ग्राफ के विशिष्ट जोड़तोड़ की बात कर रहे। वे मन में उस मानसिक मॉडल के साथ तर्क करना आसान हो जाता है।
TSamper द्वारा उल्लिखित मेरे अपने उत्तर के पूरक के लिए ,
एक रिबेस एक मर्ज से पहले करने के लिए अक्सर एक अच्छा विचार है, क्योंकि विचार यह है कि आप अपनी शाखा में Y
उस शाखा के काम को एकीकृत करते हैं जिस B
पर आप विलय करेंगे।
लेकिन फिर से, विलय करने से पहले, आप अपनी शाखा में किसी भी संघर्ष को हल करते हैं (जैसे: "रिबास", जैसा कि "मेरी शाखा में अपना काम फिर से खेलना है, शाखा से हाल के बिंदु से शुरू करना B
)।
यदि सही ढंग से किया जाता है, तो बाद में आपकी शाखा से विलय होता है। शाखा B
तेजी से आगे बढ़ सकती है।
एक मर्ज सीधे गंतव्य शाखा को प्रभावित करता है B
, जिसका अर्थ है कि विलय बेहतर रूप से तुच्छ हो, अन्यथा वह शाखा B
एक स्थिर स्थिति में वापस आने के लिए लंबी हो सकती है (आपके लिए सभी संघर्षों को हल करने का समय)
छूट के बाद विलय की बात?
इस मामले में कि मैं वर्णन करता हूं, मैं B
अपनी शाखा पर पुन: प्रवेश करता हूं, बस मुझे अपने काम को फिर से शुरू करने का अवसर मिलता है B
, लेकिन मेरी शाखा में रहते हुए।
इस स्थिति में, मेरे "रिप्लेड" कार्य को लाने के लिए मर्ज की आवश्यकता है B
।
अन्य परिदृश्य ( उदाहरण के लिए गित रेडी में वर्णित ), अपने कार्य को सीधे B
रिबेस के माध्यम से लाना है (जो आपके सभी अच्छे कामों का संरक्षण करता है, या यहां तक कि आपको एक इंटरैक्टिव रिबास के माध्यम से उन्हें फिर से आदेश देने का अवसर देता है)।
उस स्थिति में (जहाँ आप B शाखा में रहते हुए छूट देते हैं), आप सही हैं: अब और विलय की आवश्यकता नहीं है:
डिफ़ॉल्ट रूप से एक गिट ट्री जब हमने विलय नहीं किया है और न ही विद्रोह किया है
हम रिबासिंग करवाते हैं:
यह दूसरा परिदृश्य सभी के बारे में है: मैं मास्टर में नए-फ़ीचर वापस कैसे ला सकता हूं।
मेरी बात, पहले रिबास परिदृश्य का वर्णन करते हुए, सभी को याद दिलाना है कि एक रिबेस को प्रारंभिक कदम के रूप में भी इस्तेमाल किया जा सकता है (जो कि "मास्टर में नया-फीचर वापस लाएं")।
आप नई-फीचर शाखा में पहले मास्टर लाने के लिए रिबास का उपयोग कर सकते हैं: रिबेस नए-फीचर कमिट को फिर से चलाएगा HEAD master
, लेकिन फिर भी नए-फीचर ब्रांच में, प्रभावी ढंग से आपकी शाखा को एक पुराने मास्टर कमिट से शुरू करने के लिए स्थानांतरित करेगा HEAD-master
।
यह आपको अपनी शाखा में किसी भी संघर्ष को हल करने की अनुमति देता है (मतलब, अलगाव में, जबकि मास्टर को समानांतर में विकसित करने के लिए जारी रखने की अनुमति देता है यदि आपका संघर्ष समाधान चरण बहुत लंबा लगता है)।
फिर आप मास्टर में जा सकते हैं और मर्ज कर सकते हैं new-feature
(या यदि आप अपने में किए गए कमिट्स को संरक्षित करना चाहते हैं तो रिबास new-feature
कर master
सकते हैं)new-feature
डाली)।
इसलिए:
master
।यदि आपको कोई संदेह है, तो मर्ज का उपयोग करें।
एक रिबेस और मर्ज के बीच केवल अंतर हैं:
तो इसका संक्षिप्त उत्तर यह है कि आप अपने इतिहास को कैसा दिखना चाहते हैं, उसके आधार पर रिबास या मर्ज चुनें ।
कुछ कारक हैं जिन पर आपको विचार करना चाहिए कि किस ऑपरेशन का उपयोग करना है।
यदि हां, तो रिबास न करें। रेबेस शाखा को नष्ट कर देता है और जब तक वे उपयोग नहीं करते हैं, तब तक उन डेवलपर्स के पास टूटी हुई / असंगत रिपॉजिटरी होगीgit pull --rebase
। अन्य डेवलपर्स को जल्दी से परेशान करने का यह एक अच्छा तरीका है।
रीबेस एक विनाशकारी ऑपरेशन है। इसका मतलब है, यदि आप इसे सही तरीके से लागू नहीं करते हैं, तो आप प्रतिबद्ध काम खो सकते हैं और / या अन्य डेवलपर के रिपॉजिटरी की स्थिरता को तोड़ सकते हैं।
मैंने उन टीमों पर काम किया है, जहां डेवलपर्स सभी एक समय से आए थे जब कंपनियां शाखाएं और विलय से निपटने के लिए समर्पित कर्मचारियों को वहन कर सकती थीं। उन डेवलपर्स को Git के बारे में ज्यादा जानकारी नहीं है और वे ज्यादा जानना नहीं चाहते हैं। इन टीमों में मैं किसी भी कारण से रिबासिंग की सिफारिश करने का जोखिम नहीं उठाता।
कुछ टीम शाखा-प्रति-सुविधा मॉडल का उपयोग करती हैं जहां प्रत्येक शाखा एक विशेषता (या बगफिक्स, या उप-सुविधा, आदि) का प्रतिनिधित्व करती है। इस मॉडल में शाखा संबंधित आवागमन के सेट की पहचान करने में मदद करती है। उदाहरण के लिए, कोई भी उस शाखा के विलय को पुनः प्राप्त करके एक सुविधा को वापस ला सकता है (निष्पक्ष होने के लिए, यह एक दुर्लभ ऑपरेशन है)। या दो शाखाओं (अधिक सामान्य) की तुलना करके एक सुविधा को अलग करें। रिबेस शाखा को नष्ट कर देगा और यह सीधा नहीं होगा।
मैंने उन टीमों पर भी काम किया है, जिन्होंने शाखा-प्रति-डेवलपर मॉडल का उपयोग किया है (हम सभी वहां मौजूद हैं)। इस मामले में शाखा स्वयं कोई अतिरिक्त जानकारी नहीं देती है (कमिट पहले से ही लेखक के पास है)। रिबासिंग में कोई नुकसान नहीं होगा।
एक मर्ज को रोकने की तुलना में रिवर्टिंग (पूर्ववत में) एक रिबेज़ काफी मुश्किल और / या असंभव है (यदि रिबेज़ में संघर्ष था)। अगर आपको लगता है कि कोई मौका है जिसे आप वापस करना चाहते हैं तो मर्ज का उपयोग करें।
रिबास संचालन को एक संगत के साथ खींचने की आवश्यकता है git pull --rebase
। यदि आप अपने आप से काम कर रहे हैं, तो आप यह याद रख सकते हैं कि आपको उचित समय पर उपयोग करना चाहिए। यदि आप एक टीम पर काम कर रहे हैं तो यह समन्वय करना बहुत मुश्किल होगा। यही कारण है कि अधिकांश रिबास वर्कफ्लो सभी मर्जों के लिए रिबास (और) का उपयोग करने की सलाह देते हैंgit pull --rebase
सभी पुल के लिए) ।
मान लें कि आपके पास निम्न मर्ज है:
B -- C
/ \
A--------D
कुछ लोग बताएंगे कि मर्ज "इतिहास" को नष्ट कर देता है क्योंकि यदि आप केवल मास्टर शाखा (ए - डी) के लॉग को देखते हैं, तो आप बी और सी में निहित महत्वपूर्ण प्रतिबद्ध संदेशों को याद करेंगे।
अगर यह सच होता तो हमारे पास इस तरह के सवाल नहीं होते । मूल रूप से, आप बी और सी देखेंगे जब तक कि आप स्पष्ट रूप से उन्हें नहीं देखने के लिए कहें (का उपयोग करते हुए - माता-पिता)। अपने लिए प्रयास करना बहुत आसान है।
दोनों दृष्टिकोण अलग-अलग विलय करते हैं, लेकिन यह स्पष्ट नहीं है कि एक हमेशा दूसरे से बेहतर होता है और यह डेवलपर वर्कफ़्लो पर निर्भर हो सकता है। उदाहरण के लिए, यदि कोई डेवलपर नियमित रूप से प्रतिबद्ध होता है (उदाहरण के लिए वे दिन में दो बार काम करते हैं क्योंकि वे घर से काम के लिए संक्रमण करते हैं) तो किसी दिए गए शाखा के लिए बहुत कुछ हो सकता है। उन कमिटों में से कुछ अंतिम उत्पाद की तरह नहीं लग सकते हैं (मैं प्रति बार एक या दो बार अपने दृष्टिकोण को फिर से भरना है)। यदि कोई अन्य व्यक्ति कोड के संबंधित क्षेत्र में काम कर रहा था और उन्होंने मेरे बदलावों को फिर से बनाने की कोशिश की तो यह काफी थकाऊ ऑपरेशन हो सकता है।
यदि आप "समय बचाने" के लिए उपनाम rm
देना पसंद करते हैं rm -rf
तो शायद आपके लिए रिबास है।
मैं हमेशा सोचता हूं कि किसी दिन मैं एक ऐसे परिदृश्य में आऊंगा जहां Git rebase एक भयानक उपकरण है जो समस्या को हल करता है। बहुत कुछ मुझे लगता है कि मैं एक ऐसे परिदृश्य में आऊँगा जहाँ Git reflog एक भयानक उपकरण है जो मेरी समस्या को हल करता है। मैंने अब पांच साल के लिए Git के साथ काम किया है। ऐसा नहीं हुआ है।
गन्दी इतिहास मेरे लिए कभी समस्या नहीं रही। मैं कभी भी एक रोमांचक उपन्यास की तरह अपना प्रतिबद्ध इतिहास नहीं पढ़ता। उस समय के अधिकांश समय के लिए मुझे एक इतिहास की आवश्यकता है, मैं वैसे भी Git दोष या Git द्विशताब्दी का उपयोग करने जा रहा हूं। उस स्थिति में, मर्ज कमिट होना वास्तव में मेरे लिए उपयोगी है, क्योंकि यदि मर्ज ने समस्या को पेश किया, तो यह मेरे लिए सार्थक जानकारी है।
मैं यह उल्लेख करने के लिए बाध्य हूं कि मैंने व्यक्तिगत रूप से रिबेस का उपयोग करने पर नरम किया है, हालांकि मेरी सामान्य सलाह अभी भी है। मैं हाल ही में कोणीय 2 सामग्री परियोजना के साथ बहुत कुछ बातचीत कर रहा हूं । उन्होंने बहुत साफ-सुथरे इतिहास को बनाए रखने के लिए विद्रोह का इस्तेमाल किया है। यह मुझे बहुत आसानी से यह देखने की अनुमति देता है कि किसी दिए गए दोष का क्या निर्धारण किया गया है और क्या वह प्रतिबद्ध एक रिलीज में शामिल किया गया था या नहीं। यह रिबास का सही ढंग से उपयोग करने का एक बड़ा उदाहरण है।
यहां बहुत सारे उत्तर कहते हैं कि विलय आपके सभी कमिट्स को एक में बदल देता है, और इसलिए अपने कमिट्स को संरक्षित करने के लिए रिबेस का उपयोग करने का सुझाव देता है। यह गलत है। और एक बुरा विचार अगर आपने अपने कमिट्स को पहले ही धक्का दे दिया है ।
मर्ज आपके कमिट को अनपढ़ नहीं करता है। मेराज इतिहास रचता है! (बस gitk को देखें) रिबेस इतिहास को फिर से लिखता है, जिसे आपने इसे धकेलने के बाद एक खराब चीज है।
मर्ज का उपयोग करें - जब भी आप पहले ही धक्का दे चुके हों, तब रिबास न करें ।
यहाँ लिनुस '(गिट के लेखक) इसे लेते हैं (अब मेरे अपने ब्लॉग पर होस्ट किया गया है, जैसा कि वेबैक मशीन द्वारा पुनर्प्राप्त किया गया है )। यह वास्तव में अच्छा पढ़ा है।
या आप एक ही विचार के अपने स्वयं के संस्करण को नीचे पढ़ सकते हैं।
मास्टर पर एक शाखा रिबासिंग:
इसके विपरीत, विषय शाखा को मास्टर में विलय करना:
TLDR: यह इस बात पर निर्भर करता है कि सबसे महत्वपूर्ण क्या है - एक सुव्यवस्थित इतिहास या विकास के अनुक्रम का सच्चा प्रतिनिधित्व
यदि एक सुव्यवस्थित इतिहास सबसे महत्वपूर्ण है, तो आप पहले रिबास करेंगे और फिर अपने परिवर्तनों को मर्ज करेंगे, इसलिए यह स्पष्ट है कि नया कोड क्या है। यदि आपने पहले ही अपनी शाखा को धक्का दे दिया है, तो तब तक रिबास न करें जब तक आप परिणामों से निपट नहीं सकते।
यदि अनुक्रम का सच्चा प्रतिनिधित्व सबसे महत्वपूर्ण है, तो आप बिना पुनरावृत्ति के विलय करेंगे।
मर्ज का अर्थ है: एक नया कमिट बनाएं जो मेरे बदलावों को गंतव्य में विलय कर दे। नोट: इस नई कमिट में दो अभिभावक होंगे - आपकी कमिट के तार से नवीनतम कमिट और आप जिस अन्य शाखा में विलय कर रहे हैं उसकी नवीनतम कमेटी।
रिबेस का अर्थ है: मेरे वर्तमान के सेट का उपयोग करके संकेत के रूप में, कमिट की एक पूरी नई श्रृंखला बनाएं। दूसरे शब्दों में, गणना करें कि मेरे परिवर्तन क्या दिखते हैं यदि मैंने उन्हें उस बिंदु से बनाना शुरू कर दिया है जिस पर मैं फिर से विचार कर रहा हूं। रिबास के बाद, इसलिए, आपको अपने परिवर्तनों का पुन: परीक्षण करने की आवश्यकता हो सकती है और रिबेस के दौरान, आपको संभवतः कुछ संघर्ष करना होगा।
यह देखते हुए, आप क्यों प्रतिपूर्ति करेंगे? सिर्फ विकास के इतिहास को स्पष्ट रखने के लिए। मान लीजिए कि आप फ़ीचर X पर काम कर रहे हैं और जब आप काम पूरा कर लेते हैं, तो आप अपने परिवर्तनों को मर्ज कर देते हैं। गंतव्य अब एक एकल प्रतिबद्ध होगा जो "एडेड फ़ीचर X" की तर्ज पर कुछ कहेगा। अब, विलय के बजाय, यदि आप बगावत कर गए और फिर विलीन हो गए, तो गंतव्य विकास इतिहास में सभी व्यक्ति एकल तार्किक तर्क में शामिल होंगे। यह बाद में बहुत आसान बदलावों की समीक्षा करता है। कल्पना करें कि यदि 50 डेवलपर्स हर समय विभिन्न विशेषताओं का विलय कर रहे थे, तो आपको विकास के इतिहास की समीक्षा करना कितना मुश्किल होगा।
उस ने कहा, यदि आप पहले से ही उस शाखा को धक्का दे चुके हैं जो आप ऊपर की तरफ काम कर रहे हैं, तो आपको रिबास नहीं करना चाहिए, बल्कि इसके बजाय विलय करना चाहिए। उन शाखाओं के लिए जिन्हें अपस्ट्रीम, रिबेस, टेस्ट और मर्ज नहीं किया गया है।
एक और समय जब आप रिबास करना चाहते हैं, जब आप ऊपर की तरफ धकेलने से पहले अपनी शाखा से आवागमन से छुटकारा पाना चाहते हैं। उदाहरण के लिए: कमिट जो कुछ डिबगिंग कोड को जल्दी शुरू करते हैं और दूसरे उस कोड को साफ करते हैं। ऐसा करने का एकमात्र तरीका एक इंटरैक्टिव रिबास प्रदर्शन है:git rebase -i <branch/commit/tag>
अद्यतन: आप रिसेट का उपयोग तब भी करना चाहते हैं जब आप Git को इंटरफ़ेस का उपयोग एक ऐसे संस्करण नियंत्रण प्रणाली में करते हैं जो गैर-रेखीय इतिहास ( उदाहरण के लिए तोड़फोड़ ) का समर्थन नहीं करता है । Git-svn पुल का उपयोग करते समय, यह बहुत महत्वपूर्ण है कि आप जो बदलाव Subversion में वापस मर्ज करते हैं, वे ट्रंक में सबसे हाल के परिवर्तनों के शीर्ष पर हुए परिवर्तनों की एक क्रमिक सूची है। ऐसा करने के केवल दो तरीके हैं: (1) मैन्युअल रूप से बदलावों को फिर से बनाएं और (2) रीबेज कमांड का उपयोग करें, जो बहुत तेज है।
अद्यतन 2: एक रिबास के बारे में सोचने का एक अतिरिक्त तरीका यह है कि यह आपके विकास शैली से उस शैली में मैपिंग की शैली को स्वीकार करने में सक्षम बनाता है जिसे आप अपना रहे हैं। मान लीजिए कि आप छोटे, छोटे टुकड़ों में प्रतिबद्ध हैं। आपके पास एक टाइपो को ठीक करने के लिए एक है, एक अप्रयुक्त कोड से छुटकारा पाने के लिए प्रतिबद्ध है और इसी तरह। जब आप पूरा कर लेते हैं, तब तक आपके पास काम करने की एक लंबी श्रृंखला होती है। अब कहते हैं कि आप जिस बड़े काम के लिए प्रोत्साहित कर रहे हैं उसे रिपॉजिटरी करते हैं, इसलिए आप जो काम कर रहे हैं, उसके लिए आपको एक या एक ही हिट की उम्मीद होगी। आप अपनी कमिटियों के तार को कैसे लेते हैं और उन्हें उम्मीद के मुताबिक संकुचित करते हैं? आप एक इंटरेक्टिव रिबास का उपयोग करेंगे और अपने छोटे-छोटे कामों को कम मात्रा में करेंगे। यदि रिवर्स की आवश्यकता थी तो वही सच है - अगर आपकी शैली कुछ बड़ी थी, लेकिन रिपॉजिटरी ने छोटे-छोटे आवागमन के लंबे तार की मांग की। आप ऐसा करने के लिए एक छूट का उपयोग करेंगे। यदि आप इसके बजाय विलीन हो गए थे, तो अब आपने मुख्य भंडार पर अपनी प्रतिबद्ध शैली तैयार कर ली है। यदि बहुत सारे डेवलपर्स हैं, तो आप कल्पना कर सकते हैं कि कुछ समय बाद कई अलग-अलग प्रतिबद्ध शैलियों के साथ एक इतिहास का पालन करना कितना कठिन होगा।
अद्यतन 3: Does one still need to merge after a successful rebase?
हाँ, आप करते हैं। कारण यह है कि एक रिबेट में अनिवार्य रूप से एक "स्थानांतरण" होता है। जैसा कि मैंने ऊपर कहा है, इन कमिट्स की गणना की जाती है, लेकिन अगर आपके पास ब्रांचिंग के बिंदु से 14 कमिट्स थे, तो यह मानकर कि आपके रिबेस के साथ कुछ भी गलत नहीं होता है, आप 14 कमिट्स आगे होंगे (जिस बिंदु पर आप रिबास कर रहे हैं) रिबास किया जाता है। आपके पास रिबास से पहले एक शाखा थी। आपके पास एक ही लंबाई की एक शाखा होगी। अपने परिवर्तन प्रकाशित करने से पहले आपको अभी भी विलय करने की आवश्यकता है। दूसरे शब्दों में, जितनी बार चाहें उतनी बार रीबेज करें (फिर से, केवल तभी जब आपने अपने परिवर्तनों को ऊपर की ओर नहीं धकेला हो)। पुनर्जन्म के बाद ही विलय करें।
git merge
उस --no-ff
विकल्प का समर्थन करता है जो इसे मर्ज करने के लिए बाध्य करता है ।
विलय को निश्चित रूप से बदलावों को एकीकृत करने का सबसे आसान और सबसे आम तरीका है, यह एकमात्र नहीं है: रिबेस एकीकरण का एक वैकल्पिक साधन है।
मर्ज को थोड़ा बेहतर समझना
जब Git एक मर्ज करता है, तो वह तीन कमिटों को देखता है:
फास्ट-फॉरवर्ड या मर्ज कमिट
बहुत ही सरल मामलों में, दो शाखाओं में से एक में कोई नया कमिट नहीं है क्योंकि ब्रांचिंग हुई है - इसकी नवीनतम प्रतिबद्धता अभी भी सामान्य पूर्वज है।
इस मामले में, एकीकरण का प्रदर्शन आसान है: जीआईटी सामान्य शाखा के सामान्य प्रतिबद्ध के शीर्ष पर अन्य शाखा के सभी कमिट्स को जोड़ सकता है। गिट में, एकीकरण के इस सरलतम रूप को "फास्ट-फॉरवर्ड" मर्ज कहा जाता है। दोनों शाखाएं फिर समान इतिहास साझा करती हैं।
बहुत सारे मामलों में, हालांकि, दोनों शाखाएँ व्यक्तिगत रूप से आगे बढ़ीं।
एकीकरण करने के लिए, Git को एक नई कमिट बनानी होगी जिसमें उनके बीच का अंतर हो - मर्ज कमिट।
मानव कमिट और मर्ज कमिट
आम तौर पर, एक इंसान द्वारा सावधानीपूर्वक कमिट बनाई जाती है। यह एक सार्थक इकाई है जो केवल संबंधित परिवर्तनों को लपेटती है और उन्हें टिप्पणी के साथ एनोटेट करती है।
एक मर्ज कमिट थोड़ा अलग है: एक डेवलपर द्वारा बनाए जाने के बजाय, यह गिट द्वारा स्वचालित रूप से बनाया जाता है। और संबंधित परिवर्तनों का एक सेट लपेटने के बजाय, इसका उद्देश्य गाँठ की तरह, दो शाखाओं को जोड़ना है। यदि आप बाद में एक मर्ज ऑपरेशन को समझना चाहते हैं, तो आपको दोनों शाखाओं के इतिहास और संबंधित प्रतिबद्ध ग्राफ पर एक नज़र डालने की आवश्यकता है।
रिबेस के साथ एकीकरण
कुछ लोग ऐसे स्वचालित मर्ज के बिना जाना पसंद करते हैं। इसके बजाय, वे चाहते हैं कि परियोजना का इतिहास ऐसा दिखे जैसे कि यह एक सीधी रेखा में विकसित हुआ था। कोई संकेत नहीं है कि यह किसी बिंदु पर कई शाखाओं में विभाजित हो गया था।
चलो एक रिबेस ऑपरेशन कदम से कदम के माध्यम से चलते हैं। परिदृश्य पिछले उदाहरणों की तरह ही है: हम शाखा-बी से परिवर्तन को शाखा-ए में एकीकृत करना चाहते हैं, लेकिन अब रिबेस का उपयोग करके।
हम इसे तीन चरणों में करेंगे
git rebase branch-A // Synchronises the history with branch-A
git checkout branch-A // Change the current branch to branch-A
git merge branch-B // Merge/take the changes from branch-B to branch-A
सबसे पहले, Git, "पूर्ववत" करेगा, जो शाखा-ए पर होता है, जो लाइनों को शाखा से निकालने के बाद (सामान्य पूर्वजों की प्रतिबद्धता के बाद) हुआ था। हालांकि, निश्चित रूप से, यह उन्हें नहीं छोड़ेगा: इसके बजाय आप उन लोगों के बारे में सोच सकते हैं जो "अस्थायी रूप से बच गए" हैं।
अगला, यह शाखा-बी से उन कमिटों को लागू करता है जिन्हें हम एकीकृत करना चाहते हैं। इस बिंदु पर, दोनों शाखाएं एक समान दिखती हैं।
अंतिम चरण में, शाखा-ए पर नए कमिट अब फिर से लागू किए जाते हैं - लेकिन एक नई स्थिति पर, शाखा-बी से एकीकृत कमिट्स के शीर्ष पर (वे फिर से आधारित होते हैं)।
परिणाम ऐसा लगता है जैसे विकास एक सीधी रेखा में हुआ था। मर्ज कमिट के बजाय जिसमें सभी संयुक्त परिवर्तन होते हैं, मूल प्रतिबद्ध संरचना संरक्षित थी।
अंत में, आपको एक साफ शाखा शाखा-ए मिलती है जिसमें कोई अवांछित और ऑटो उत्पन्न नहीं होता है।
नोट: भयानक पोस्ट से लिया गया git-tower
। नुकसान की rebase
भी एक अच्छा एक ही पोस्ट में पढ़ा है।
विलय / छूट से पहले:
A <- B <- C [master]
^
\
D <- E [branch]
के बाद git merge master
:
A <- B <- C
^ ^
\ \
D <- E <- F
के बाद git rebase master
:
A <- B <- C <- D' <- E'
(ए, बी, सी, डी, ई और एफ कमिट हैं)
इस उदाहरण और बहुत अच्छी तरह से Git के बारे में सचित्र जानकारी Git द बेसिक्स ट्यूटोरियल में पाई जा सकती है ।
इस वाक्य को यह मिलता है:
सामान्य तौर पर, दोनों दुनिया में सबसे अच्छा पाने का तरीका आपके द्वारा किए गए स्थानीय परिवर्तनों को रद्द करना है, लेकिन अभी तक साझा नहीं किया गया है, इससे पहले कि आप अपनी कहानी को साफ़ करने के लिए उन्हें धक्का दें, लेकिन कभी भी किसी भी चीज़ को न धकेलें, जो आपने कहीं धकेल दी हो ।
यह उत्तर Git Flow के आसपास व्यापक रूप से उन्मुख है । टेबल अच्छा के साथ उत्पन्न हो रही हैं ASCII तालिका जेनरेटर , और इस अद्भुत आदेश (के साथ इतिहास के पेड़ एलियास के रूप में 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
आदेश:
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
हमेशा विलय करते समय उपयोग किया गया है)। ध्यान दें कि चूंकि मुझे यकीन नहीं है कि एक बेहतर समाधान ( एक बहस मौजूद है ), मैं केवल यह बताऊंगा कि दोनों कमांड कैसे व्यवहार करते हैं। मेरे मामले में, मैं 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
आदेश:
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
develop
एक सुविधा शाखा कोgit merge
आदेश:
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 develop
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
आदेश:
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 develop
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
git cherry-pick
जब आपको बस एक विशिष्ट प्रतिबद्ध की आवश्यकता होती है, git cherry-pick
तो एक अच्छा समाधान होता है ( -x
विकल्प एक पंक्ति को जोड़ता है जो कहता है " (चेरी प्रतिबद्ध से ...) " मूल प्रतिबद्ध संदेश शरीर के लिए, इसलिए यह आमतौर पर इसका उपयोग करने के लिए एक अच्छा विचार है - git log <commit_sha1>
देखने के लिए यह):
आदेश:
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
मुझे यकीन नहीं है कि मैं इसे डेरेक गोरले से बेहतर समझा सकता हूं ... मूल रूप से, git pull --rebase
इसके बजाय का उपयोग करें git pull
:) लेख में क्या गायब है हालांकि, यह है कि आप इसे डिफ़ॉल्ट रूप से सक्षम कर सकते हैं :
git config --global pull.rebase true
git rerere
फिर, अच्छी तरह से यहाँ समझाया । लेकिन सीधे शब्दों में कहें, अगर आप इसे सक्षम करते हैं, तो आपको एक ही संघर्ष को कई बार हल नहीं करना पड़ेगा।
प्रो Git किताब पर एक बहुत अच्छी व्याख्या है रिबेसिंग पेज ।
मूल रूप से एक मर्ज दो कमिट ले जाएगा और उन्हें संयोजित करेगा।
एक रिबेस दो पर आम पूर्वज के पास जाएगा और एक दूसरे के ऊपर परिवर्तन को लागू करेगा। यह एक 'क्लीनर' और अधिक रैखिक इतिहास के लिए बनाता है।
लेकिन जब आप रिबेट करते हैं, तो आप पिछले कमिट्स को छोड़ देते हैं और नए बनाते हैं। इसलिए आपको कभी भी एक रिपॉजिटरी को सार्वजनिक नहीं करना चाहिए। रिपॉजिटरी पर काम करने वाले दूसरे लोग आपसे नफरत करेंगे।
उस कारण से मैं अकेले लगभग विलीन हो गया। 99% समय मेरी शाखाओं में इतना अंतर नहीं होता है, इसलिए यदि संघर्ष होते हैं तो यह केवल एक या दो स्थानों पर होता है।
Git rebase का इस्तेमाल हिस्ट्री क्लीनर और रिपॉजिटरी स्ट्रक्चर को रैखिक बनाने के लिए ब्रांचिंग रास्तों को बनाने के लिए किया जाता है।
इसका उपयोग आपके द्वारा बनाई गई शाखाओं को निजी रखने के लिए भी किया जाता है, क्योंकि सर्वर में परिवर्तन को पुन: शुरू करने और धकेलने के बाद, यदि आप अपनी शाखा को हटा देते हैं, तो आपके द्वारा काम की गई शाखा का कोई सबूत नहीं होगा। इसलिए आपकी शाखा अब आपकी स्थानीय चिंता है।
रिबेस करने के बाद हमें एक अतिरिक्त कमिटमेंट से भी छुटकारा मिलता है जिसे हम देखते थे कि क्या हम एक सामान्य मर्ज करते हैं।
और हाँ, किसी को अभी भी एक सफल रिबास के बाद मर्ज करने की आवश्यकता है क्योंकि रिबास कमांड सिर्फ आपके काम को रिबेस के दौरान उल्लिखित शाखा के शीर्ष पर रखता है, मास्टर का कहना है, और मास्टर ब्रांच के प्रत्यक्ष वंशज के रूप में अपनी शाखा की पहली प्रतिबद्ध बनाता है । इसका अर्थ है कि अब हम इस शाखा से मास्टर शाखा में परिवर्तन लाने के लिए एक तेज़ फॉरवर्ड मर्ज कर सकते हैं।
कुछ व्यावहारिक उदाहरण, कुछ हद तक बड़े पैमाने पर विकास से जुड़े हुए हैं जहां जेरिट का उपयोग समीक्षा और वितरण एकीकरण के लिए किया जाता है:
जब मैं अपनी सुविधा शाखा को एक नए दूरस्थ मास्टर में बढ़ाता हूं, तो मैं विलीन हो जाता हूं। यह न्यूनतम उत्थान कार्य देता है और उदाहरण gitk के लिए फीचर विकास के इतिहास का पालन करना आसान है ।
git fetch
git checkout origin/my_feature
git merge origin/master
git commit
git push origin HEAD:refs/for/my_feature
जब मैं एक डिलीवरी कमिट तैयार करता हूं, तो मैं विलीन हो जाता हूं।
git fetch
git checkout origin/master
git merge --squash origin/my_feature
git commit
git push origin HEAD:refs/for/master
जब मेरा डिलीवरी कमिटमेंट किसी भी कारण से एकीकरण में विफल रहता है, तो मैं इसे रिजेक्ट कर देता हूं, और मुझे इसे एक नए दूरस्थ मास्टर की ओर अपडेट करना होगा।
git fetch
git fetch <gerrit link>
git checkout FETCH_HEAD
git rebase origin/master
git push origin HEAD:refs/for/master
यह कई बार समझाया गया था कि क्या रिबेस और मर्ज क्या है, लेकिन आपको कब उपयोग करना चाहिए?
आपको रिबास का उपयोग कब करना चाहिए?
जैसे-जैसे गिट रीबेस इतिहास बदलता है। इसलिए आपको इसका उपयोग तब नहीं करना चाहिए जब कोई अन्य उसी शाखा पर काम कर रहा हो / यदि आपने उसे धक्का दिया हो। लेकिन अगर आपके पास एक स्थानीय शाखा है तो आप एक क्लीनर इतिहास रखने के लिए अपनी शाखा को वापस मास्टर में विलय करने से पहले एक मर्ज रिबेस मास्टर कर सकते हैं। ऐसा करने से, मास्टर शाखा में विलय के बाद यह दिखाई नहीं देगा कि आपने मास्टर शाखा में एक शाखा का उपयोग किया है - इतिहास "क्लीनर" है क्योंकि आपके पास ऑटो-जनरेट "मर्ज .." नहीं है, लेकिन फिर भी है "मर्ज किए गए .." के बिना आपके मास्टर ब्रांच में पूरा इतिहास।
सुनिश्चित करें कि, आप git merge feature-branch --ff-only
यह सुनिश्चित करने के लिए उपयोग करते हैं कि जब आप अपनी सुविधा को मुख्य रूप से मर्ज कर रहे हैं, तो कोई भी एकल कमिट बनाने का कोई विरोध न हो। यह दिलचस्प है यदि आप अपने द्वारा काम करने वाले प्रत्येक कार्य के लिए सुविधा शाखाओं का उपयोग कर रहे हैं जैसा कि आप सुविधा शाखा का इतिहास प्राप्त करते हैं, लेकिन "मेरिट .." प्रतिबद्ध नहीं है
एक दूसरा परिदृश्य होगा, यदि आप एक शाखा से शाखा लेते हैं और जानना चाहते हैं कि मुख्य शाखा में क्या बदलाव आया है। रिबेस आपको जानकारी देता है क्योंकि इसमें हर एक कमेटी शामिल है।
आपको मर्ज का उपयोग कब करना चाहिए?
जब आपको अपनी मास्टर शाखा में किसी सुविधा शाखा के इतिहास की आवश्यकता नहीं है या चाहते हैं या यदि अन्य एक ही शाखा में काम कर रहे हैं / तो आपने उसे धक्का दे दिया है। यदि आप अभी भी इतिहास रखना चाहते हैं, तो फीचर शाखा को मास्टर में विलय करने से पहले सिर्फ फीचर शाखा में मास्टर मर्ज करें। इसका परिणाम होगा कि आप अपने मास्टर में सुविधा शाखा का इतिहास तेजी से आगे मर्ज करेंगे (मर्ज कमिट जो आपकी सुविधा शाखा में थी क्योंकि आपने इसमें मास्टर मर्ज किया था)।
मैं कब उपयोग git rebase
करूं? लगभग कभी नहीं, क्योंकि यह इतिहास को फिर से लिखता है। git merge
लगभग हमेशा बेहतर विकल्प है, क्योंकि यह इस बात का सम्मान करता है कि वास्तव में आपकी परियोजना में क्या हुआ है।