मैं एक मजबूर धक्का की आवश्यकता के बिना गिट रीबेस का उपयोग कैसे कर सकता हूं?


92

नीट निर्वाण प्राप्त करने के प्रयास में, मैं उन दिनों को सीखने में बिता रहा हूं, जहां मैं वर्तमान में विलय की स्थितियों के लिए छूट का लाभ उठा सकता हूं।

जब मैं जिस चीज के बारे में सोचता हूं, वह 101 प्रवाह (जिसे मैं नीचे वर्तनी करता हूं) के माध्यम से चलाता हूं, तो मुझे push --forceअपने परिवर्तनों को मूल में वापस लाना होगा।

मैं केवल एक ही नहीं हूं - मुझे पता है कि यह कवर जमीन है (देखें 1 , 2 , 3 , 4 , 5 ), और मैं तकनीकी कारणों को समझता हूं कि क्यों एक बल आवश्यक है। मेरा मुद्दा यह है --- वहाँ कई (कई) ब्लॉग प्रविष्टियाँ हैं जो रिबास की प्रशंसा गा रही हैं और यह कैसे उनके जीवन को बदल दिया है (देखें 1 , 2 , 3 , 4 कुछ सूचीबद्ध करने के लिए), लेकिन उनमें से कोई भी उल्लेख नहीं है जो push --forceइसका हिस्सा है उनका प्रवाह। हालांकि, मौजूदा स्टैकओवरफ्लो सवालों के लगभग हर उत्तर में "हाँ, अगर आप रिबास करने जा रहे हैं, तो आप उपयोग करेंगे push --force" जैसी बातें कहते हैं ।

रिबेस अधिवक्ताओं की संख्या और धार्मिकता को देखते हुए, मेरा मानना ​​है कि 'पुश -फोर्स' का उपयोग करना रिबास प्रवाह का एक अंतर्निहित हिस्सा नहीं है, और अगर किसी को अक्सर अपने पुश को मजबूर करना पड़ता है, तो वे कुछ गलत कर रहे हैं

push --forceएक है बुरी बात

तो यहाँ मेरा प्रवाह है। किस तरह से मैं एक बल के बिना एक ही परिणाम प्राप्त कर सकता था?

सरल उदाहरण

दो शाखाएँ:

  • v1.0 - एक रिलीज शाखा, जिसमें केवल पैच होते हैं
  • मास्टर - अगले प्रमुख रिलीज के लिए सब कुछ।

मुझे कुछ पैच कमिट्स मिल गए हैं और अगले रिलीज़ के लिए कुछ कमिट्स।

premerge

मैं पैच को अपने स्वामी में शामिल करना चाहता हूं ताकि वे अगली रिलीज़ के लिए खो न जाएं। पूर्व-प्रबोधन मैं बस:

git checkout master
git merge v1.0

लेकिन अब मैं कोशिश कर रहा हूं

git checkout master
git rebase v1.0

तो अब मैं यहाँ हूँ:

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

के लिए समय:

git push

कोई पाँसा नहीं।

जवाबों:


43

रिबासिंग एक महान उपकरण है, लेकिन यह सबसे अच्छा काम करता है जब आप इसका उपयोग मास्टर शाखाओं में विषय शाखाओं के लिए तेजी से अग्रेषित मर्ज बनाने के लिए करते हैं। उदाहरण के लिए, आप अपने ऐड-न्यू-विजेट ब्रांच को मास्टर के खिलाफ रिजेक्ट कर सकते हैं:

git checkout add-new-widget
git rebase -i master

मास्टर में शाखा के तेजी से आगे विलय करने से पहले। उदाहरण के लिए:

git checkout master
git merge --ff-only add-new-widget

इसका लाभ यह है कि आपके इतिहास में बहुत सारे जटिल मर्ज कमिट या मर्ज का विरोध नहीं होगा, क्योंकि आपके सभी बदलावों को मर्ज से पहले मास्टर की नोक पर रिबेट किया जाएगा। एक माध्यमिक लाभ यह है कि आपने छूट दी है, लेकिन आपको इसका उपयोग करने की आवश्यकता नहीं है git push --forceक्योंकि आप मास्टर शाखा पर इतिहास को क्लोब नहीं कर रहे हैं।

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


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

