सवाल एक गिट रिबेस को पूर्ववत करना


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

दिमाग में आने का एकमात्र तरीका मैन्युअल रूप से जाना है:

  • गिट चेकआउट माता-पिता दोनों शाखाओं को चेकआउट करें
  • फिर वहां से एक अस्थायी शाखा बनाएं
  • चेरी-सब हाथ से काम करता है
  • उस शाखा को प्रतिस्थापित करें जिसमें मैंने मैन्युअल रूप से बनाई गई शाखा द्वारा पुन: प्रयास किया था

मेरी वर्तमान स्थिति में यह काम करेगा क्योंकि मैं आसानी से दोनों शाखाओं से काम करता हूं (एक मेरी चीज थी, दूसरा मेरा सहयोगी सामान था)।

हालांकि मेरा दृष्टिकोण मुझे उपोक्त और त्रुटि-प्रवण के रूप में मारता है (मान लीजिए कि मैंने अपनी खुद की शाखाओं में से 2 के साथ पुनर्विचार किया था)।

कोई विचार?

स्पष्टीकरण: मैं एक रिबेस के बारे में बात कर रहा हूं जिसके दौरान कामों का एक गुच्छा फिर से चलाया गया था। न केवल एक।


2434
2017-09-25 17:59


मूल


यह भी ध्यान दें कि एक रिबेस के दौरान आप काम को बाहर कर सकते हैं, या उन्हें स्क्वैश कर सकते हैं; ये परिवर्तन मूल नोड्स के पॉइंटर के बिना या रीफ्लॉग के माध्यम से बहने के बिना वापस नहीं किए जा सकते हैं, इसलिए चेरीपिकिंग काम नहीं करेगी। - ANeves
stackoverflow.com/a/692763/2458438 यह आदर्श रूप से स्वीकार्य उत्तर होना चाहिए। - DDM


जवाब:


सबसे आसान तरीका शाखा के सिर प्रतिबद्धता को ढूंढना होगा क्योंकि यह पुन: शुरू होने से ठीक पहले था reflog...

git reflog

और वर्तमान शाखा को रीसेट करने के लिए (सामान्य चेतावनी के साथ रीसेट करने से पहले पूरी तरह से सुनिश्चित होने के बारे में --hard विकल्प)।

मान लीजिए पुरानी प्रतिबद्धता थी HEAD@{5} रेफ लॉग में:

git reset --hard HEAD@{5}

विंडोज़ में, आपको संदर्भ उद्धृत करने की आवश्यकता हो सकती है:

git reset --hard "HEAD@{5}"

आप केवल एक करके उम्मीदवार के पुराने सिर का इतिहास देख सकते हैं git log HEAD@{5} (विंडोज:  git log "HEAD@{5}")।

यदि आपने प्रति शाखा रीफ्लॉग अक्षम नहीं किया है तो आप बस ऐसा करने में सक्षम होना चाहिए git reflog branchname@{1} क्योंकि एक विद्रोह अंतिम सिर पर पहुंचने से पहले शाखा के सिर को अलग करता है। मैं इसे दोबारा जांचूंगा, हालांकि मैंने हाल ही में यह सत्यापित नहीं किया है।

डिफ़ॉल्ट रूप से, सभी रीफ्लॉग गैर-नंगे भंडारों के लिए सक्रिय होते हैं:

[core]
    logAllRefUpdates = true

3371
2017-09-25 19:56



