सुविधा शाखा छूट के बाद Git पुश अस्वीकार कर दिया गया


916

ठीक है, मुझे लगा कि यह एक सरल परिदृष्य था, मैं क्या याद कर रहा हूँ?

मेरी एक masterशाखा और एक featureशाखा है। मैं कुछ पर काम करता हूं master, कुछ पर featureऔर फिर कुछ पर master। मैं कुछ इस तरह से समाप्त करता हूं (लेक्सिकोग्राफिक ऑर्डर का अर्थ है कमिट्स का क्रम):

A--B--C------F--G  (master)
       \    
        D--E  (feature)

मुझे अपने काम के लिए रिमोट बैकअप बनाए रखने के लिए न git push origin masterतो रिमोट को masterअपडेट रखने की कोई समस्या है , न ही git push origin feature(जब ( feature)) feature। अब तक, हम अच्छे हैं।

लेकिन अब मैं मास्टर पर कमिट्स के featureशीर्ष पर फिर से बनना चाहता हूं F--G, इसलिए मैं git checkout featureऔर git rebase master। फिर भी अच्छा। अब हमारे पास है:

A--B--C------F--G  (master)
                 \
                  D'--E'  (feature)

समस्या: पल बैकअप के लिए मैं चाहता हूँ नया रिबेस featureसाथ branched git push origin feature, धक्का अस्वीकार कर दिया है के बाद से पेड़ रिबेसिंग की वजह से बदल गया है। यह केवल के साथ हल किया जा सकता है git push --force origin feature

मुझे --forceयकीन है कि मुझे इसकी आवश्यकता के बिना उपयोग करने से नफरत है। तो, क्या मुझे इसकी आवश्यकता है? रिबेसिंग है जरूरी मतलब है कि अगले pushहोना चाहिए --forceful?

यह सुविधा शाखा, किसी भी अन्य devs साथ साझा नहीं है तो मैं कोई समस्या नहीं है वास्तविक बल धक्का के साथ, मैं किसी भी डेटा खोने के लिए नहीं जा रहा हूँ, प्रश्न अधिक वैचारिक है।

जवाबों:


681

समस्या यह है कि git pushयह माना जाता है कि दूरस्थ शाखा को आपकी स्थानीय शाखा में तेजी से अग्रेषित किया जा सकता है, यही है कि स्थानीय और दूरस्थ शाखाओं के बीच का अंतर स्थानीय में कुछ नया होता है जैसे कि अंत में:

Z--X--R         <- origin/some-branch (can be fast-forwarded to Y commit)
       \        
        T--Y    <- some-branch

जब आप git rebaseकमिट करते हैं तो डी और ई को नए बेस पर लागू किया जाता है और नए कमिट बनाए जाते हैं। इसका मतलब यह है कि आप के बाद ऐसा कुछ है:

A--B--C------F--G--D'--E'   <- feature-branch
       \  
        D--E                <- origin/feature-branch

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

और जो --forceविकल्प है, वह केवल दूरस्थ शाखा की स्थिति की अनदेखी कर रहा है और इसे उस प्रतिबद्ध करने के लिए सेट कर रहा है जिसमें आप इसे आगे बढ़ा रहे हैं। तो git push --force origin feature-branchबस origin/feature-branchस्थानीय के साथ ओवरराइड करता है feature-branch

मेरी राय में, सुविधा शाखाओं को फिर से चालू करना masterऔर उन्हें दूरस्थ रिपॉजिटरी में वापस धकेलना तब तक ठीक है जब तक आप उस शाखा पर काम करने वाले एकमात्र व्यक्ति हैं।


67
ईमानदार होने के लिए, सुविधा शाखा के मूल संस्करण को एक तरह से विद्रोह में खींचने और विलय करने से पुनरावृत्ति का पूरा विचार समाप्त हो जाता है।
केएल -7

24
हो सकता है कि मैं आपको सही तरीके से समझ नहीं पाया, लेकिन अगर आप फीचर शाखा को खींचते हैं, तो इसे नई मास्टर ब्रांच पर रिबास करें, आप इसे बल के बिना पीछे नहीं धकेल सकते, क्योंकि फीचर ब्रांच का रिमोट वर्जन आपके नए में तेजी से अग्रसर नहीं हो सकता है (छूट) सुविधा शाखा का संस्करण। ठीक यही ओपी ने अपने प्रश्न में वर्णित किया है। यदि रिबासिंग के बाद, लेकिन धक्का देने से पहले, आप करते हैं git pull feature-branch, तो यह पुल एक नई मर्ज कमिटेशन उत्पन्न करेगा (फीचर शाखा के दूरस्थ और स्थानीय संस्करणों को मर्ज करके)। इसलिए या तो आप रिबासिंग के बाद एक अनावश्यक मर्ज प्राप्त करें, या आप के साथ धक्का --force
केएल -7

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

