Git tuşunu nasıl doğru şekilde zorlarım?


1274

Ben çıplak olmayan bir "ana" repo kurduk ve bilgisayarıma klonladım. Bazı yerel değişiklikler yaptım, yerel veri havuzumu güncelledim ve değişiklikleri uzaktan repoma geri gönderdim. İşler o ana kadar iyiydi.

Şimdi, uzak depodaki bir şeyi değiştirmek zorunda kaldım. Sonra yerel repoda bir şey değiştirdim. Uzak depodaki değişikliğin gerekli olmadığını fark ettim. Bu yüzden git pushyerel repodan uzak repoma denedim , ama şöyle bir hata aldım:

Geçmişinizi kaybetmenizi önlemek için, ileri sarma olmayan güncellemeler reddedildi. Tekrar basmadan önce uzaktan değişiklikleri birleştirin. Ayrıntılar için 'Hızlı ileri sarma hakkında not' bölümüne git push --helpbakın.

Muhtemelen bir

git push --force

yerel kopyamı uzaktaki değişikliklere zorlamaya ve aynı hale getirmeye zorlardı. Güncellemeyi zorlar , ancak uzak repoya geri döndüğümde ve bir taahhütte bulunduğumda, dosyaların eski değişiklikler (daha önce ana uzak repo'nun sahip olduğu) içerdiğini fark ettim.

Yanıtlardan birine yapılan yorumlarda belirttiğim gibi :

[Ben] zorlamayı denedim, ama değişiklikleri kaydetmek için ana sunucuya geri döndüğümde, eski aşamaları alıyorum. Böylece, i taahhüt ettiğinde depolar aynı değildir. Git tuşuna tekrar basmaya çalıştığımda da aynı hatayı alıyorum.

Bu sorunu nasıl düzeltebilirim?


4
Yakında (git1.8.5, 4. Çeyrek 2013) daha dikkatli bir git push -forceşekilde yapabileceksiniz .
VonC


6
Kendi cevabımda detay verdiğim gibi git push --force, gerçekten de zorlamayı zorlamanın başka bir geçerli yoludur ve dalları git push origin master --forceda Git'in varsayılanı ile itecektir push.default config settings, ancak hangi dalların özel olarak itildiği Git sürümleri arasında 2.0 sürümünden sonra 2.0 sürümüne göre farklılık gösterir.

2
git push --forcebugünlerde iyi çalışıyor, FWIW ...
rogerdpack

git push --force-with-leasedaha da iyi çalışır :), beklediğiniz durum olmadığı sürece bir dalı güncellemeyi reddedecektir. (bkz. developer.atlassian.com/blog/2015/04/force-with-lease )
spoorcc

Yanıtlar:


2308

Sadece yap:

git push origin <your_branch_name> --force

veya belirli bir deponuz varsa:

git push https://git.... --force

Bu, önceki işlem (ler) inizi silecek ve geçerli işleminizi zorlayacaktır.

Doğru olmayabilir, ancak bu sayfada tökezleyen biri varsa, basit bir çözüm isteyebileceklerini düşündü ...

Kısa bayrak

Ayrıca -fkısa olduğunu unutmayın --force, bu yüzden

git push origin <your_branch_name> -f

de çalışacak.


58
Bunun git push origin +masteryerine, hepsini zorlamadan birden fazla refspec'i itmenize izin veren kullanabilirsiniz .
nickgrim

5
Yanlışlıkla sadece git push --forceyaparsanız, ana şube (itme varsayılan davranışınıza bağlı olarak) karışıklık sona erebilir unutmayın .. Bu biraz .. .. biraz berbat ..: D
Jeewes

9
@ Git sürüm 2.0'dan başlayarak, varsayılan davranışı git push --forcetemel olarak, şu anda kullanıma alınmış dalı uzak sayaç parçasına zorlamaktır, bu nedenle ana dalı teslim aldıysanız, aynıdır git push origin master --force. 2.0'dan önceki Git sürümleri için varsayılan matchingayar olan ayarı kullanmanız farklı olacaktır push.default. tüm yerel şubeleri aynı ada sahip uzak olanlara matchingiter , bu yüzden zorlamak o zaman kesinlikle yapmak istediğiniz şey