गिट रीफ्लॉग बहुत बढ़िया है, बस याद रखें कि आप बेहतर प्रारूपित आउटपुट प्राप्त कर सकते हैं git log -g (स्कॉट चेकॉन से टिप progit.org/book)। - karmi
@Zach: git rebase --abort (-i के साथ कोई मतलब नहीं है --abort) एक रिबेस को त्यागने के लिए है जो पूरा नहीं हुआ है - या तो क्योंकि संघर्ष थे या क्योंकि यह इंटरैक्टिव था या दोनों; यह एक सफल रिबेस को पूर्ववत करने के बारे में नहीं है, जो सवाल है। आप या तो उपयोग करेंगे rebase --abort या reset --hard इस स्थिति के आधार पर कि आप किस स्थिति में थे। आपको दोनों को करने की आवश्यकता नहीं है। - CB Bailey
धन्यवाद! मेरे गिट इंस्टॉल में मुझे काम करने के लिए उद्धरणों में "HEAD {22}" डालना होगा। - SidJ
यह मेरे जीवन को बचाया ... दुर्भाग्य से, मेरे में haste मैंने किया git reset --hard HEAD@{5} - जो मैं करना चाहता था उससे ऊपर दो काम करता था। कहने की जरूरत नहीं है, गिट के लिए भगवान का शुक्र है जिसने मुझे आगे बढ़ने और एक और करने के बाद, उस सुधार को करने की अनुमति दी git reflogऔर जिस प्रतिबद्धता को मैं जाना चाहता था उसे महसूस करना सिर्फ 1 तक बढ़ गया था, मैंने तुरंत इसे ठीक किया और सब अच्छा है। =) - marcamillion
बस मामले में, पहले बैकअप लें: git tag BACKUP। कुछ गलत होने पर आप इसे वापस कर सकते हैं: git reset --hard BACKUP - kolypto


असल में, रीबेस आपके शुरुआती बिंदु को बचाता है ORIG_HEAD इसलिए यह आमतौर पर सरल है:

git reset --hard ORIG_HEAD

हालांकि reset, rebase तथा merge सब तुम्हारा मूल बचाओ HEAD में सूचक ORIG_HEAD इसलिए, यदि आपने उन आदेशों में से कोई भी किया है जो रीबेज के बाद से आप पूर्ववत करने का प्रयास कर रहे हैं तो आपको रीफ्लॉग का उपयोग करना होगा।


1169
2018-03-28 13:24



धन्यवाद। इससे मुझे स्क्वैश वापस करने में मदद मिली! - kakyo
यदि ORIG_HEAD अब उपयोगी नहीं है, आप भी इसका उपयोग कर सकते हैं branchName@{n} वाक्यविन्यास, कहाँ n शाखा सूचक की पिछली स्थिति है। तो उदाहरण के लिए, यदि आप rebase featureA आपकी शाखा master शाखा, लेकिन आपको रिबेस के नतीजे पसंद नहीं हैं, तो आप बस कर सकते हैं git reset --hard featureA@{1} शाखा को फिर से रीसेट करने के लिए जहां आप रीबेज करने से पहले थे। आप शाखा @ {n} वाक्यविन्यास के बारे में अधिक पढ़ सकते हैं संशोधन के लिए आधिकारिक गिट दस्तावेज़।
यह सबसे आसान है। एक के साथ इसका पालन करें git rebase --abort हालांकि। - Seph
यह स्वीकार्य उत्तर आईएमओ होना चाहिए। - Tomáš Fejfar
ORIG_HEAD यदि आपने अभी एक रिबेज किया है और इसे एक शांत और शांतिपूर्ण तरीके से वापस करना चाहते हैं तो बहुत बहुत उपयोगी है। यह शीर्ष वोट उत्तर (या स्वीकृत उत्तर) होना चाहिए। इसे एक टक्कर की जरूरत है। शीर्ष वोट दिया गया जवाब जो एक करने के लिए कहता है git reset --hard HEAD@{5} अनावश्यक सिर गिनती शामिल है जिसमें गलत होने की अधिक संभावना है। - DDM


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

git rebase --abort

के बाद साफ करने के लिए reset

अन्यथा, आपको संदेश मिल सकता है "Interactive rebase already started"।


320
2017-07-27 18:21



इसने मेरे प्रॉम्प्ट में "| REBASE" भाग हटा दिया। +1 - Wouter Thielen
मुझे लगता है कि यह होना चाहिए git rebase --abort में (शायद गिट के आपके संस्करण के आधार पर)। - Seph
वह सवाल नहीं था। प्रश्न पूछता है कि एक पूर्ण रिबेस को पूर्ववत कैसे करें। - Arunav Sanyal
@ArunavSanyal यह आखिरी उम्मीद है अगर पूर्ववत विफल हो गया है .. - aswzen


