Git में एक उल्टा विलय फिर से कर रहा है


231

मैं यहां थोड़ी समस्या में चला गया हूं: मेरे पास 28sGit में एक समस्या-विशिष्ट शाखा थी, जिसे मैंने सामान्य developशाखा में विलय कर दिया था । यह पता चला है कि मैंने इसे बहुत तेजी से किया था, इसलिए मैंने मर्ज को पूर्ववत करने के लिए गिट-रिवर्ट का उपयोग किया। अब, हालांकि, विलय करने का समय आ 28sगया है develop, लेकिन गिट-मर्ज कमांड मूल मर्ज को देखता है, और खुशी से घोषणा करता है कि सब ठीक है और शाखाओं को पहले ही विलय कर दिया गया है। अब मैं क्या करू? एक "रिवर्ट" रिवर्ट "28s बनाएँ -> डेवलप" "कमिट? यह करने के लिए एक अच्छा तरीका नहीं लगता है, लेकिन मैं इस समय किसी भी अन्य की कल्पना नहीं कर सकता।

पेड़ की संरचना कैसी दिखती है:

लॉग लॉग आउटपुट


4
यह GitX ( gitx.frim.nl ) है।
टॉम्स मिकॉस

जवाबों:


169

आपको "रिवर्ट रिवर्ट" करना होगा। आप पर निर्भर करता है कि मूल वापस कैसे आया, यह जितना आसान लगता है उतना आसान नहीं हो सकता है। देखो इस विषय पर आधिकारिक दस्तावेज

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

अनुमति देने के लिए:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

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

तो तकनीकी कोण से, मर्ज को वापस लाने में कुछ भी गलत नहीं है, लेकिन वर्कफ़्लो के कोण से यह कुछ ऐसा है जिसे आपको आमतौर पर बचने की कोशिश करनी चाहिए

यदि संभव हो तो, उदाहरण के लिए, यदि आप एक समस्या पाते हैं जो मुख्य पेड़ में विलीन हो गई, तो मर्ज को वापस लाने के बजाय, वास्तव में कठिन प्रयास करें :

  • जिस समस्या को आप विलय कर रहे हैं, उस शाखा में नीचे जाएं और इसे ठीक करें,
  • या इसके कारण होने वाले व्यक्ति को वापस करने की कोशिश करें।

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


10
अच्छा लिंक (+1)। मैंने पाठकों को इस मामले में तुरंत प्रासंगिक विकल्पों को देखने की अनुमति देने के लिए आपके उत्तर में दस्तावेज़ का हिस्सा कॉपी करने की स्वतंत्रता ली। यदि आप असहमत हैं, तो वापस लौटने के लिए स्वतंत्र महसूस करें।
VonC

5
हम सिर्फ एक ऐसे मामले में भागे जहां हमें ऐसा करने की जरूरत थी और पाया कि यहां मजा बिल्कुल नहीं रुकता। यह एक लंबी चलने वाली शाखा थी जिसका विलय कर दिया गया था, इसलिए हमें इसे अपडेट करना जारी रखना चाहिए। मेरा दृष्टिकोण यहाँ है: tech.patientslikeme.com/2010/09/29/…
jdwyah

मैंने @ jdwyah के ब्लॉग पोस्ट का अनुसरण किया और यह शानदार था (गंभीरता से, यह बहुत बढ़िया था कि यह बस काम कर गया)।
नरकांत

2
@jdwyah जो एक टूटी हुई कड़ी लगती है, लेकिन यह एक दिलचस्प पढ़ने की तरह लगता है। यहाँ एक आर्काइव है। आईना। लेकिन यह चित्र गायब है: web.archive.org/web/20111229193713/http://…
एलेक्स कीस्मिथ

15
ब्लॉग पोस्ट को फिर से जीवित किया गया है, धन्यवाद: blog.jdwyah.com/2015/07/dealing-with-git-merge-revisions.html
jdwyah

53

चलिए मान लेते हैं आपका ऐसा इतिहास है

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

