मास्टर में गिट शाखा को मर्ज करने का सबसे अच्छा (और सबसे सुरक्षित) तरीका क्या है?


2101

से एक नई शाखा masterबनाई जाती है, जिसे हम कहते हैं test

कई डेवलपर्स हैं जो या तो masterअन्य शाखाएं बनाते हैं या बनाते हैं और बाद में विलय कर देते हैं master

मान लीजिए कि काम में testकई दिनों का समय लग रहा है और आप लगातार testकमिट्स के अंदर अपडेट रहना चाहते हैं master

मैं git pull origin masterसे करूँगा test

प्रश्न 1: क्या यह सही दृष्टिकोण है? अन्य डेवलपर्स आसानी से एक ही फाइलों पर काम कर सकते थे जैसे मैंने btw काम किया है।


मेरा काम पूरा हो गया testहै और मैं इसे वापस मर्ज करने के लिए तैयार हूं master। यहां दो तरीके बताए जा सकते हैं:

ए:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

बी:

git checkout test
git pull origin master
git checkout master
git merge test

मैं उपयोग नहीं कर रहा हूं --rebaseक्योंकि मेरी समझ से, रिबेज से बदलाव मिलेगा masterऔर इसके शीर्ष पर मेरा स्टैक होगा, इसलिए यह उन लोगों के बदलाव को अधिलेखित कर सकता है जो अन्य लोगों ने किए हैं।

प्रश्न 2: इन दोनों में से कौन सी विधि सही है? वहाँ क्या अंतर है?

इस सब में लक्ष्य यह है कि मैं अपनी testशाखा को आगे चल रही चीजों के साथ अद्यतन रखूं masterऔर बाद में मैं उन्हें masterसमय-सीमा को यथासंभव रैखिक बनाए रखने की उम्मीद में विलय कर सकूं ।


18
नहीं .. छूट कभी भी अधिलेखित नहीं होती है, यह सिर्फ एक क्लीनर इतिहास प्राप्त करने की कोशिश कर रही है। Reattach (या नकली) द्वारा मास्टर के देर से बिंदु पर इतिहास
Junchen लियू

7
रिबास आपके कमिट को अधिलेखित नहीं करता है। यह आपके कमिट्स को अनडू करता है, आपके टेस्ट ब्रांच के लिए मास्टर ब्रांच में कमिट्स लागू करता है, फिर आपके कमिट्स को टेस्ट करने के लिए वापस लागू करता है।
जुन्डी

जवाबों:


2991

मैं यह कैसे करूँगा

git checkout master
git pull origin master
git merge test
git push origin master

अगर मेरे पास रिमोट से एक स्थानीय शाखा है, तो मुझे रिमोट के साथ इस की तुलना में अन्य शाखाओं को विलय करने में सहज महसूस नहीं होता है। इसके अलावा, मैं अपने बदलावों को आगे नहीं बढ़ाऊंगा, जब तक मैं खुश नहीं हो जाऊंगा कि मैं क्या करना चाहता हूं और साथ ही मैं उन चीजों को भी नहीं बढ़ाऊंगा, जो केवल मेरे और मेरे स्थानीय भंडार के लिए हैं। आपके वर्णन में ऐसा लगता है, testयह केवल आपके लिए है? तो इसे प्रकाशित करने का कोई कारण नहीं।

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


2
git merge testमुझे देता है fatal: 'test' does not point to a commit। मुझे git logपरीक्षण शाखा पर प्रतिबद्ध बिंदु के लिए देखना है , फिर मास्टर शाखा पर वापस जाना है git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234
डंकनमो डे

17
@ डंकनू वेल, बेशक शाखा testमौजूद होना चाहिए। ज़रूर, आप इसके बजाय प्रतिबद्ध हैश का उपयोग कर सकते हैं, लेकिन आमतौर पर शाखा नाम का उपयोग करना आसान है। आंतरिक रूप से यह सिर्फ HEADशाखा के हैश को पुनः प्राप्त करता है ।
किंगक्रंच