अपनी पुरानी नोक की लटकती प्रतिबद्ध वस्तु को शाखा को रीसेट करना निश्चित रूप से सबसे अच्छा समाधान है, क्योंकि यह किसी भी प्रयास के बिना पिछले राज्य को पुनर्स्थापित करता है। लेकिन अगर आप ऐसा करते हैं जो खो जाते हैं (f.ex. क्योंकि आप इस दौरान अपने भंडार को कचरा इकट्ठा करते हैं, या यह एक नया क्लोन है), तो आप हमेशा शाखा को फिर से दबा सकते हैं। इसकी कुंजी है --onto स्विच।

मान लीजिए कि आपके पास कल्पना की जाने वाली विषय शाखा थी topic, कि आप बंद कर दिया master जब की नोक master था 0deadbeef प्रतिबद्ध। कुछ बिंदु पर जबकि topic शाखा, तुमने किया था git rebase master। अब आप इसे पूर्ववत करना चाहते हैं। ऐसे:

git rebase --onto 0deadbeef master topic

यह सब कुछ ले जाएगा topic जो चालू नहीं हैं master और उन्हें शीर्ष पर फिर से चलाएं 0deadbeef

साथ में --onto, आप अपने इतिहास को काफी ज्यादा व्यवस्थित कर सकते हैं कोई भी आकार

मज़े करो। :-)


75
2017-09-26 02:08



मुझे लगता है कि इसकी लचीलापन के कारण यह सबसे अच्छा विकल्प है। मैंने मास्टर से बी 1 ब्रांच किया, फिर बी 1 को एक नई शाखा बी 2 में दोबारा बांध दिया, फिर फिर से मास्टर पर आधारित होने के लिए बी 1 को वापस करना चाहता था। मुझे बस गिट पसंद है - धन्यवाद! - ripper234
यह सबसे अच्छा विकल्प है! यह मेरी वर्तमान शाखा में मेरे सभी परिवर्तनों को रखता है, और सभी अवांछित लोगों को हटा देता है! - Alicia Tang
मैं कहूंगा कि एक संयोजन के साथ --onto तथा -i आप अपने इतिहास को किसी भी आकार में बहुत अधिक आकार में पुनर्व्यवस्थित कर सकते हैं। आपके द्वारा बनाए गए आकार देखने के लिए गिटक (या मैक पर gitx) का उपयोग करें :-)। - rjmunro


मैं वास्तव में शाखा पर बैकअप टैग डालता हूं इससे पहले कि मैं कोई नॉनट्रिविअल ऑपरेशन करता हूं (अधिकांश रिबेज छोटे होते हैं, लेकिन अगर ऐसा कहीं भी जटिल लगता है तो मैं ऐसा करूँगा)।

फिर, बहाल करना उतना आसान है जितना आसान है git reset --hard BACKUP


62
2018-05-12 20:57



मैं भी यह करता हूँ। बैकअप को अलग करने के लिए भी उपयोगी है .. यह सुनिश्चित करने के लिए कि आपने जो किया है उसे बदल दिया है। - Paul Bone
मैं भी ऐसा करता था, लेकिन जब से मुझे रिफ्लॉग के साथ और अधिक सहजता मिली, मुझे अब यह आवश्यक नहीं लगता है। प्रत्येक बार जब आप हेड बदलते हैं तो रेफ्लॉग अनिवार्य रूप से आपकी तरफ से ऐसा कर रहा है। - Pete Hodgson
खैर, मैं सार्थक नाम पसंद करता हूं, क्योंकि रीफ्लॉग में सही आइटम की तलाश करना कभी-कभी मजेदार नहीं होता है। - Alex Gontmakher
आपको वास्तव में बैकअप शाखा बनाने की भी आवश्यकता नहीं है, आप बस इसका उपयोग कर सकते हैं branchName@{n} वाक्यविन्यास, यहाँ n शाखा सूचक की पिछली स्थिति है। तो उदाहरण के लिए, यदि आप rebase featureA आपकी शाखा master शाखा, लेकिन आपको रिबेस के नतीजे पसंद नहीं हैं, तो आप बस कर सकते हैं git reset --hard featureA@{1} शाखा को फिर से रीसेट करने के लिए जहां आप रीबेज करने से पहले थे। आप इसके बारे में अधिक पढ़ सकते हैं branch@{n} पर वाक्यविन्यास संशोधन के लिए आधिकारिक गिट दस्तावेज़।
असल में, आपको ऊपर दिए गए वाक्यविन्यास का उपयोग करने की भी आवश्यकता नहीं है पैट नोटज़ का जवाब, असली HEAD शाखा का अस्थायी रूप से संग्रहित है ORIG_HEAD। लेकिन बैकअप शाखा लेबल का उपयोग करने की तकनीक भी काम करती है, यह सिर्फ और कदम है।