11
Trouble फोर्स-पुश "के साथ परेशानी यह है कि, आप वास्तव में (ढीला सामान" (पूर्व में काम कर सकते हैं), ऐसा कुछ जो सामान्य रूप से किसी भी संस्करण नियंत्रण प्रणाली में संभव नहीं होना चाहिए reason उस कारण से कम से कम एक-मास्टर-ईश ’शाखा होनी चाहिए संभावित नुकसान को सीमित करने के लिए बल-पुश को स्वीकार नहीं करने के लिए सेटिंग्स । (निम्नलिखित में से किसी एक का नाम: क्रोधी / निकाल दिए गए कर्मचारी, खुद मूर्ख, थके हुए और 'निर्णय' ... पर काम करते हैं।)।
फ्रैंक नोके

13
--force-with-leaseजैसा कि @hardev ने सुझाव दिया है कि एक बेहतरीन विकल्प है
'14

464

का उपयोग करने के बजाय -f या --फोर्स डेवलपर्स को उपयोग करना चाहिए

--force-with-lease

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


33
महान व्याख्या। git push --force-with-leaseमुझे एक गुच्छा बचाया है।
ckib16

5
यह एक उपयोगी टिप्पणी है, लेकिन वास्तव में इस सवाल का जवाब नहीं है।
डैलिन

4
यह उत्तर है, मास्टर / विकसित करने के लिए रिबासिंग एक मुद्दा बनाता है, यही कारण है कि --फोर्स-विद-लीज मौजूद है।
तामीर दानीली

3
यह स्वीकृत उत्तर होना चाहिए। ठीक वर्णित समस्या हल करता है - यदि कोई और इस बीच में प्रतिबद्ध हो तो मजबूर किए बिना जोर लगाना।
लूजियान

3
मुझे लगता है कि दोनों स्वीकार किए जाते हैं और यह एक सवाल का जवाब है। स्वीकृत उत्तर बताता है कि आपको मजबूर करने की आवश्यकता क्यों है। और यह बताता है कि क्यों --force-with-leaseइस्तेमाल करने की चिंता को संबोधित करता है--force
जेफ अप्पर्टी

47

मैं "चेकआउट-बी" के बजाय उपयोग करूंगा और इसे समझना आसान है।

git checkout myFeature
git rebase master
git push origin --delete myFeature
git push origin myFeature

जब आप हटाते हैं, तो आप एक अलग शाखा में धक्का देने से रोकते हैं जिसमें अलग-अलग SHA ID होती है। मैं इस मामले में केवल दूरस्थ शाखा को हटा रहा हूं।


6
यह बहुत अच्छा काम करता है, खासकर अगर आपकी टीम के पास एक हुक है जो सभी गिट पुश --फोर्स कमांड को खारिज कर देता है।
रयान टेम्स

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

5
यह उसी तरह का परिणाम है push --force, इसलिए एक गिट रेपो को रोकने के लिए केवल एक तरीका है --force। जैसे, मुझे नहीं लगता कि यह कभी एक अच्छा विचार है - या तो रेपो अनुमति देता है push --force, या किसी अच्छे कारण से इसे निष्क्रिय कर देता है। --forceरिमोट रेपो पर अक्षम होने पर नबी का जवाब अधिक उपयुक्त है, क्योंकि इसमें अन्य डेवलपर्स से कमिट खोने का जोखिम नहीं है या अन्यथा समस्याएं हैं।
लोगन पिकअप

19

इसका एक समाधान यह करना है कि msysGit की रिबासिंग मर्ज स्क्रिप्ट क्या करती है - रिबेज़ के बाद, पुराने हेड के featureसाथ मर्ज करें -s ours। आप प्रतिबद्ध ग्राफ़ के साथ समाप्त होते हैं:

A--B--C------F--G (master)
       \         \
        \         D'--E' (feature)
         \           /
          \       --
           \    /
            D--E (old-feature)

... और आपका धक्का featureजल्दी-जल्दी होगा।

दूसरे शब्दों में, आप कर सकते हैं:

git checkout feature
git branch old-feature
git rebase master
git merge -s ours old-feature
git push origin feature

(परीक्षण नहीं किया गया है, लेकिन मुझे लगता है कि यह सही है ...)


