Kısa cevap
Koştuğunuz gerçeğini atladınız git push
, aşağıdaki hatayı aldınız ve ardından çalışmaya devam ettiniz 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'in yardımcı olmaya çalışmasına rağmen , 'git pull' tavsiyesi büyük olasılıkla yapmak istediğiniz şey değil .
Eğer sen:
- Bir "özellik dalı" veya "geliştirici dalı" üzerinde çalışma Tek başına üzerinde çalıştığınızda,
git push --force
yeniden ödeme sonrası taahhütlerinizle uzaktan kumandayı güncellemek için çalıştırabilirsiniz ( user4405677'nin cevabına göre ).
- Aynı anda birden fazla geliştiriciyle bir dalda çalışıyorsanız, muhtemelen
git rebase
ilk etapta kullanmamalısınız. Adresindeki dev
değişikliklerle güncellemek için , çalıştırmak master
yerine git rebase master dev
çalıştırmalısınız.git merge master
üzerinde iken dev
( Justin Yanıt başına kadar ).
Biraz daha uzun bir açıklama
Git'teki her kaydetme karması bir dizi faktöre dayanır ve bunlardan biri, kendisinden önce gelen kaydetmenin karmasıdır.
Kaydetmeleri yeniden sıralarsanız, kaydetme karmalarını değiştirirsiniz; yeniden sıralama (bir şey yaptığında) commit hash değerlerini değiştirir. Bunun üzerine, koşu sonucu git rebase master dev
, nerede dev
ile senkronize değildi master
yaratacak, yeni onlardan önce dev
eklenenler ile aynı içeriğe sahip (ve dolayısıyla hash'ler)master
.
Bunun gibi bir duruma birden çok şekilde girebilirsiniz. Düşünebileceğim iki yol:
- Üzerinde taahhüt alabilirdin
master
dev
Çalışmanızı temel almak istediğiniz
- Üzerinde taahhüt alabilirdin
dev
Önceden bir uzaktan kumandaya aktarılmış olan işlemlere sahip daha sonra bunları değiştirmeye devam edebilirsiniz (yeniden sözcük tamamlama mesajları, yeniden sırala kaydetme, squash kaydetme vb.)
Ne olduğunu daha iyi anlayalım — işte bir örnek:
Bir deponuz var:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0
Daha sonra taahhütleri değiştirmeye devam edersiniz.
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(Burada sözümü almanız gerekecek: Git'te commit'leri değiştirmenin birkaç yolu var. Bu örnekte, zamanını değiştirdim C3
, ancak yeni commit'ler ekliyor, commit mesajlarını değiştiriyor, commit'leri yeniden sıralayacaksınız. ezme birlikte taahhüt eder vb.)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0
Kaydetme karmalarının farklı olduğunu fark etmenin önemli olduğu yer burasıdır. Onlarla ilgili bir şeyi (herhangi bir şeyi) değiştirdiğiniz için bu beklenen bir davranıştır. Sorun değil, AMA:
İtmeye çalışmak size bir hata gösterecektir (ve koşmanız gerektiğine dair ipucu 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.
Koşarsak git pull
şu günlüğü görürüz:
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
Veya başka bir yol gösterildi:
Ve şimdi yerel olarak yinelenen taahhütlerimiz var. Eğer koşarsakgit push
olsaydık, onları sunucuya göndeririz.
Bu aşamaya gelmekten kaçınmak için koşabilirdik git push --force
(bunun yerine koştuğumuz yere git pull
). Bu, yeni karmalarla bizim taahhütlerimizi sorunsuz bir şekilde sunucuya gönderirdi. Bu aşamada sorunu çözmek için, koşmadan önce sıfırlayabiliriz git pull
:
Reflog (bak git reflog
karma oldu işlemek ne olduğunu görmek için) önce biz koştu 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
Yukarıda ba7688a
, koşmadan önce yaptığımız taahhüt buydu git pull
. Elimizdeki bu commit karması ile buna ( git reset --hard ba7688a
) geri dönebilir ve sonra çalıştırabiliriz git push --force
.
Ve bitirdik.
Ama bekle, yinelenen kayıtlardan yola çıkmaya devam ettim
Eğer taahhütlerin tekrarlandığını bir şekilde fark etmediyseniz ve tekrarlanan taahhütler üzerinde çalışmaya devam ettiyseniz, gerçekten kendinize bir kargaşa yaratmışsınızdır. Karmaşanın boyutu, kopyaların üzerinde sahip olduğunuz işlemlerin sayısı ile orantılıdır.
Bu neye benziyor:
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
Veya başka bir yol gösterildi:
Bu senaryoda, yinelenen taahhütleri kaldırmak, ancak onlara dayandırdığımız taahhütleri saklamak istiyoruz - C6'dan C10'a kadar tutmak istiyoruz. Çoğu şeyde olduğu gibi, bunu yapmanın birkaç yolu vardır:
Ya:
- Son çoğaltılan kayıtta yeni bir şube oluşturun 1 ,
cherry-pick
her kayıt (C6'dan C10'a kadar) bu yeni şubeye ve bu yeni dalı standart olarak ele alın.
- Çalıştırın
git rebase --interactive $commit
, her iki yinelenen $commit
kaydetmeden önceki kaydetme nerede 2 . Burada kopyalar için satırları tamamen silebiliriz.
1 İkisinden hangisini seçtiğiniz önemli değil, ya ba7688a
da 2a2e220
iyi çalışıyor.
2 Örnekte olacaktır 85f59ab
.
TL; DR
Set advice.pushNonFastForward
için false
:
git config --global advice.pushNonFastForward false