यदि आपने अपनी शाखा को रिमोट रिपोजिटरी में धक्का दिया था (आमतौर पर यह मूल है) और फिर आपने एक सफल प्रतिक्रिया (बिना विलय के) किया है (git rebase --abort "प्रगति में कोई रिबेस नहीं" देता है) आप आसानी से कर सकते हैं शाखा रीसेट करें का उपयोग करते हुए आदेश:

गिट रीसेट - हार्ड मूल / {शाखा नाम}

उदाहरण:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean

53
2017-09-28 12:43



यह मेरे लिए सही जवाब है। रीबेज से पहले रिबेस और प्रतिबद्धता एक ही प्रतिबद्ध आईडी थी, और हेड {1} पर वापस जाकर बस रिबेस को वापस नहीं किया जाएगा! - Bill Kotsias


यदि आपने रिबेस को पूरा नहीं किया है और इसके बीच में, निम्न कार्य करता है:

git rebase --abort

49
2017-10-15 20:20



यह मेरे लिए काम किया। मैंने विवादों को मर्ज कर दिया था, इसलिए यह 'इसके बीच में' होने के योग्य था। - Fakeer


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


14
2017-09-25 21:36



सच है, अनुस्मारक के लिए धन्यवाद ;-) - webmat


का उपयोग करते हुए reflog मेरे लिए काम नहीं किया

मेरे लिए क्या काम किया गया वर्णन के समान था यहाँ। फ़ाइल को खोले गए शाखा के नाम पर .git / logs / refs में खोलें और उस पंक्ति को ढूंढें जिसमें "रीबेज फिनिश" है, जैसे कुछ:

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

लाइन पर सूचीबद्ध दूसरी प्रतिबद्धता चेकआउट करें।

git checkout 88552c8f

एक बार पुष्टि हुई कि इसमें मेरे खोए गए परिवर्तन शामिल हैं, मैंने ब्रांच किया और राहत का आह्वान किया।

git log
git checkout -b lost_changes

14
2018-02-20 13:59



या यह: stackoverflow.com/questions/1108853/... - cregox
वाह - उस लिंक से, "एक चेतावनी है: मैंने शाखा का इतिहास खो दिया लेकिन इस मामले में यह वास्तव में कोई फर्क नहीं पड़ता। मुझे अपने परिवर्तनों को पुनः प्राप्त करने में खुशी हुई।" ? - ruffin


@ एलन और @ ज़ीरिन के समाधान के बाद, मेरी इच्छा है कि मैं बस एक टिप्पणी कर सकता हूं लेकिन मुझे पर्याप्त प्रतिष्ठा नहीं है, इसलिए मैंने निम्न आदेश का उपयोग किया है:

करने के बजाय git rebase -i --abort  (ध्यान दें -मैं) मुझे बस करना था git rebase --abort (के बग़ैर  -मैं)।

दोनों का उपयोग करना -i तथा --abort साथ ही गिट मुझे उपयोग / विकल्पों की एक सूची दिखाने का कारण बनता है।

तो इस समाधान के साथ मेरी पिछली और वर्तमान शाखा स्थिति है:

matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

matbhz@myPc /my/project/environment (branch-123)
$

11
2018-03-11 21:26