1
मैं इसे समझता हूं, लेकिन मूल सवाल यही है। मुझे लगता है कि वास्तविक उत्तर @Fabien Quatravaux
IsmailS

4
खैर, आपको अभी भी 1.0 शाखा को बल-धक्का देना होगा, नहीं? कम से कम, यह है कि कैसे चीजें मेरे लिए हर समय बाहर बारी है। Fabiens विधि ऐसा होने से रोकेगी।
joerx

23

@CodeGnome सही है। आपको v1.0 शाखा पर मास्टर को रिबास नहीं करना चाहिए, लेकिन मास्टर पर v1.0 शाखा है, जिससे सभी अंतर होंगे।

git checkout -b integrate_patches v1.0
git rebase master
git checkout master
git merge integrate_patches

V1.0 को इंगित करने वाली एक नई शाखा बनाएं, उस नई शाखा को मास्टर के ऊपर ले जाएं और फिर V1.0 पैच के नए संस्करण को मास्टर शाखा में एकीकृत करें। आप कुछ इस तरह से समाप्त करेंगे:

o [master] [integrate_patches] Another patch on v1.0
o A patch on v1.0
o Another change for the next major release
o Working on the next major release
|  o [v1.0] Another path on v1.0
|  o A patch on v1.0
| /
o Time for the release

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

मुझे लगता है कि आप इसके बारे में सही हैं git push --force: आपको केवल इसका उपयोग करना चाहिए यदि आपने कोई गलती की है और कुछ ऐसा धक्का दिया है जो आप नहीं चाहते थे।


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

धन्यवाद Fabien, महान जवाब। हममें से जो केवल बदलावों को एकीकृत करना चाहते हैं masterऔर फीचर शाखा को खुद में विलय करने की इच्छा नहीं रखते हैं, उनके लिए यह किया जा सकता है:git checkout my-branch; git rebase master; git checkout master; git merge my-branch
सियावास

17

आपको बलपूर्वक धक्का देना पड़ता है यदि आप पुनरावृत्ति करते हैं, और आपने पहले ही अपने परिवर्तन प्रकाशित किए हैं, है ना?

मैं एक पूरे झुंड का उपयोग करता हूं, लेकिन मैं या तो कुछ निजी में प्रकाशित करता हूं, जहां एक बल धक्का कोई फर्क नहीं पड़ता (उदाहरण के लिए: GitHub पर अपना स्वयं का क्लोन, एक पुल अनुरोध के भाग के रूप में), या मैं पहली बार धक्का देने से पहले फिर से मिटा देता हूं।

यह वर्कफ़्लो का दिल है जहाँ आप रिबास का उपयोग करते हैं, लेकिन बहुत जोर न डालें: चीजों को तब तक प्रकाशित न करें जब तक वे तैयार न हों, आप को पुश करने से मना न करें।


धन्यवाद डैन। क्या आप मुझे बता सकते हैं कि ऊपर कैसे प्राप्त किया जाना चाहिए? क्या यह सिर्फ एक परिदृश्य नहीं है जहां रिबास लागू होता है?
रॉय Truelove

2
यदि आप अपने सभी कार्यों को विषय शाखाओं में अलग करते हैं, तो यह रिबासिंग के लिए एक अच्छा परिदृश्य स्थापित करता है। आपने rebaseअपनी विषय शाखा में नए परिवर्तन किए, लेकिन जब आपने उस शाखा के परिवर्तन को पूरा कर लिया, तो आप mergeमुख्य विकास शाखा में वापस शाखा में आ गए।
redhotvengeance

1
समस्या यह है कि आपने शाखा प्रकाशित की है - इसलिए आपको भंडार को धक्का देने के लिए मजबूर करना होगा। आपको दो में से एक को छोड़ने की ज़रूरत है: आप जिस तरह से करते हैं, या पुन: प्रकाशित कर रहे हैं। माफ़ करना।
डैनियल पिटमैन

