जीआईटी रिबास के तहत


3177

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

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

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

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

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

कोई विचार?

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


6
यह भी ध्यान दें कि छूट के दौरान आप कमिट्स को बाहर कर सकते हैं, या उन्हें स्क्वैश कर सकते हैं; इन परिवर्तनों को मूल नोड्स के लिए एक सूचक के बिना वापस नहीं किया जा सकता है या रिफ्लग के माध्यम से शिफ्ट किया जा सकता है, इसलिए चेरीपिंग काम नहीं करेगा।
ANeves

जवाबों:


4334

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

git reflog

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

मान लीजिए कि पुराना वचन HEAD@{5}रेफरी लॉग में था:

git reset --hard HEAD@{5}

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

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

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

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

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

[core]
    logAllRefUpdates = true

113
Git reflog कमाल का है, बस याद रखें कि आप बेहतर स्वरूपित आउटपुट प्राप्त कर सकते हैं git log -g(स्कॉट चाकोन के progit.org/book से टिप )।
कर्मी

60
@Zach: git rebase --abort( -iइससे कोई मतलब नहीं है --abort) एक रिबेस को छोड़ने के लिए है जो पूरा नहीं हुआ है - या तो क्योंकि वहाँ संघर्ष थे या क्योंकि यह इंटरैक्टिव था या दोनों; यह एक सफल छूट को पूर्ववत् करने के बारे में नहीं है जो कि सवाल है। आप या तो प्रयोग करेंगे rebase --abortया reset --hardजो स्थिति आप में थे पर निर्भर करता है। आप दोनों क्या करने की जरूरत नहीं होनी चाहिए।
सीबी बेली

310
बस के मामले में, पहले एक बैकअप बनाओ git tag BACKUP:। अगर कुछ गलत हो जाता है, तो आप इसे वापस कर सकते हैं:git reset --hard BACKUP
kolypto

6
यदि आपने HEAD @ {#} पर बहुत सारे काम किए हैं, तो आप देख रहे हैं commit:कि विरोध किया जाएगा rebase:। स्पष्ट लगता है लेकिन इसने मुझे थोड़ा भ्रमित कर दिया।
२०

4
आकस्मिक विद्रोह के बाद पार्टी में शामिल होना: डी। एक नहीं चाहेंगे git reset --hard ORIG_HEADचाल के साथ-साथ तुरंत आकस्मिक रिबेस के बाद करते हैं?
क्वालाल

1485

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

git reset --hard ORIG_HEAD

हालाँकि, और reset, rebaseऔर mergeसभी अपने मूल HEADपॉइंटर को इसमें सहेजते हैं ORIG_HEAD, यदि आपने उन आदेशों में से कोई भी किया है जो आप पूर्ववत करने की कोशिश कर रहे हैं, तो आपको फिर से उपयोग करना होगा।


34
यदि ORIG_HEADअब उपयोगी नहीं है, तो आप branchName@{n}सिंटैक्स का उपयोग भी कर सकते हैं , जहां nशाखा सूचक की नौवीं पूर्व स्थिति है। उदाहरण के लिए, यदि आप featureAअपनी शाखा पर शाखा को रीबेज करते हैं master, लेकिन आप रिबास के परिणाम को पसंद नहीं करते हैं, तो आप बस git reset --hard featureA@{1}उस शाखा को वापस रीसेट करने के लिए कर सकते हैं, जहां आपने रिबेस करने से पहले यह किया था। आप संशोधन के लिए आधिकारिक Git डॉक्स पर शाखा @ {n} सिंटैक्स के बारे में अधिक पढ़ सकते हैं ।

15
यह सबसे आसान है। git rebase --abortहालांकि इसके साथ पालन करें ।
Seph

1
@DaBlick इस पर मेरे लिए पूरी तरह से सफल होने के बाद ठीक से काम नहीं किया git 2.17.0
DVlsg

4
और मुझे इसे पूरक करने दें: git reset --hard ORIG_HEADबार-बार रोल करने के लिए बार-बार उपयोग कर सकते हैं। कहो, अगर A --- रीबेज़ से --- B --- रिबेज़ से --- C, अब मैं C पर हूँ, तो मैं A को दो बार प्रयोग करके वापस जा सकता हूँgit reset --hard ORIG_HEAD
CalvinChe

5
@ सिफ आप समझा सकते हैं कि आप क्यों सुझाव दे रहे हैं git rebase --abort?
UpTheCreek

385

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

git rebase --abort

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

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


4
इसने मेरे प्रॉम्प्ट में "| REBASE" भाग को हटा दिया। +1
रूटर थिएलेन

62
यह सवाल नहीं था। सवाल पूछता है कि एक समाप्त रिबास को पूर्ववत् कैसे करें।
अरुणव सान्याल

2
चार्ल्स जवाब पर एक टिप्पणी होनी चाहिए, क्योंकि यह इस पर सवाल का जवाब नहीं देता है
म्यूरल

हम्म, मुझे ऐसा नहीं करना था।
विक्टर सेक् सिप

1
केवल वही जो मेरे लिए काम करता है!
अलेक्जेंड्रे पिकार्ड

90

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

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

git rebase --onto 0deadbeef master topic

यह उन सभी कमिटों को लेगा topicजो कि चालू नहीं हैं masterऔर उन्हें शीर्ष पर फिर से खेलना है 0deadbeef

इसके साथ --onto, आप अपने इतिहास को किसी भी आकार में पुन: व्यवस्थित कर सकते हैं ।

मज़े करो। :-)