26
मेरा मानना ​​है कि उपयोग करने के लिए सबसे आम कारण git rebase( masterआपकी सुविधा शाखा में वापस विलय के बजाय ) स्वच्छ रैखिक इतिहास बना रहा है। आपके दृष्टिकोण के साथ इतिहास भी बदतर हो जाता है। और जैसा कि रिबासिंग उनके पिछले संस्करणों के संदर्भ के बिना नए कमिट बनाता है मुझे यकीन भी नहीं है कि इस मर्ज का परिणाम पर्याप्त होगा।
केएल -7

6
@ केएल -7: इसका संपूर्ण बिंदु merge -s oursयह है कि यह कृत्रिम रूप से पिछले संस्करण में एक मूल संदर्भ जोड़ता है। निश्चित रूप से, इतिहास साफ नहीं दिखता है, लेकिन featureशाखा के धक्का को मजबूर करने से प्रश्नकर्ता विशेष रूप से परेशान होने लगता है , और यह उसके चारों ओर है। यदि आप रिबेस करना चाहते हैं, तो यह कमोबेश एक या दूसरे का है। :) अधिक आम तौर पर, मुझे लगता है कि यह दिलचस्प है कि msysgit परियोजना ऐसा करती है ....
मार्क Longair

@ केएल -7: संयोग से, मैंने आपका जवाब 1ed दिया, जो स्पष्ट रूप से सही है - मुझे लगा कि यह दिलचस्प हो सकता है।
मार्क लॉन्गेयर

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

15

यह हो सकता है या नहीं भी हो सकता है कि इस शाखा पर केवल एक ही डेवलपर है, जो अब (रिबेस के बाद) मूल / सुविधा के साथ इनलाइन नहीं है।

जैसा कि मैं निम्नलिखित अनुक्रम का उपयोग करने का सुझाव दूंगा:

git rebase master
git checkout -b feature_branch_2
git push origin feature_branch_2

हाँ, नई शाखा, इसे बिना किसी प्रवर्तन के इसे हल करना चाहिए, जो मुझे लगता है कि आम तौर पर एक बड़ी समस्या है।


3
ऐसा कहने के लिए क्षमा करें: „" मौजूदा फोर्स-ओवरराइडिंग से बचने के लिए "ब्रांच जेनरेट करना जारी रखें, इससे on अकेला फीचर डेवलपर्स’ (जो ओवरराइड कर सकते हैं) और न ही एक फीचर ब्रांच में काम करने वाले कई लोग मदद कर सकते हैं (उस ब्रांच को "इंक्रीमेंट" और बताने की जरूरत है) ऊपर जाने के लिए, दोस्तों)। - यह एक संस्करण प्रणाली के भीतर मैन्युअल संस्करण ("थीसिस_00.doc, थीसिस_01.doc, ...") की तरह अधिक है ...
फ्रैंक Nocke

2
इसके अलावा, जब आपके पास एक शाखा के नाम पर जीथब पीआर खोला जाता है, तो यह मदद नहीं करता है, आपको उस नए शाखा नाम के लिए एक नया पीआर बनाना होगा जिसे आपने धक्का दिया था।
gprasant

1
@frankee मेरे अनुभव से आधा सच है। एक अकेले डेवलपर के लिए, हाँ, बस जोर जबरदस्ती करना आसान है, लेकिन यह आदत है जो आपको बाद में काट सकती है। + एक नया देव बस शामिल हो गया? या हो सकता है कि कुछ CI सिस्टम --हार्ड रीसेट का उपयोग नहीं कर रहा है? सहयोग करने वाली एक टीम के लिए, मुझे लगता है कि नई शाखा के नाम से संवाद करना काफी आसान है, यह आसानी से एक टीम के लिए + के रूप में अच्छी तरह से स्क्रिप्ट किया जा सकता है, मैं स्थानीय स्तर पर या जब शाखा विलय के लिए तैयार है, तो दिन के काम के दौरान नहीं। परिणाम के रूप में रिबेट / मर्ज टकराव से निपटने के लिए अतिरिक्त कम परेशानी से कम नहीं है।
JAR.JAR.beans 10

पीआर के लिए @gprasant, फिर से, मुझे लगता है कि यह रिबेस करना गलत होगा, मैं वास्तव में पीआर फिक्स के साथ एक ही कॉमेट्स देखना चाहता हूं। एक रिबेस (स्क्वैश) केवल बाद में मास्टर में विलय के हिस्से के रूप में होना चाहिए और जब पीआर सब किया जाता है और तैयार होता है (इसलिए नए पीआर को खोलने की आवश्यकता नहीं है)।
JAR.JAR.beans 10

13

