मैं "अन-रिवर्ट" कैसे एक उलटा गिट प्रतिबद्ध कर सकता हूं?


484

ऐसे परिवर्तन को देखते हुए, जिसका उपयोग करते हुए प्रतिबद्ध किया गया है commit, और फिर वापस उपयोग करते हुए revert, फिर से पूर्ववत करने का सबसे अच्छा तरीका क्या है?

आदर्श रूप से, यह एक नई प्रतिबद्धता के साथ किया जाना चाहिए, ताकि इतिहास को फिर से न लिखा जाए।



@ Fuclv संभव डुप्लिकेट के लिए एक टिप्पणी वहाँ, अंक यहाँ। एक को मूल रूप से चिह्नित किया जाना चाहिए और एक को डुप्लीकेट चिह्नित किया जाना चाहिए
जॉन डेमेट्रियौ

@JohnDemetriou कोई ऐसा प्रश्न नहीं है जिसके उत्तर का बेहतर सेट खुला रखा जाए। समय यहाँ प्रासंगिक नहीं है डुप्लिकेट प्रश्नों को कैसे संभाला जाना चाहिए?
फुलकव

मैंने समय के बारे में नहीं कहा। मैं सिर्फ इस मुद्दे के बारे में दो में से एक पर टिप्पणी करने के लिए हुआ
जॉन डेमेट्रियौ

जवाबों:


384

यदि आपने उस परिवर्तन को अभी तक आगे नहीं बढ़ाया है, git reset --hard HEAD^

अन्यथा, रिवर्ट को वापस करना पूरी तरह से ठीक है।

एक और तरीका है git checkout HEAD^^ -- .और फिर git add -A && git commit


8
ध्यान दें कि यदि आप मास्टर शाखा में मूल परिवर्तनों को तुरंत लागू किए बिना अन-रिवर्ट करना चाहते हैं, तो आप नष्ट होने पर (1) मूल शाखा को पुनर्स्थापित कर सकते हैं, (2) एडम द्वारा बताए अनुसार, रिवर्ट शाखा पर "रिवर्ट" पर क्लिक करें , (तब) 3) परिणामी पीआर के हेडर में "एडिट" पर क्लिक करें और टारगेट ब्रांच को मास्टर की बजाय मूल ब्रांच में बदलें। अब आपकी मूल शाखा को पूर्ववर्ती परिवर्तनों को प्रभावित करने के लिए फिर से विलय किया जा सकता है।
पौलज्म

1
कृपया ध्यान दें कि यह काम करने वाले पेड़ और सूचकांक में सभी परिवर्तनों को हटा देगा। जिन परिवर्तनों को आप खोना नहीं चाहते, उन्हें बचाने के लिए git stash का उपयोग करें।
zpon

3
चेकआउट और& प्रतिबद्ध पद्धति का क्या लाभ है? ऐसा लगता है कि सामान्य मामले में git cherry-pickया वैकल्पिक रूप git revertसे एक पलटना वापस करने के लिए सबसे सीधे-आगे के तरीके हैं।
रॉबर्ट जैक विल

5
मुझे लगता है कि यह दिखाना उपयोगी होगा कि कैसे: Otherwise, reverting the revert is perfectly fine.और फिर यह समझाने के लिए कि क्या git checkout HEAD^^ -- .कर रहा है।
टॉड

3
अच्छा प्रभु, git add -Aतब तक उपयोग न करें ... जब तक आप हर फ़ाइल को संस्करण नियंत्रण में नहीं जोड़ना चाहते हैं, जो कि सबसे अधिक संभावना है कि आप क्या चाहते हैं।
काइटेन

473

git cherry-pick <original commit sha>
मूल प्रतिबद्ध की एक प्रति बनाएगा, अनिवार्य रूप से प्रतिबद्ध को फिर से लागू करेगा

मैसेज करने वाले मैसेज के साथ रिवर्ट को वापस करेंगे।
git revert <commit sha of the revert>

इन तरीकों में से git pushकोई भी आपको इतिहास को अधिलेखित किए बिना अनुमति देगा , क्योंकि यह वापस आने के बाद एक नई प्रतिबद्धता बनाता है।
जब आप कमि टाइप करते हैं, तो आपको आमतौर पर पहले 5 या 6 अक्षरों की आवश्यकता होती है:
git cherry-pick 6bfabc