44
@shanyangqu रिमोट से नवीनतम परिवर्तन प्राप्त करने के लिए। यदि आप अकेले और केवल एक प्रणाली के साथ काम करते हैं तो कोई समस्या नहीं है। लेकिन जब एक अलग प्रणाली (शायद एक अलग डेवलपर से) से धकेल दिए गए परिवर्तन होते हैं, तो जैसे ही आप अपने मर्ज को वापस लाने की कोशिश करते हैं (4 वां कदम)। एकमात्र उपाय अब अपने स्थानीय मास्टर को रिमोट्स मास्टर में विलय करना है, जो कि मूल / मास्टर में एक बहुत बदसूरत "मर्ज किए गए मास्टर" मर्ज कमिट में समाप्त होता है। इसलिए मर्ज से पहले एक पुल बनाना हमेशा एक अच्छा विचार है
KingCrunch

7
"आपके विवरण में ऐसा लगता है, वह परीक्षा केवल आपके लिए है? इसलिए इसे प्रकाशित करने का कोई कारण नहीं है।" आप अपनी स्थानीय शाखा को किसी सर्वर तक पहुंचाना चाहें, उदाहरण के लिए, वह सर्वर आपके स्थानीय ड्राइव के विफल होने के खिलाफ बैकअप प्रदान करता है या यदि आपके पास बैकअप करने के लिए कोई अन्य साधन नहीं है।
एरिक

5
"... इसके अलावा, मैं अपने बदलावों को आगे नहीं बढ़ाऊंगा, जब तक कि मैं जो धक्का देना चाहता हूं उससे खुश हूं ..." आपके स्थानीय मशीनों के मरने और प्रयासों के दिनों में आपके कोड के बैकअप के लिए क्यों नहीं जोर दिया जा रहा है चले गए हैं?
रिच स्टोन

399

यह एक बहुत ही व्यावहारिक प्रश्न है, लेकिन उपरोक्त सभी उत्तर व्यावहारिक नहीं हैं।

पसंद

git checkout master
git pull origin master
git merge test
git push origin master

इस दृष्टिकोण के दो मुद्दे हैं :

  1. यह असुरक्षित है, क्योंकि हमें नहीं पता कि परीक्षण शाखा और मास्टर शाखा के बीच कोई संघर्ष है या नहीं।

  2. यह "निचोड़" करेगा सभी परीक्षण मास्टर पर एक मर्ज कमिट में होता है; यह मास्टर शाखा पर कहना है, हम परीक्षण शाखा के सभी परिवर्तन लॉग नहीं देख सकते हैं।

इसलिए, जब हमें संदेह होता है कि कुछ संघर्ष होंगे, तो हम निम्नलिखित कार्य कर सकते हैं:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

mergeपहले परीक्षण करें commit, एक फास्ट-फॉरवर्ड कमिट से बचें --no-ff,

यदि संघर्ष का सामना करना पड़ता है, तो हम git statusसंघर्षों के बारे में विवरण की जांच करने और हल करने का प्रयास कर सकते हैं

git status

एक बार जब हम संघर्षों को हल कर लेते हैं, या कोई संघर्ष नहीं होता है, तो हम commitऔर pushवे

git commit -m 'merge test branch'
git push

लेकिन इस तरह से परीक्षण शाखा में लॉग किए गए परिवर्तन इतिहास को खो देंगे, और यह परियोजना के इतिहास को समझने के लिए अन्य डेवलपर्स के लिए मास्टर शाखा को कठिन बना देगा।

तो सबसे अच्छा तरीका यह है कि हमें rebaseइसके बजाय merge(मान लीजिए, जब इस समय में, हमने शाखा संघर्षों को हल कर लिया है)।

निम्नलिखित एक सरल नमूना है, उन्नत संचालन के लिए, कृपया http://git-scm.com/book/en/v2/Git-Branching-Rebasing देखें

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

हां, जब आपने uppers कर लिया है, तो सभी टेस्ट शाखा के कमिट्स को मास्टर शाखा के प्रमुख पर ले जाया जाएगा। रिबासिंग का प्रमुख लाभ यह है कि आपको एक रेखीय और ज्यादा क्लीनर प्रोजेक्ट इतिहास मिलता है।

केवल एक चीज जिससे आपको बचने की आवश्यकता है: rebaseसार्वजनिक शाखा पर कभी भी उपयोग न करें , जैसे कि मास्टर शाखा।

कभी भी निम्न कार्य न करें :

git checkout master
git rebase -i test

Https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing का विवरण

अनुबंध:


4
मैं सहमत हूं कि बाद में मास्टर में विलय के लिए परीक्षण शाखा को फिर से तैयार करना है। यहां तक ​​कि अन्य उत्तर सही हैं, यह मास्टर के सिर में शाखा परीक्षण के परिवर्तनों का इतिहास रखेगा क्योंकि ऑटेर उल्लेख "आपको एक लाइनर और बहुत क्लीनर प्रोजेक्ट मिलता है" जो कि संस्करण नियंत्रण प्रणाली का उद्देश्य है।
le0diaz

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

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

3
रिबेज -आई क्यों?
मुशायस

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

90

न तो रिबास और न ही मर्ज को किसी के बदलाव को ओवरराइट करना चाहिए (जब तक कि आप किसी संघर्ष को हल करते समय ऐसा नहीं करते हैं)।

विकसित होते समय सामान्य दृष्टिकोण

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

जब आप मास्टर में वापस विलय करने के लिए तैयार हों,

git checkout master
git log ..test # if you're curious
git merge test
git push

यदि आप मर्ज पर कुछ तोड़ने के बारे में चिंतित हैं, git merge --abortतो क्या आप के लिए है।

पुश का उपयोग करना और फिर विलय के साधन के रूप में खींचना मूर्खतापूर्ण है। मुझे यह भी पता नहीं है कि आप परीक्षण को उत्पत्ति पर क्यों धकेल रहे हैं।


1
इस प्रक्रिया से कमिट की संख्या बढ़ जाएगी, हर बार जब आप शाखाओं के बीच स्विच करते हैं, तो आपको अपनी शाखा करनी होगी।
जुग

2
क्या? क्या आप यह कह रहे हैं कि यह हर बार जब आप शाखाओं को स्विच करते हैं, तो इसकी संख्या बढ़ जाएगी? या क्या आप कह रहे हैं कि हर बार जब आप शाखाएँ बदलते हैं, तो आपको "अपनी शाखा करना होगा"? पहला असत्य है और मुझे यकीन नहीं है कि दूसरा क्या है।
रेउल जूल

चेकआउट करने से पहले, आपको शाखा करनी होगी। यही मैं कह रहा हूँ
iBug

11
आप ऐसा नहीं करते: यह (चीजों में से एक) git stashहै।
msanford

1
या आप अपनी पिछली प्रतिबद्धताओं (स्थानीय शाखा में) को रद्द कर सकते हैं और धक्का देने से पहले इसे सही बना सकते हैं।
व्हिहाट्क

42

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

KingCrunches जवाब के अलावा , मैं उपयोग करने का सुझाव देता हूं

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

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

संपादित करें: आप में रुचि हो सकती है

इसलिए GitHub पर, मैं एक सुविधा शाखा के लिए निम्नलिखित कार्य कर रहा हूं mybranch:

मूल से नवीनतम प्राप्त करें

$ git checkout master
$ git pull origin master

मर्ज बेस हैश का पता लगाएं:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

अब सुनिश्चित करें कि केवल पहला है pick, बाकी है s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

अगला एक बहुत अच्छा प्रतिबद्ध संदेश चुनें और GitHub पर धकेलें। पुल अनुरोध तब करें।

पुल अनुरोध के विलय के बाद, आप इसे स्थानीय रूप से हटा सकते हैं:

$ git branch -d mybranch

और GitHub पर

$ git push origin :mybranch

" जो मास्टर शाखा में केवल एक प्रतिबद्ध होना चाहिए ", जरूरी नहीं कि आवश्यक हो; आप इतिहास को बनाए रखना चाहते हैं
कोकवला

ज़रूर। लेकिन फिर बस स्क्वैश नहीं करते
मार्टिन थोमा

मुझे लगता है - प्यास-जनक सबसे अच्छा समाधान लगता है। davidchudzicki.com/posts/first-parent
bkribbs

7

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

मास्टर और शाखा प्राप्त करें:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

मास्टर के शीर्ष पर मर्ज शाखा:

git checkout <branch_name>
git rebase master

वैकल्पिक: यदि आप रिबेस के दौरान संघर्ष में भाग लेते हैं:

सबसे पहले, फ़ाइल में विरोध को हल करें। फिर:

git add .
git rebase --continue

अपनी विद्रोही शाखा को धक्का दें:

git push origin <branch_name>

अब आपको दो विकल्प मिले हैं:

  • A) एक PR बनाएँ (जैसे GitHub पर) और इसे UI के माध्यम से मर्ज करें
  • बी) कमांड लाइन पर वापस जाएं और शाखा को मास्टर में मर्ज करें
git checkout master
git merge --no-ff <branch_name>
git push origin master

किया हुआ।


6

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

git pull -r upstream master

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


3
git checkout master
git pull origin master
# Merge branch test into master
git merge test

विलय के बाद, यदि फ़ाइल बदली जाती है, तो जब आप विलय करते हैं, तो यह "रिज़ॉल्यूशन संघर्ष" की त्रुटि के माध्यम से होगा

तो फिर आपको पहले अपने सभी संघर्षों को हल करने की आवश्यकता है, फिर आपको अपने सभी परिवर्तनों को फिर से करना होगा और फिर धक्का देना होगा

git push origin master

यह बेहतर है कि जिसने परीक्षण शाखा में बदलाव किए हैं, क्योंकि वह जानता है कि उसने क्या बदलाव किए हैं।


3

मैं रीबेस विधि का उपयोग करूंगा। ज्यादातर क्योंकि यह पूरी तरह से आपके मामले को दर्शाता है, अर्थात। आप क्या करना चाहते हैं अपनी वर्तमान शाखा की स्थिति को ताज़ा करें और "दिखावा" करें जैसे कि यह नवीनतम पर आधारित था।

इसलिए, बिना जांच किए भी master, मैं:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

बेशक, केवल मूल से प्राप्त करने से आपकी स्थानीय स्थिति ताज़ा नहीं होती है master(क्योंकि यह मर्ज नहीं करता है), लेकिन यह हमारे उद्देश्य के लिए पूरी तरह से ठीक है - हम समय बचाने के लिए, चारों ओर स्विच करने से बचना चाहते हैं।


2

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

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master

0

आपके पास खींचने के लिए शाखा की जाँच होनी चाहिए, क्योंकि खींचने का मतलब मास्टर में विलय करना है, और आपको विलय करने के लिए एक कार्य वृक्ष की आवश्यकता है।

git checkout master
git pull

पहले चेक आउट करने की आवश्यकता नहीं है; rebase दो तर्कों के साथ सही काम करता है

git rebase master test  

git checkout master
git merge test

डिफ़ॉल्ट रूप से git पुश उन सभी शाखाओं को धक्का देता है जो यहां और रिमोट पर मौजूद हैं

git push
git checkout test

0

जैसा कि शीर्षक "सर्वश्रेष्ठ तरीका" कहता है, मुझे लगता है कि धैर्य मर्ज रणनीति पर विचार करना एक अच्छा विचार है ।

से: https://git-scm.com/docs/merge-strategies

इस विकल्प के साथ, 'मर्ज-पुनरावर्ती' गलतफहमी से बचने के लिए थोड़ा अतिरिक्त समय खर्च करता है जो कभी-कभी महत्वहीन मिलान लाइनों (जैसे, अलग-अलग कार्यों से ब्रेसिज़) के कारण होता है। इस का उपयोग तब करें जब मर्ज होने वाली शाखाओं को बेतहाशा मोड़ दिया गया हो। Git-diff [1] --patience भी देखें।

उपयोग:

git fetch
git merge -s recursive -X patience origin/master

गित अलियास

मैं हमेशा इसके लिए एक उपनाम का उपयोग करता हूं, उदाहरण के लिए एक बार चलाएं:

 git config --global alias.pmerge 'merge -s recursive -X patience'

अब आप कर सकते हैं:

git fetch
git pmerge origin/master

0

यह GitLab से है: बस निर्देशों का पालन करें:

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


0

मैं विकसित और सुविधा शाखाओं के अनुसार उत्तर दूंगा,

यदि आप सुविधा शाखा पर हैं और इसे कमांड के नीचे विकसित उपयोग के साथ अद्यतन करने की आवश्यकता है: git चेकआउट डेवलप git पुल git चेकआउट सुविधा / xyz git मर्ज डेवलप

अब आपकी विशेषता विकसित होने के साथ अपडेट हो गई है आप अपने बदलावों को आगे बढ़ा सकते हैं।

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