जहां A, B विफल हो जाता है और W - M से वापस आ जाता है

तो इससे पहले कि मैं समस्याओं को ठीक करना शुरू करूं, मैं अपनी शाखा के लिए डब्ल्यू-चेरी का चेरी-पिक करता हूं

git cherry-pick -x W

फिर मैंने अपनी शाखा पर डब्ल्यू कमिट किया

git revert W 

के बाद मैं फिक्सिंग जारी रख सकता हूं।

अंतिम इतिहास जैसा दिख सकता है:

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

जब मैं एक पीआर भेजता हूं तो यह स्पष्ट रूप से पता चलता है कि पीआर पूर्ववत है और कुछ नए कमिट जोड़ता है।


3
ऐसा लगता है कि यह उपयोगी हो सकता है, लेकिन विवरणों पर इतना विरल है (अंतिम आरेख में सी, डी क्या हैं) यह उपयोगी से अधिक निराशाजनक है
Isochronous

4
@ समकालिक सी और डी लगता है कि ए और बी द्वारा पेश की गई समस्याओं को ठीक करें
थॉमस

@Thomas बिल्कुल
Maksim Kotlyar

यह अच्छा है कि आपने इस उदाहरण में एक पीआर का उपयोग करके हाइलाइट किया है क्योंकि यह मास्टर में वापस विलय से पहले एक अंतिम 'पवित्रता जांच' प्रदान कर सकता है।
विलेम वैन केटविच

उपयोग क्यों आप मूल डब्ल्यू से अपनी शाखा को पुनः आरंभ करते हैं? यानी, W से अपना विषय जारी रखें, W के साथ C और D का अनुसरण करें? यह कुछ दोहराव को हटाता है
एरिक कार्स्टेंसन

12

अपने वर्कफ़्लो को बहुत अधिक खराब किए बिना रिवर्ट को वापस लाने के लिए:

  • विकास की एक स्थानीय कचरा प्रतिलिपि बनाएँ
  • विकसित की स्थानीय प्रति पर वापस लौटने के लिए प्रतिबद्ध है
  • उस प्रति को अपनी सुविधा शाखा में मर्ज करें, और अपनी सुविधा शाखा को अपने git सर्वर पर धकेलें।

जब आप इसके लिए तैयार होते हैं तो आपकी सुविधा शाखा को सामान्य रूप से विलय करने में सक्षम होना चाहिए। यहाँ केवल नकारात्मक पक्ष यह है कि आपके पास अपने इतिहास में कुछ अतिरिक्त मर्ज / रिवर्ट कमिट होंगे।


बस किसी भी आगे के मिश्रण अप को रोकने के लिए मैंने अपनी सुविधा शाखा की एक 'कचरा' प्रति भी बनाई और उसमें फिर से विकसित विकास को मिला दिया।
jhhwilliams

धन्यवाद! यह एकमात्र उत्तर है जो वास्तव में बताता है कि यह कैसे करना है बजाय यह कहने के कि आपको ऐसा नहीं करना चाहिए। वास्तव में सहायक।
एमी

धन्यवाद, इसने वास्तव में मेरी मदद की। :)
डैनियल स्ट्रैकोबोस्को

11

GIT में वापस लौटने के लिए:

git revert <commit-hash-of-previous-revert>

1
मेरे कार्य शाखा में इस का उपयोग करके रिवर्ट को वापस करना है, फिर नए पीआर को विकसित करना है। अब जीआईटी उन सभी परिवर्तनों को देखता है जो पिछले पीआर में थे जो वापस कर दिए गए थे। धन्यवाद।
डैनस्टन

3

इसके बजाय का उपयोग करने का git-revertआप में इस आदेश का इस्तेमाल किया जा सकता था develके लिए शाखा फेंक (पूर्ववत) गलत मर्ज (बस इसे पूर्ववत करने के बजाय) के लिए प्रतिबद्ध।

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