बल धक्का से बचने का मेरा तरीका एक नई शाखा बनाना और उस नई शाखा पर निरंतर काम करना है और कुछ स्थिरता के बाद, पुरानी शाखा को हटा दें जो कि छूट दी गई थी:

  • स्थानीय स्तर पर चेक आउट शाखा को रिबास करना
  • विद्रोही शाखा से एक नई शाखा में शाखाएँ
  • उस शाखा को रिमोट की एक नई शाखा के रूप में धक्का देना। और रिमोट पर पुरानी शाखा को हटाना

1
इस विकल्प के लिए प्यार क्यों नहीं? यह निश्चित रूप से सबसे साफ, सबसे सरल, सबसे सुरक्षित है।
cdmo

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

@TamirDaniely मैंने कोशिश नहीं की है, लेकिन नई शाखा को हटाने और धक्का देने से पहले पुरानी शाखा को हटाने से क्या पुराने नाम के साथ आपकी समस्या हल हो जाएगी?
नबी

2
@ नाबी यह वही है - प्रवर्तन-के साथ-पट्टा करता है, इसके अलावा यह भी पुष्टि करता है कि कोई नया कमिट नहीं है जो आपके नहीं हैं।
तामिर डेनियली

12

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

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

सामान्य तौर पर, स्थानीय शाखा प्रबंधन के लिए रिबास अच्छा काम करता है। सुदूर शाखा प्रबंधन स्पष्ट मर्ज (--no-ff) के साथ सबसे अच्छा काम करता है।

हम मास्टर को एक सुविधा शाखा में विलय करने से भी बचते हैं। इसके बजाय हम मास्टर करने के लिए रिबेट करते हैं लेकिन एक नई शाखा के नाम के साथ (जैसे एक संस्करण प्रत्यय जोड़ना)। यह साझा भंडार में रिबासिंग की समस्या से बचा जाता है।


5
क्या आप एक उदाहरण जोड़ सकते हैं?
थर्मेक

8

शाखा git merge masterपर क्या गलत है feature? यह आपके द्वारा किए गए कार्य को संरक्षित रखेगा, जबकि इसे मेनलाइन शाखा से अलग रखेगा।

A--B--C------F--G
       \         \
        D--E------H

संपादित करें: आह क्षमा करें, आपकी समस्या बयान नहीं पढ़ी। जैसे ही आपने प्रदर्शन किया, आपको बल की आवश्यकता होगी rebase। इतिहास को संशोधित करने वाले सभी आदेशों को --forceतर्क की आवश्यकता होगी । यह आपको काम करने से रोकने के लिए एक असफल है (पुराना Dऔर Eखो जाएगा)।

इसलिए आपने एक ऐसा प्रदर्शन किया, git rebaseजिससे पेड़ जैसा दिखता है (हालांकि आंशिक रूप से छिपा हुआ है Dऔर Eअब नामित शाखा में नहीं है)

A--B--C------F--G
       \         \
        D--E      D'--E'

इसलिए, जब आप अपनी नई featureशाखा (इसके साथ D'और E'उसमें) को धक्का देने की कोशिश कर रहे हैं, तो आप हार जाएंगे Dऔर E


3
इसमें कुछ भी गलत नहीं है, और मुझे पता है कि यह काम करेगा। यह सिर्फ वही नहीं है जो मुझे चाहिए। जैसा कि मैंने कहा, प्रश्न व्यावहारिक से अधिक वैचारिक है।
युवल एडम

4

मेरे लिए आसान चरणों के बाद काम करता है:

1. git checkout myFeature
2. git rebase master
3. git push --force-with-lease
4. git branch -f master HEAD
5. git checkout master
6. git pull

उपरोक्त सभी करने के बाद, हम निम्नलिखित कमांड द्वारा myFeature शाखा को हटा सकते हैं:

git push origin --delete myFeature

3

निम्नलिखित मेरे लिए काम करता है:

git push -f origin branch_name

और यह मेरे किसी भी कोड को नहीं हटाता है।

लेकिन, अगर आप इससे बचना चाहते हैं तो आप निम्नलिखित कार्य कर सकते हैं:

git checkout master
git pull --rebase
git checkout -b new_branch_name

फिर आप अपनी सभी कमियों को नई शाखा में चुन सकते हैं। git cherry-pick COMMIT ID और फिर अपनी नई शाखा को आगे बढ़ाएं।


5
-fके लिए एक उपनाम है --force, जो कि यदि संभव हो तो सवाल से बचने की कोशिश कर रहा है।
युगांतर

1

जैसा कि ओपी समस्या को समझता है, बस एक अच्छे समाधान की तलाश में है ...

अभ्यास के रूप में इसके बारे में कैसे?

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

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

इस पद्धति के लिए पहले से ही एक पैटर्न नाम हो सकता है।

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