@Jeewes Ancak Git 2.0 ile varsayılan değer daha güvenlidir veya en azından olduğundan daha tehlikeli değildir git push origin master --force.

2
push -f iyidir, ancak çoğu kurumsal depoda master için -f devre dışı bırakıldığı için master için tekrar kullanılmaz. merge -s oursbenim için çalıştı
mihai

247

Ve eğer push --forceişe yaramazsa yapabilirsiniz push --delete. Bu örnekte 2. satıra bakın :

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

Ama dikkat et...

Asla hiç bir kamu git geçmişine geri dönün!

Başka bir deyişle:

  • Hiçbir zaman forcehalka açık bir depoya basmayın .
  • Bunu ya da birini kırabilecek herhangi bir şey yapmayın pull.
  • Değil hiç Do resetveya rewritetarih a'da çekmemiş olabileceği repodaki .

Elbette bu kuralda bile son derece nadir istisnalar vardır, ancak çoğu durumda bunu yapmak gerekli değildir ve diğer herkese sorun yaratacaktır.

Bunun yerine bir geri dönüş yapın.

Ve halka açık bir repoya ittiğiniz şeylere daima dikkat edin . dönülüyor:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

Aslında, her iki orijinal HEAD ( geri ve kötü sıfırlamadan ) aynı dosyaları içerecektir.


güncellenmiş bilgi ve daha fazla argüman eklemek için düzenle push --force

İtme gücü yerine itme kuvveti ile kiralamayı düşünün, ancak yine de geri dönmeyi tercih edin

Başka bir sorun push --forcegetirebilir, birileri sizden önce bir şey ittiğinde, ancak zaten getirdikten sonra. Eğer zorlamak bastırırsanız rebased versiyonu artık olacak diğerlerinden işi yerine .

git push --force-with-leasegit 1.8.5'te tanıtılan ( sorudaki @VonC yorumu sayesinde ) bu özel sorunu çözmeye çalışır. Temel olarak, en son getirinizden beri uzaktan kumanda değiştirildiyse bir hata getirir ve itmez.

A'nın gerçekten push --forcegerekli olduğundan eminseniz , ancak yine de daha fazla sorunu önlemek istiyorsanız , bu iyidir . Ben varsayılan push --forcedavranış olması gerektiğini söyleyebilirim . Ama yine de a'yı zorlamak için bir bahane olmaktan çok uzak push. İnsanlar getirilen senin önce rebase hala olsaydı kolayca önlenebilir olan sorunların çok olacaktır döndürüldü yerine.

Ve git --pushörneklerden bahsettiğimiz için ...

Neden kimse zorla itmek ister ki?

@linquize yorumlarda iyi bir itme gücü örneği getirdi: hassas veriler . Aktarılmaması gereken verileri yanlış bir şekilde sızdırdınız. Yeterince hızlıysanız, üzerine bir itme zorlayarak "düzeltebilirsiniz"* .

*Veriler hala uzak olacak ayrıca bir yapmadıkça toplamak çöp veya bir şekilde temizleyin . Orada o olurdu başkaları tarafından yayılmış olması için belli bir potensiyel da getirilen zaten, ama fikir olsun.


1
Sorun, @rogerdpack, yapılabilir durumdaysa değil. Bu. Ancak büyük bir felaketle sonuçlanabilir. Ne kadar çok kişi yaparsa (zorla itme) ve kamuoyu deposundan ne kadar az güncelleme yaparsanız (o kadar az), felaket o kadar büyük olur. En azından bu depodan oluşan dünyayı parçalara ayırabilir !!! 111
cregox

3
Eğer hassas veri varsa, kuvvet itin
linquize

3
@Cawas: Sanırım depodaki hassas verileri kaldırmaya çalışıyorsanız, geçmişi yeniden yazmak istediğiniz anlamına geliyor. Geri döndürürseniz, hassas veriler önceki işlemde hala oradadır. Bununla birlikte, başka biri zaten depodan çekildiyse, yeniden yazma geçmişi hassas verilere erişmelerini engellemenize yardımcı olmaz - bu noktada zaten çok geç.
Stuart Golodetz

