संक्षिप्त जवाब
आपने इस तथ्य को छोड़ दिया कि आप भाग गए git push
, निम्न त्रुटि हुई, और फिर चलाने के लिए आगे बढ़े git pull
:
To git@bitbucket.org:username/test1.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Git सहायक होने की कोशिश करने के बावजूद, इसकी 'git pull' सलाह सबसे अधिक संभावना है कि आप क्या करना चाहते हैं ।
अगर आप:
- अकेले "सुविधा शाखा" या "डेवलपर शाखा" पर काम करना , फिर आप
git push --force
अपने पोस्ट- रिबास के साथ रिमोट को अपडेट करने के लिए चला सकते हैं ( user4405677 के जवाब के अनुसार )।
- एक ही समय में कई डेवलपर्स के साथ एक शाखा पर काम करना, तो आपको संभवतः
git rebase
पहली जगह में उपयोग नहीं करना चाहिए । अद्यतन करने के लिए dev
से परिवर्तन के साथ master
आपको चाहिए, बजाय चल git rebase master dev
, रन git merge master
, जबकि पर dev
( जस्टिन जवाब के अनुसार )।
थोड़ा लंबा स्पष्टीकरण
जीआईटी में प्रत्येक कमिट हैश कई कारकों पर आधारित है, जिनमें से एक कमिट का हैश है जो इसके पहले आता है।
यदि आप फिर से करते हैं, तो आप प्रतिबद्ध हैश बदल देंगे; रिबासिंग (जब यह कुछ करता है) कमिट हैश को बदल देगा। इसके साथ, रनिंग का परिणाम git rebase master dev
, जहां dev
सिंक से बाहर है master
, उसी तरह की सामग्री के साथ नए कमिट (और इस तरह हैश) बनाएंगे, dev
लेकिन उन पर master
पहले से डाले गए कमिट के साथ ।
आप इस तरह की स्थिति में कई तरीकों से समाप्त कर सकते हैं। दो तरीके मैं सोच सकता हूँ:
- आप
master
अपने dev
काम को आधार बनाना चाहते हैं
- आप उस पर कमिट कर सकते हैं
dev
जो पहले ही किसी रिमोट पर धकेल दिया गया है, जिसे आप फिर से बदलने के लिए आगे बढ़ें (संदेशों को पुन: व्यवस्थित करें, फिर से शुरू करें, स्क्वैश कमिट करें, आदि)
आइए बेहतर समझते हैं कि क्या हुआ- यहाँ एक उदाहरण है:
आपके पास एक भंडार है:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0
फिर आप कमिट बदलने के लिए आगे बढ़ते हैं।
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(यह वह जगह है जहाँ आपको इसके लिए अपना शब्द लेना होगा: Git में कमिट्स को बदलने के कई तरीके हैं। इस उदाहरण में मैंने समय बदल दिया है C3
, लेकिन आप नए कमिट्स डाल रहे हैं, कमिट मैसेज बदल रहे हैं, कमिटिंग कर रहे हैं, एक साथ स्क्वैश करना, आदि)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0
यह वह जगह है जहां यह ध्यान रखना महत्वपूर्ण है कि प्रतिबद्ध हैश अलग हैं। यह अपेक्षित व्यवहार है क्योंकि आपने उनके बारे में कुछ (कुछ) बदल दिया है। यह ठीक है, लेकिन
धक्का देने की कोशिश आपको एक त्रुटि दिखाएगा (और संकेत है कि आपको चलना चाहिए git pull
)।
$ git push origin master
To git@bitbucket.org:username/test1.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
यदि हम चलते हैं git pull
, तो हम इस लॉग को देखते हैं:
7df65f2 (HEAD, master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 (origin/master) C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0
या, एक और तरीका दिखाया गया है:
और अब हमारे पास स्थानीय स्तर पर डुप्लिकेट कमिट हैं। अगर हम दौड़ते git push
तो हम उन्हें सर्वर तक भेज देते।
इस चरण में जाने से बचने के लिए, हम दौड़ सकते थे git push --force
(जहाँ हम इसके बजाय भागे थे git pull
)। इसने बिना किसी समस्या के नए हैश के साथ हमारे कमिट को सर्वर पर भेजा होगा। इस स्तर पर समस्या को ठीक करने के लिए, हम दौड़ने से पहले वापस रीसेट कर सकते हैं git pull
:
Reflog (देखो git reflog
) क्या प्रतिबद्ध हैश था देखने के लिए इससे पहले कि हम भाग गया git pull
।
070e71d HEAD@{1}: pull: Merge made by the 'recursive' strategy.
ba7688a HEAD@{2}: rebase -i (finish): returning to refs/heads/master
ba7688a HEAD@{3}: rebase -i (pick): C5
44085d5 HEAD@{4}: rebase -i (pick): C4
961390d HEAD@{5}: commit (amend): C3
3cb46a9 HEAD@{6}: cherry-pick: fast-forward
85f59ab HEAD@{7}: rebase -i (start): checkout HEAD~~~
2a2e220 HEAD@{8}: rebase -i (finish): returning to refs/heads/master
2a2e220 HEAD@{9}: rebase -i (start): checkout refs/remotes/origin/master
2a2e220 HEAD@{10}: commit: C5
ab1bda4 HEAD@{11}: commit: C4
3cb46a9 HEAD@{12}: commit: C3
85f59ab HEAD@{13}: commit: C2
4516164 HEAD@{14}: commit: C1
0e783a3 HEAD@{15}: commit (initial): C0
ऊपर हम देखते हैं कि ba7688a
दौड़ने से पहले हम कमिट थे git pull
। हाथ में उस हैश के साथ हम उस पर वापस रीसेट कर सकते हैं ( git reset --hard ba7688a
) और फिर चला सकते हैं git push --force
।
और हम कर रहे हैं।
लेकिन रुकिए, मैंने डुप्लिकेट किए गए कमिट्स के आधार को काम करना जारी रखा
यदि आप किसी भी तरह से यह नहीं देखते हैं कि कमिट डुप्लिकेट थे और डुप्लिकेट कमिट्स के ऊपर काम करना जारी रखने के लिए आगे बढ़े, तो आपने वास्तव में अपने लिए एक गड़बड़ बना दिया है। गड़बड़ का आकार डुप्लिकेट के ऊपर आपके द्वारा किए गए कमिट की संख्या के लिए आनुपातिक है।
यह कैसा दिखता है:
3b959b4 (HEAD, master) C10
8f84379 C9
0110e93 C8
6c4a525 C7
630e7b4 C6
070e71d (origin/master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0
या, एक और तरीका दिखाया गया है:
इस परिदृश्य में हम डुप्लिकेट कमिट्स को हटाना चाहते हैं, लेकिन उन कमिट्स को रखें जिन्हें हमने उनके आधार पर बनाया है - हम C6 को C10 के साथ रखना चाहते हैं। अधिकांश चीजों के साथ, इस बारे में जाने के कई तरीके हैं:
कोई एक:
- उस नई शाखा पर अंतिम डुप्लिकेट किए गए 1 ,
cherry-pick
प्रत्येक प्रतिबद्ध (C10 समावेशी के माध्यम से) पर एक नई शाखा बनाएं और उस नई शाखा को विहित के रूप में मानें।
- भागो
git rebase --interactive $commit
, जहां $commit
के लिए प्रतिबद्ध है पहले दोनों डुप्लिकेट करता करने के लिए 2 । यहां हम डुप्लिकेट के लिए लाइनों को एकमुश्त हटा सकते हैं।
1 यह कोई बात नहीं है जो दो की आप चुनते हैं, या तो ba7688a
या 2a2e220
काम ठीक।
2 उदाहरण में यह होगा 85f59ab
।
टी एल; डॉ
इस पर सेट advice.pushNonFastForward
करें false
:
git config --global advice.pushNonFastForward false