3
मुझे लगता है कि लचीलेपन के कारण यह सबसे अच्छा विकल्प है। मैंने b1 को मास्टर के रूप में विभाजित किया, फिर b1 को एक नई शाखा b2 में बदल दिया, फिर b1 को फिर से मास्टर पर आधारित होना चाहता था। मैं सिर्फ प्यार प्यार - धन्यवाद!
ripper234

2
यह यहाँ सबसे अच्छा विकल्प है! इसने मेरे वर्तमान शाखा में सभी परिवर्तनों को रखा, और सभी अवांछित लोगों को हटा दिया!
एलिसिया तांग

मैं कहता हूँ कि के संयोजन के साथ --ontoऔर -iआप अपने इतिहास को किसी भी आकार में पुनर्व्यवस्थित कर सकते हैं। :-) बनाने के लिए gitk (या gitx का मैक) का उपयोग करें।
rjmunro

69

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

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


2
मैं भी यही करता हूं। यह सुनिश्चित करने के लिए भी महत्वपूर्ण है कि BACKUP..HEAD को बदलने के लिए सुनिश्चित करें कि आपने जो कुछ भी किया है उसे आप बदल दिया है।
पॉल बोन

5
मैं भी ऐसा करता था, लेकिन चूंकि मैं रिफ्लॉग के साथ अधिक सहज हो गया था इसलिए मुझे नहीं लगता कि यह आवश्यक है। जब भी आप HEAD को बदलते हैं, तो रिफंड अनिवार्य रूप से आपकी ओर से ऐसा कर रहा होता है।
पीट हॉजसन

4
खैर, मैं सार्थक नामों को पसंद करता हूं, क्योंकि रिफ्लॉग में सही आइटम की खोज करना कभी-कभी मज़ेदार नहीं होता है।
एलेक्स गोम्तखेर

12
आपको वास्तव में एक बैकअप शाखा बनाने की आवश्यकता नहीं है, आप बस branchName@{n}सिंटैक्स का उपयोग कर सकते हैं , यहां nशाखा सूचक की नौवीं पूर्व स्थिति है। उदाहरण के लिए, यदि आप featureAअपनी शाखा पर शाखा को रीबेज करते हैं master, लेकिन आप रिबास के परिणाम को पसंद नहीं करते हैं, तो आप बस git reset --hard featureA@{1}उस शाखा को वापस रीसेट करने के लिए कर सकते हैं, जहां आपने रिबेस करने से पहले यह किया था। आप संशोधन के लिए आधिकारिक Git डॉक्सbranch@{n} पर वाक्य रचना के बारे में अधिक पढ़ सकते हैं ।