60
यह आसानी से ओपीएस प्रश्न का सबसे सुरुचिपूर्ण और पूर्ण समाधान है। इसके साथ स्वीकार किए गए उत्तर की तुलना में बेहतर है कि यह पुनर्विचार प्रतिबद्ध है कि प्रतिबद्ध पेड़ के हेड पर। ऑप ने विशेष रूप से एक समाधान के लिए कहा जो इतिहास को फिर से नहीं लिखता है इसलिए स्वीकार किए गए उत्तर में प्रस्तुत कठिन समाधान बस गलत है।
तिमो

6
@Timo स्पष्ट करने के लिए, स्वीकृत उत्तर में वह समाधान होता है जिसका मैंने उपयोग किया था ("रिवर्टर रिवर्ट करना"), और मेरे प्रश्न के कुछ घंटों के भीतर पोस्ट किया गया था - इस उत्तर से 3 साल पहले एक स्पष्ट । इसलिए, चेक मार्क।
जिममिड्यू जू

6
@JimmidyJoo मुझे पता है कि मुझे 3 साल की देर हो गई थी, मैं बस चाहता था कि लोग एक बेहतर खोज देखने के लिए गूगल सर्च से यहां आएं
Stephan

2
@Stephan हां, लेकिन फिर से, स्पष्ट करने के लिए - यह एक बेहतर जवाब है न कि मैं सिर्फ अपनी समस्या को हल करने के लिए इस्तेमाल किया। मैं केवल इस बात पर टिप्पणी कर रहा था कि चेक मार्क क्यों है। सभी के लिए प्रश्न: क्या एसओ कन्वेंशन यह तय करता है कि मुझे अपने पिछले प्रश्नों को "बनाए रखना चाहिए" और नए उत्तर आते ही चेक मार्क को फिर से असाइन करना चाहिए?
जिम्मीजियू

3
@JimmidyJoo मुझे एसओ सम्मेलन के बारे में कोई जानकारी नहीं है। लेकिन एक Google खोजकर्ता के रूप में, मैं वास्तव में बेहतर उत्तर को देखना पसंद करता हूं। और अपने पिछले सवालों को बनाए रखने के लिए किसी के प्रयासों की सराहना करेंगे।
पैमान रूतानन

28

रीट कमिट किसी भी अन्य कमिट की तरह है। मतलब, आप इसे वापस कर सकते हैं, जैसे कि:

git revert 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746

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

हमारी टीम में, हम मुख्य रूप से इतिहास को साफ रखने के लिए मुख्य शाखा में किए गए रिवर्ट कमिट पर एक रिवर्ट का उपयोग करने के लिए एक नियम रखते हैं , ताकि आप देख सकें कि कौन सी प्रतिज्ञाओं को प्रभावित करती है:

      7963f4b2a9d   Revert "Revert "OD-9033 parallel reporting configuration"
      "This reverts commit a0e5e86d3b66cf206ae98a9c989f649eeba7965f.
                    ...
     a0e5e86d3b6    Revert "OD-9055 paralel reporting configuration"
     This reverts commit 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746.
                ...
     Merge pull request parallel_reporting_dbs to master* commit 
    '648d7d808bc1bca6dbf72d93bf3da7c65a9bd746'

इस तरह, आप इतिहास का पता लगा सकते हैं और पूरी कहानी का पता लगा सकते हैं, और यहां तक ​​कि विरासत के ज्ञान के बिना भी वे इसे खुद के लिए काम कर सकते हैं। जबकि, यदि आप चेरी-पिक या रिबेज सामान लेते हैं , तो यह बहुमूल्य जानकारी खो जाती है (जब तक कि आप इसे टिप्पणी में शामिल नहीं करते)।

जाहिर है, अगर कोई कमिटमेंट एक बार से ज्यादा रिवर्ट और रिवर्ट हुआ तो काफी गड़बड़ हो जाता है।


14

उलटा लौटना चालबाजी करेगा

उदाहरण के लिए,

यदि abcdefआपकी प्रतिबद्धता है और आपके द्वारा प्रतिबद्ध ghijklकिए जाने पर आपके पास वापस जाने के लिए प्रतिबद्ध है abcdef, तो चलाएं:

git revert ghijkl

इससे रिवर्ट वापस हो जाएगा


4

यह मेरे लिए बेवकूफ लग रहा है। लेकिन मैं एक ही स्थिति में था और मैंने उलटे कमिट्स के लिए रिवर्ट किया। मैंने नंबर रिवर्ट किया, इसलिए मुझे प्रत्येक 'रिवर्ट कमिट' के लिए रिवर्ट करना पड़ा।