यह भी तदनुसार काम कर निर्देशिका की सामग्री को समायोजित करेगा। सावधान रहें :

  • विकसित शाखा में (गलत मर्ज के बाद से) अपने परिवर्तनों को सहेजें क्योंकि वे भी मिट जाएंगे git-reset। आपके द्वारा निर्दिष्ट git resetकिए गए तर्क के बाद सभी कमिट हो जाएंगे!
  • यदि आपके परिवर्तन पहले से ही अन्य रिपॉजिटरी से खींच लिए गए हैं, तो भी ऐसा न करें क्योंकि रीसेट इतिहास को फिर से लिखेगा।

मैं git-resetयह कोशिश करने से पहले मैन-पेज का सावधानीपूर्वक अध्ययन करने की सलाह देता हूं ।

अब, रीसेट के बाद आप अपने परिवर्तनों को फिर से लागू कर सकते हैं develऔर फिर कर सकते हैं

git checkout devel
git merge 28s

इस से कोई वास्तविक मर्ज हो जाएगा 28sमें develप्रारंभिक एक (जो अब Git के इतिहास से मिटा दिया जाता है) की तरह।


8
जो कोई सुपर गिट के साथ परिचित नहीं है और इन निर्देशों का पालन करना चाहता है: संयोजन के साथ सावधान reset --hardऔर push origin। यह भी ध्यान रखें कि मूल रूप से एक बल धक्का मूल रूप से गीथहब पर खुले पीआरएस को दबा सकता है।
फुल जूल

एक निजी गिट सर्वर पर कुछ मर्ज मुद्दों को ठीक करने के लिए बहुत उपयोगी है। धन्यवाद!
मिश्रण 3 डी

1
इस तकनीक के लिए +1। विवेकपूर्ण रूप से विनाशकारी, लेकिन विवेकपूर्ण तरीके से लागू होने पर आपको बहुत सारे सिरदर्द (और एक पेचीदा इतिहास) से बचा सकता है।
सिलिकॉनट्रस्ट

1

उसी समस्या का सामना करते हुए मुझे यह पोस्ट मिला। मुझे लगता है कि मैं कुछ नहीं करना चाहता, और मैं इसे वापस नहीं पा सकूंगा।

इसके बजाय मैंने कमिट की जाँच की कि मैं चाहता था कि शाखा वापस उदा में जाए git checkout 123466t7632723। फिर एक शाखा में परिवर्तित कर दिया git checkout my-new-branch। फिर मैंने वह शाखा हटा दी जिसे मैं और नहीं चाहता था। निश्चित रूप से यह केवल तभी काम करेगा जब आप उस शाखा को फेंकने में सक्षम होंगे जिसे आपने गड़बड़ किया था।


1
git reflogआप बाद में है कि तुम खो प्रतिबद्ध जरूरत की खोज के मामले में दो महीने के लिए हार्ड रीसेट पर आप की रक्षा करेगा। आपके स्थानीय रेपो तक सीमित है।
टॉड

1

मैं आपको SHA1 कहने के लिए एक रिवर्ट पलटने के लिए नीचे दिए गए चरणों का पालन करने का सुझाव दूंगा।

git checkout develop #go to develop branch
git pull             #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote

अब शाखा के लिए पीआर बनाएं users/yourname/revertOfSHA1


1
  1. मूल मर्ज से पहले नई शाखा बनाएं - इसे 'डेवलप-बेस' कहें
  2. 'डेवलप-बेस' (भले ही यह पहले से ही शीर्ष पर है) के शीर्ष पर 'डेवलप' का इंटरएक्टिव रीबेस हो। इंटरएक्टिव रिबेस के दौरान, आपके पास मर्ज कमेटी को हटाने का अवसर होगा, और मर्ज को उलट देने वाले कमिट यानी दोनों घटनाओं को गिट हिस्ट्री से हटा देंगे

इस बिंदु पर आपके पास एक साफ 'विकसित' शाखा होगी, जिसमें आप नियमित रूप से अपनी फीचर ब्रैक को मर्ज कर सकते हैं।


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