जबरन अपडेट के बाद खींचो


332

मैंने बस कुछ कमिट्स के साथ स्केच किया git rebaseऔर ए किया git push --force(जो बुराई है, मुझे पता है)।

अब अन्य सॉफ्टवेयर इंजीनियरों का एक अलग इतिहास है और जब वे ए करते हैं git pull, तो Git का विलय हो जाएगा। क्या इसे ठीक करने का कोई तरीका है, सिवाय एक करने के rm my-repo; git clone git@example.org:my-repo.git?

मुझे इसके विपरीत की तरह कुछ चाहिए git push --force, लेकिन git pull --forceइच्छित परिणाम नहीं दिए।


16
वे पूरी शाखा को हटाने के बिना अपनी शाखा को हटा सकते हैं और इसे फिर से बना सकते हैं:git checkout master && git branch -D test && git checkout -b test origin/test
फ्लोरियन क्लेन


जवाबों:


509

नए आने के लिए

git fetch

रीसेट

आप एक स्थानीय शाखा का उपयोग करके कमिट को रीसेट कर सकते हैं git reset

स्थानीय शाखा की प्रतिबद्धता को बदलने के लिए:

git reset origin/master --hard

हालाँकि, सावधान रहें क्योंकि दस्तावेज इसे कहते हैं:

सूचकांक और काम करने वाले पेड़ को रीसेट करता है। <प्रतिबद्ध> के बाद से कार्यशील ट्री में ट्रैक की गई फ़ाइलों में कोई भी परिवर्तन नहीं किया गया है।

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

रिबेस

आप का उपयोग कर किसी भी अन्य प्रतिबद्ध / शाखा के शीर्ष पर अपने स्थानीय प्रतिबद्ध फिर से खेलना कर सकते हैं git rebase:

git rebase -i origin/master

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

यदि आपके द्वारा हटाए गए (के साथ git push -f) पहले से ही स्थानीय इतिहास में खींच लिए गए हैं, तो उन्हें उन कमिटों के रूप में सूचीबद्ध किया जाएगा जिन्हें फिर से लागू किया जाएगा - उन्हें रिबेस के हिस्से के रूप में हटा दिया जाना चाहिए या उन्हें बस इतिहास में फिर से शामिल किया जाएगा। शाखा के लिए - और अगले धक्का पर दूरस्थ इतिहास में फिर से दिखाई देना।

git command --helpउपरोक्त किसी भी (या अन्य) कमांड पर अधिक विवरण और उदाहरणों के लिए सहायता का उपयोग करें ।


2
@ भाई-बहन सभी परिवर्तनों को खोने, प्रतिबद्ध इतिहास को हटाने, लेकिन फ़ाइल परिवर्तनों को बनाए रखने, या नए सिर के शीर्ष पर प्रत्येक प्रतिबद्ध को लागू करने का प्रयास करने के बीच चुनते हैं। सबसे सरल विकल्प शायद एक नरम रीसेट है।
AD7six

1
@ भाई-बहन जब आपके सहकर्मी `गिट रीबस ओरिजिन / मास्टर 'का उपयोग करते हैं, और इसका मतलब है कि, वे पहले से ही कुछ प्रतिबद्ध थे, तो गिट अपनी प्रतिबद्ध के पीछे अपनी प्रतिबद्धता लिखेंगे।
टिम

6
गौरतलब हो कि अगर यह एक अलग शाखा के लिए है:git reset origin/otherbranch --hard
bmaupin

तो, स्पष्ट करने के लिए, यह या तो : विकल्प 1: reset --hard, या विकल्प 2: reset --soft+ rebase, है ना?
प्लाज्माबिन्टॉन्ग

2
@PlasmaBinturong सं git reset --soft origin/master। दूरस्थ और अवस्था के अंतर से मेल खाने के लिए इतिहास को बदल देगा जो तब प्रतिबद्ध है । उस परिदृश्य में रिबास करने की कोई आवश्यकता नहीं होगी (और आपको अनधिकृत परिवर्तनों के कारण ऐसा करने से रोका जाएगा) क्योंकि प्रतिबद्ध इतिहास में कोई अंतर नहीं है। दो विकल्प रीसेट या रिबेस हैं - दोनों का संयोजन नहीं। कृपया एक प्रश्न पूछें कि क्या आपका परिदृश्य मेरे द्वारा दिए गए उत्तर से भिन्न है।
AD7six

16

यह उन शाखाओं को ठीक नहीं करेगा जिनके पास पहले से ही वह कोड है जो आप उनमें नहीं चाहते हैं (नीचे देखें कि कैसे करना है), लेकिन अगर उन्होंने कुछ शाखाएं खींच ली हैं और अब इसे साफ करना चाहते हैं (और नहीं "आगे" उत्पत्ति / कुछ-शाखा) तो आप बस:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

नोट: आप इन सभी को उनके बीच && डालकर संयोजित कर सकते हैं

नोट 2: फ्लोरियन ने एक टिप्पणी में इसका उल्लेख किया है, लेकिन जवाब की तलाश में टिप्पणियों को कौन पढ़ता है?

नोट 3: यदि आपके पास दूषित शाखाएँ हैं, तो आप नए "डंब ब्रांच" के आधार पर नए बना सकते हैं और सिर्फ चेरी-पिक कम्यून ओवर कर सकते हैं।

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

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

अब फीचर-नया आपकी शाखा के बिना अतिरिक्त (संभवतः खराब) है!


यह वही है जो मैं वास्तव में चाहता था। किसी ने मास्टर शाखा को फटकार लगाई (भगवान जानता है कि किस कारण से) लेकिन मेरे पास इस पर कोई स्थानीय परिवर्तन नहीं था जो मैं करना चाहता था या कुछ भी। इसलिए मुझे केवल अपनी स्थानीय मास्टर शाखा (जो वास्तव में अजीब लगी) को हटाना था और फिर से एक चेकआउट करना था। धन्यवाद!
डेनिलो कार्वाल्हो

@ पीटर-मोर्टेनसेन संपादित करता करने के लिए पर्याप्त अनुसार होना चाहिए stackoverflow.com/help/editing
टॉम Prats

अंतिम चरण के लिए, आप के git checkout -b base-branch origin/base-branchसाथ भी उपयोग कर सकते हैंgit checkout --track origin/base-branch
ब्लूज़मनक

1

छूट के साथ खींचो

एक नियमित रूप से खींचना + मर्ज है, लेकिन आप जो चाहते हैं वह है + रिबेस। यह pullकमांड के साथ एक विकल्प है :

git pull --rebase

मैं इतिहास में उन सभी मर्ज किए बिना अपनी सुविधा शाखा में मास्टर से नवीनतम कोड प्राप्त करने के लिए हर समय इसका उपयोग करता हूं।
हरमन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.