अब मेरा इतिहास इतिहास थोड़ा अजीब लग रहा है।

अजीब इतिहास

यह एक पालतू परियोजना है इसलिए यह ठीक है। लेकिन वास्तविक जीवन की परियोजना के लिए मैं एक कमिट और अधिक वाजिब टिप्पणी में एक साथ सभी रिवर्ट किए गए कोड को वापस लाने से पहले अंतिम प्रतिबद्ध पर जाने को प्राथमिकता दूंगा।


4
आप मेरे एक और सवाल के जवाब में दिलचस्पी ले सकते हैं: stackoverflow.com/questions/10415565/…
JimmidyJoo

2
आप ऑटो कमिट करने से बच सकते हैं और जब आप संबंधित संदेश का उपयोग कर -no-प्रतिबद्ध ध्वज का उपयोग करते हैं और तब संबंधित संदेश के साथ प्रतिबद्ध कर सकते हैं
डेविड बार्डा

जीआईटी रिवर्ट (जब मुझे लगता है कि उन्हें सही क्रम में होना है) का उपयोग करते हुए भी आप कई प्रतिबद्ध आईडी निर्दिष्ट कर सकते हैं।
एलेक्सी गाबी

क्या मैं ऐसा जीथब डेस्कटॉप से ​​कर सकता हूं?
गुइलूम एफ।

4

यहां बताया गया है कि मैंने यह कैसे किया:
यदि शाखा my_branchnameको मर्ज में शामिल किया गया था जो वापस मिल गया। और मैं अनियंत्रित होना चाहता थाmy_branchname :

मैं पहले एक git checkout -b my_new_branchnameसे my_branchname
तब मैं एक कर git reset --soft $COMMIT_HASHजहां $COMMIT_HASHप्रतिबद्ध अधिकार के हैश प्रतिबद्ध है से पहले पहले की प्रतिबद्ध my_branchnameहै (देखें git log)
तो मैं एक नया प्रतिबद्ध बनाने git commit -m "Add back reverted changes"
तब मैं नई शाखा को धक्का git push origin new_branchname
तब मैं नई शाखा के लिए एक पुल का अनुरोध किया।


जाने के लिए रास्ता जब बहुत सारे "चेरी-पिक" करने के लिए हैं। मुझे यह नहीं
सूझता

2

या आप कर सकते हैं git checkout -b <new-branch>और git cherry-pick <commit>करने से पहले और git rebaseकरने के लिए revertप्रतिबद्ध है। पहले की तरह पुल अनुरोध भेजें।


1

यदि आपको "रिवर्ट रिवर्टिंग" का विचार पसंद नहीं है (विशेषकर जब इसका मतलब है कि कई कमिट्स के लिए इतिहास की जानकारी खोना), तो आप हमेशा "एक गलत मर्ज को फिर से शुरू करने" के बारे में डॉक्यूमेंट के लिए जा सकते हैं

निम्नलिखित शुरुआती स्थिति को देखते हुए

 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E   <-- fixed-up topic branch

(W, मर्ज M का आपका प्रारंभिक रिवर्ट है; D और E आपकी आरंभिक रूप से टूटी हुई सुविधा शाखा / प्रतिबद्ध के लिए फिक्स हैं)

अब आप रीप्ले को A से E तक ले जा सकते हैं, ताकि उनमें से कोई भी "मर्ज" न हो जाए।

$ git checkout E
$ git rebase --no-ff P

आपकी शाखा की नई प्रति अब masterफिर से मर्ज की जा सकती है :

   A'---B'---C'------------D'---E'  <-- recreated topic branch
  /
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E

अच्छा विचार और डॉक्टर लिंक के लिए धन्यवाद। हम आमतौर पर वापस विलय करने से पहले मास्टर के साथ रिबेट करते हैं, लेकिन फिर git को लगता है कि A ', B', C 'पहले वाले के समान हैं, और मेरे पास अब W ( pastebin ) के बाद D, E है । इसे हल करने के बारे में सुझाव?
क्रिस्टोफर बक्केजॉर्ड

0

अनस्ट्रेड और स्टेज किए गए परिवर्तनों को वापस लाने के लिए जो एक कमिट के बाद वापस किए गए थे:

git reset HEAD@{1}

सभी अस्थिर हटाने के लिए:

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