रिबासिंग जैसी आवाज़ इस परिदृश्य के लिए काम नहीं करती है। v1.0 एक विषय शाखा नहीं है, यह एक रिलीज़ शाखा है, इसलिए यह कभी नहीं मर जाएगा और इसे प्रकाशित करना होगा।
रॉय Truelove

5

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


2
मेरे पास यह एक ही वर्कफ़्लो है (कई कंप्यूटर / स्थानों से काम करना)। तो, मान लेते हैं कि आप 'mytopic' नामक विषय शाखा पर काम कर रहे हैं। जब तक आप हमेशा "मास्टर" पर एक स्थानीय फेंकने वाली शाखा (जो कि केवल mytopic की एक शाखा है) को वापस कर देते हैं और फिर उस वापस mytopic में विलय कर देते हैं, तब आपको कभी भी धक्का देने के लिए मजबूर नहीं करना पड़ता है। ओपी का परिदृश्य थोड़ा अलग है, इसलिए इस तरह के मामले में एक बल धक्का आवश्यक हो सकता है। हालांकि, मुझे लगता है कि ओपी गलत तरीके से पुनरावृत्ति कर रहा है - अगर उसने ऐसा किया जैसा कि मैंने वर्णित किया है तो कोई बल धक्का आवश्यक नहीं होगा।
bwv549

3

यहाँ मैं क्या उपयोग कर रहा हूँ (आपकी शाखा का नाम फोब्बर है )

git checkout master              # switch to master
git rebase   foobar              # rebase with branch
git merge -s ours origin/master  # do a basic merge -- but this should be empty
git push origin master           # aaand this should work

2
रिबासिंग मास्टर अजीब लग रहा है।
एमिल विक्रोत्स्म

2
gitबिना व्यक्तित्व नहीं है
सुगन्धित

1
git merge -s ours origin/<branch>क्या यह हमारे लिए तय किया गया था
अधिकतम

0

tl; साझा शाखाओं के साथ डॉ। मर्ज, अलग-अलग शाखाओं के साथ फिर से जुड़ना। --force-with-leaseबल के लिए एक सुरक्षित विकल्प है और आपको बल की विनाशकारी प्रकृति के बिना कहा गया निर्वाण प्राप्त करने में मदद करनी चाहिए।

अंगूठे का एक सामान्य नियम जो मैंने विभिन्न टीमों के वर्कफ़्लोज़ के लिए काम देखा है merge, साझा शाखाओं (यानी, मास्टर या डेवलपमेंट) के लिए उपयोग करना है और rebaseअपनी स्वयं की सुविधा शाखा पर काम करते समय उपयोग करना है। यहाँ एक सुविधा शाखा का एक विशिष्ट जीवन चक्र है

git checkout master
git checkout -b new-feature
git commit -am "commit new work"
git push -u origin new-feature
# have code reviewed, run CI, etc.,
# meanwhile master has new commits
git checkout master
git pull
git rebase -i master # -i for interactive rebase allows you to squash intermediate commits
git push --force-with-lease
git merge master

हमने यहां जो किया है उसका एक सादा अंग्रेजी संस्करण:

  1. मास्टर से दूर एक नई शाखा बनाई
  2. शाखा पर काम किया और दूरदराज के लिए धकेल दिया
  3. गुरु से छूट गई
  4. रिमोट के साथ पुश काम करें force-with-lease
  5. एक बहुत साफ गिट लॉग के साथ मास्टर में विलय करें, हमारी शाखा को नवीनतम मास्टर (साझा शाखा) के साथ "पकड़े" जाने के लिए हमारी साझा शाखा से कई विलय से अव्यवस्था को कम करना।

चौथा चरण वास्तव में महत्वपूर्ण है और मुख्य कारणों में से एक है जो मैंने रिबास के उपयोग की वकालत करना शुरू किया। force-with-leaseयह देखने के लिए रिमोट की जाँच करता है कि क्या कोई नया कमिट जोड़ा गया है। यदि आपका git pushविनाशकारी साबित हुआ तो यह धक्का नहीं देगा!

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

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