2
दरअसल, पैट नोटज़ के उत्तर के अनुसार, आपको सिंटैक्स का उपयोग करने की आवश्यकता नहीं HEADहै, शाखा का मूल अस्थायी रूप से संग्रहीत है ORIG_HEAD। लेकिन एक बैकअप शाखा लेबल का उपयोग करने की तकनीक भी काम करती है, यह सिर्फ और अधिक कदम है।

68

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

git रीसेट - भार उत्पत्ति / {शाखा नाम}

उदाहरण:

$ ~/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

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

23

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

मेरे लिए जो काम किया, वह यहाँ वर्णित के समान था । फ़ाइल को .it / log / 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


3
वाह - उस लिंक से, "एक कैविएट है: मैंने शाखा का इतिहास खो दिया है, लेकिन इस मामले में यह वास्तव में कोई फर्क नहीं पड़ा। मैं अपने परिवर्तनों को प्राप्त करने के लिए खुश था।" ?
रफिन

16

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


11

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

इसके बजाय ऐसा करने का git rebase -i --abort (ध्यान दें मैं ) मैं बस करना था git rebase --abort( बिना मैं )।

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

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

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

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

11

यदि आपने दूरस्थ शाखा के खिलाफ सफलतापूर्वक विद्रोह कर दिया है और git rebase --abortआप अभी भी अपने काम को बचाने के लिए कुछ तरकीबें नहीं कर सकते हैं और जबरदस्ती धक्का नहीं दिया है। मान लीजिए कि आपकी वर्तमान शाखा जो गलती से छूट गई थी उसे कॉल किया जाता है your-branchऔर ट्रैक किया जाता हैorigin/your-branch

  • git branch -m your-branch-rebased # वर्तमान शाखा का नाम बदलें
  • git checkout origin/your-branch # नवीनतम स्थिति के लिए चेकआउट जो मूल के लिए जाना जाता है
  • git checkout -b your-branch
  • जाँच करें git log your-branch-rebased, की तुलना करें git log your-branchऔर उन कमिट्स को परिभाषित करें जो से गायब हैंyour-branch
  • git cherry-pick COMMIT_HASH में हर कमिट के लिए your-branch-rebased
  • अपने बदलावों को आगे बढ़ाएं। कृपया ध्यान रखें कि दो स्थानीय शाखाएँ आपस में जुड़ी हुई हैं remote/your-branchऔर आपको केवल धक्का देना चाहिएyour-branch

4

मान लीजिए कि मैं अपनी फीचर शाखा में मास्टर को रिजेक्ट करता हूं और मुझे 30 नए कमिट मिलते हैं जो कुछ तोड़ते हैं। मैंने पाया है कि अक्सर बुरे कमेंट्स को दूर करना सबसे आसान है।

git rebase -i HEAD~31

पिछले 31 के लिए इंटरएक्टिव रिबास (यदि आप बहुत सारे रास्ते चुनते हैं तो यह चोट नहीं पहुंचाता है)।

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


3

Newbies के लिए / किसी को भी हार्ड रीसेट करने से डर लगता है, तो आप कमिट से चेकआउट कर सकते हैं, और फिर इसे नई शाखा के रूप में सहेज सकते हैं।

git reflog

रिबासिंग शुरू करने से ठीक पहले कमिटमेंट खोजें। इसे खोजने के लिए आपको और नीचे स्क्रॉल करने की आवश्यकता हो सकती है (Enter या PageDown दबाएं)। HEAD नंबर पर ध्यान दें और 57 को बदलें:

git checkout HEAD@{57}

शाखा की समीक्षा करें / करें, यदि यह अच्छा लगता है तो इस HEAD का उपयोग करके एक नई शाखा बनाएँ:

git checkout -b new_branch_name

2

यदि आप एक शाखा पर हैं, तो आप इसका उपयोग कर सकते हैं:

git reset --hard @{1}