3
git push origin master --delete # do a very very bad bad thing git push origin master # regular pushBu aslında benim sorunumu mükemmel çözdü (sadece ben ve arkadaşım ile bir repo üzerinde). belki kamu depoları için yanlış ama özel bir depo için bu bir hayat kurtarıcı.
Can Poyrazoğlu

1
bu otomatik olarak bazı repo yöneticileri, yani otomatik squash vb. ile gerçekleşir.
FlavorScape

18

Her şeyden önce, doğrudan "ana" depoda herhangi bir değişiklik yapmazdım. Gerçekten bir "ana" repoya sahip olmak istiyorsanız, sadece ona itmelisiniz, asla doğrudan değiştirmeyin.

Karşılaştığınız hata ile ilgili git pullolarak, yerel repodan ve ardından git pushana repoya mı denediniz ? Şu anda (iyi anladıysam) yaptığınız şey, itmeyi zorlamak ve daha sonra "ana" repodaki değişikliklerinizi kaybetmektir. Önce değişiklikleri yerel olarak birleştirmelisiniz.


evet çekmeyi denedim ama veri çekme nedeniyle veri kaybediyorum. Ana depolarımı yerel olarak ilk önce güncellemeden yapmak istiyorum.
Spyros

1
Bu durumda kullanın git push -f, ancak daha sonra ana repo'nuzu tekrar değiştirirseniz, yerel repoma geri dönmeniz gerekir ve git pullböylece en son değişikliklerle senkronize olur. Sonra işinizi yapabilir ve tekrar itebilirsiniz. Bu "push-pull" iş akışını izlerseniz, şikayet ettiğiniz türde bir hata elde edemezsiniz.
ubik

Evet, bu benim hatam olduğunu anlıyorum: / Ben bunu denemek ve bir süre sonra geri almak thanx
Spyros

1
zorlamayı denedim, ama değişiklikleri kaydetmek için ana sunucuya geri dönerken, eski aşamaları alıyorum. Böylece, i taahhüt ettiğinde depolar aynı değildir. Git tuşuna tekrar basmaya çalıştığımda da aynı hatayı alıyorum.
Spyros

17

Yerel şubem A'dayım ve yerel şubeyi (CI) başlangıç ​​şubesine zorlamak istiyorsanız aşağıdaki sözdizimini kullanabilirsiniz:

git push --force origin B:C

2
Yerel şubemde bile olduğumu öğrendim, yine de yapmam gerekiyor git push --force origin B:C. Benim durumumda, git push --force origin Cşu anda hangi şubede olduğumdan bağımsız olarak sadece yerel master'dan uzak C şubesine itilecek gibi görünüyor . git version 2.3.8 (Apple Git-58)
Weishi Zeng

12

şu komutu kullanın:

git push -f origin master

1
Belki de bu cevabın neden diğerlerine niçin tercih edileceği ve neyi farklı kıldığı hakkında daha fazla açıklama yapabilirsiniz.
Adam

Rahatsızlık için özür dilerim, aynı sorunu yaşıyordum ve bu komut onu çözdü, paylaşmam gerektiğini düşündüm.
mustafa Elsayed

12
Diğerleri ile aynı, sadece -fbayrağın konumunu değiştirdin ...
svelandiag

11

Gerçekten tavsiye ederim:

Başka bir deyişle, çekilecek / çekilecek tek bir yukarı akış deposuna sahip olmak için hem ana sunucudan hem de yerel bilgisayardan çıplak bir repo erişilebilir olmalıdır.


5

Bu, geçmişi korurken kurumsal bir gitHub deposundaki ustayı değiştirmek için çözümümüzdü.

push -fşirket havuzlarında uzmanlaşmak şube geçmişini korumak için genellikle devre dışıdır. Bu çözüm bizim için çalıştı.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

şubenizi zorlayın desiredOriginve bir PR oluşturun


3

Aynı soruyu sordum ama sonunda anladım. Büyük olasılıkla yapmanız gereken aşağıdaki iki git komutunu çalıştırmaktır (hash yerine git commit revizyon numarası):

git checkout <hash>
git push -f HEAD:master
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.