केवल हेड (द्वारा प्राप्त git reflog) के लिए एक संदर्भ लॉग नहीं है , प्रत्येक शाखा के लिए भी रिफ्लेक्स हैं (प्राप्त git reflog <branch>)। इसलिए, यदि आप हैं masterतो git reflog masterउस शाखा में सभी परिवर्तनों को सूचीबद्ध करेंगे। आप से है कि परिवर्तन का उल्लेख कर सकते master@{1}, master@{2}आदि

git rebase आमतौर पर कई बार हेड को बदल देगा लेकिन वर्तमान शाखा को केवल एक बार अपडेट किया जाएगा।

@{1}वर्तमान शाखा के लिए एक शॉर्टकट है , इसलिए master@{1}यदि आप चालू हैं तो यह बराबर है master

git reset --hard ORIG_HEADयदि आप git resetएक इंटरैक्टिव के दौरान इस्तेमाल किया काम नहीं करेगा rebase


1

जो मैं आमतौर पर करता हूं git reset #commit_hash

अंतिम प्रतिबद्ध के लिए, जहां मुझे लगता है कि रिबास का कोई प्रभाव नहीं था।

फिर git pull

अब आपका ब्रांच बिल्कुल मास्टर की तरह मैच होना चाहिए और रीबिटेड कमिट्स उसमें नहीं होना चाहिए।

अब इस ब्रांच पर कोई भी बस चेरी-पिक कर सकता है।


1

मैंने रीसेट के साथ सभी सुझावों की कोशिश की और बिना किसी सफलता के फिर से लिखा। IntelliJ के स्थानीय इतिहास को पुनर्स्थापित करने ने खोई हुई फ़ाइलों की समस्या को हल किया


धन्यवाद! पहले कभी भी स्थानीय इतिहास का उपयोग नहीं किया, लेकिन यह मेरे लिए कुछ आकस्मिक रूप से विद्रोही कोड को पुनर्प्राप्त करने का सबसे आसान विकल्प निकला। बहुत अच्छी लेकिन कुछ छिपी हुई सुविधा।
मैग्नस डब्ल्यू

0

git रीसेट - भार उत्पत्ति / {शाखा नाम}

रिबेस द्वारा किए गए आपके सभी स्थानीय परिवर्तनों को रीसेट करने का सही समाधान है।


1
यदि आप हार्ड रीसेट करते हैं origin/branchतो आप HEAD और उस बिंदु के बीच परिवर्तन खो सकते हैं। आप नहीं चाहते कि आम तौर पर बोल रहा हूँ।
ब्लूज़मॉन्क

यह वही है जो मैं अपने मामले में चाहता था। इतना उतावलापन।
मंदार वेज

-4

यदि आप एक जीआईटी रिबेस के भीतर कुछ गड़बड़ git rebase --abortकरते हैं , उदाहरण के लिए , जब आपके पास फाइलें नहीं हैं, तो वे खो git reflogजाएंगे और मदद नहीं करेंगे। यह मेरे साथ हुआ और आपको यहां बॉक्स के बाहर सोचने की आवश्यकता होगी। यदि आप मेरी तरह भाग्यशाली हैं और IntelliJ वेबस्टॉर्म का उपयोग करते हैं तो आप right-click->local historyअपनी फ़ाइल / फ़ोल्डरों की पिछली स्थिति में वापस आ सकते हैं और कोई फर्क नहीं पड़ता कि आपने वर्जनिंग सॉफ़्टवेयर के साथ क्या गलतियाँ की हैं। एक और असफल कैफे चलाना हमेशा अच्छा होता है।


5
git rebase --abortएक सक्रिय रिबेस को निरस्त करता है, यह रिबेड को पूर्ववत नहीं करता है । इसके अलावा, एक ही समय में दो वीसीएस का उपयोग करना एक बुरा विचार है। Jetbrains सॉफ्टवेयर में इसकी एक अच्छी विशेषता है, लेकिन आपको दोनों का उपयोग नहीं करना चाहिए। Git सीखना बेहतर है, विशेषकर जब Stit Overflow पर प्रश्नों का उत्तर देना जो Git के बारे में हो।
dudewad
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.