Hatalı bir git push -f kaynak yöneticisinden nasıl kurtarabilirim?


Yanıtlar:


55

Git genellikle hiçbir şeyi atmaz, ancak bundan kurtulmak yine de zor olabilir.

Doğru kaynağa sahipseniz, --forceseçenekle onu uzaktan kumandaya itebilirsiniz . Git, siz söylemedikçe hiçbir dalı silmiş olmayacak. Gerçekleştirmeleri gerçekten kaybettiyseniz, taahhütleri kurtarmak için bu yararlı kılavuza bir göz atın . İstediğiniz taahhütlerin SHA-1'ini biliyorsanız, muhtemelen iyisinizdir.

Yapılacak en iyi şey: Her şeyi yedekleyin ve yerel deponuzda neler olduğunu görün. Mümkünse uzaktan kumandada aynısını yapın. Bir git fsckşeyleri kurtarıp kurtaramayacağınızı görmek için kullanın ve her şeyden önce ÇALIŞMAYINgit gc .

Her şeyden önce, --forcegerçekten, gerçekten kastetmediğiniz sürece bu seçeneği asla kullanmayın .


65
Uzak dalların başlangıçta nerede olduğunu belirlemek için büyük olasılıkla sadece yeniden bloglara bakabilirsiniz. Örneğin git reflog show remotes/origin/master,. Orada itişinizi görebilmelisiniz; önceki satırdaki commit, siz onu karıştırmadan önceki yeridir. Daha sonra bu düzeltmeyi (ile --force) başlangıç ​​noktasına itebilir ve bulunduğunuz yere geri dönebilirsiniz!
Cascabel

@David: Oh. Sorunuzda deponun olmadığını söylemediniz. (Bu elbette asla yapmak istemeyeceğiniz bir şeydir.) Eğer zorladığınız dosya sistemi erişiminiz varsa, yine de tüm bunları orada yapabilirsiniz.
Cascabel

1
@David: Eyvah. Bu tür şeylerden kaçınmak için mevcut dizininizin isteminizin bir parçası olması her zaman iyidir.
Cascabel

1
@Jefromi Sanırım söylediklerinizin gerçek yanıtı var: Eski bir sürümle bile ( git fetchuzun süredir kullanmıyorsanız) GitHub'ın tarafının reflogunu görüntüleyebilir ve kurtarabilirsiniz!
nh2

1
@Jefromi'nin bu cevabı nerede? Bu kullanıcının bu yorum dizisinin dışında bu sayfada bahsettiğini görmüyorum.
Don McCurdy

47

Kaydetme karmasını biliyorsanız, kolaydır, dalınızı yeniden oluşturmanız yeterlidir.

5794458...b459f069 master -> master (forced update)

Uzak dalı silin:

git push origin :master

ardından aşağıdaki komutlarla dalınızı yeniden oluşturun:

git checkout 5794458
git branch master
git push origin master

28

Çözüm burada zaten belirtilmiştir

# work on local master
git checkout master

# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}

# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)

# finally, push the master branch (and only the master branch) to the server
git push -f origin master

Teşekkür ederim, bu benim için çalıştı. Ana silmeye erişimim olmadığı için onaylanan yorum başarısız oldu.
Andi

Evet ve git reflog show remotes/origin/mastergit reflog gerekliyse (yukarıda @Cascabel tarafından belirtildiği gibi)
Josiah Yoder

2
Doğru cevap bu, doğru cevaba bağladığınız için teşekkürler.
Noitidart

6

Zorunlu itmenin geldiği yerel depoda değilseniz, kaynak / ana düzeyde kurtarmanın bir yolu yoktur. Ancak GitHub veya GitHub for Enterprise'ı kullanacak kadar şanslıysanız , REST API'ye bir göz atabilir ve kayıp kaydı yama olarak geri alabilirsiniz, örneğin:

  1. Olayları listeleyin ve commit sha1 uzun formatını bulun

https://api.github.com/repos/apache/logging-log4j2/events

  1. Kayıp kaydı indirin ve ilgili yamayı json yolunda .files [] / patch

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. Yerel olarak uygulayın ve tekrar itin

git uygula patch.patch && git commit -m "geri yüklenen commit" && git itme kaynak yöneticisi


4

Kaybedilen taahhüdü kurtarmanın veya hatta önceki itme yerel deponuzdan gelmediyse, hangi taahhütlerin kaybedildiğini anlamanın bir başka yolu da CI makinenize bakmaktır.

Sahip olmanız gereken her işlemden (veya ardışık işlemlerden) sonra ana dalı test eden bir işiniz varsa, en son neyi test ettiğine bir göz atabilirsiniz. Geri yüklemeniz gereken taahhüt budur.

CI makinesi, bu kurtarmayı gerçekleştirebileceğiniz reponun yerel bir klonunu bile tutabilir.

Kaynak: Muhtemelen Sürekli Teslimat: Derleme, Test ve Dağıtım Otomasyonu aracılığıyla Güvenilir Yazılım Yayınları (Addison-Wesley Signature Series (Fowler))


3

Evet, daha sonra taahhütleri kurtarabilirsiniz git push -f your_branch

Dokümandan Metin :

Belirtilen süreden daha eski girdileri budayın. Bu seçenek belirtilmezse, sona erme süresi varsayılan olarak 90 gün olan gc.reflogExpire yapılandırma ayarından alınır. --expire = yaşlarına bakılmaksızın tüm girişleri kuru erik; --expire = ulaşılabilir girdilerin budamasını asla kapatmaz (ancak --expire-unreachable'a bakın).

Böylece şunları yapabilirsiniz:

1- git reflog

görüntü açıklamasını buraya girin

2- Head_Number'ı seçersiniz, kurtarmak ister misiniz? git reset –hard HEAD@{HEAD-NUMBER}

görüntü açıklamasını buraya girin

3- Bu kafadaki tüm kayıtları şu şekilde görebilirsiniz: git cherry -v branch_name

4- Sonunda zorlamalısın git push -f branch_name

VEYA

1- SHA numarasını GIT istemcinizden (arayüz) alın

git reset --hard commit_SHA

2- zorla itme

git push -f your_branch

Bu yardımcı olur umarım


2

Sadece bir dosya için son bir itmeyi geri alırken aynı şeyi yaptım. Deponun orijinal durumuna geri dönme işlemi sona erdi. Linux'ta yerel kopyaya sahip olduğum için Linus'tan git komutlarını kullanıyordum. Neyse ki bu kopya hâlâ sağlamdı.

Tek yaptığım (çılgınca yerel depodan birkaç kopya çıkardıktan sonra):

git add .
git status

(menşe / ustanın 68 kaydetme ile önde olduğunu söyledi, iyi ... bunlar sildiğim işlemlerin hepsi idi)

git remote set-url origin <GIT_SSH_URL>
git push

Ve her şey, ben zorla bastırmadan önceki haline geri döndü. Hatırlanması gereken en önemli şey, asla ödeme yapmamaktır. zorla ittikten sonra. Ancak en iyi uygulama, push seçeneğini devre dışı bırakmaktır. Bir daha asla kullanmayacağım. Dersimi öğrendim !!


1

Benim gibi gerçekten kötü durumda olan insanlar için (örneğin, bad objectkoşarken hata alıyorsanız git reset --hard):

Son çare olarak tüm dosyalarınızı GitHub API'sinden çeken treeaver adlı bir komut dosyası yazdım . İşte nasıl kullanılacağı:

  1. Klon treesaversenaryo ve cdbuna.
  2. SHAErişerek geri yüklemek istediğiniz ağacın dizesini bulun https://api.github.com/repos/<your_username_or_org>/<repo>/events.
  3. In payloadsizin itme etkinliğine karşılık gelen özelliği, bulmak commitsize dönmek ve onun üzerine tıklayın istiyorum url.
  4. Altında commit.tree, tree's kopyalayın url.
  5. Çalıştır python3 main.py <tree_url> <path_to_save_to>.

Örneğin, benim durumumda şunu çalıştırırdım:

python3 main.py https://api.github.com/repos/anthonykrivonos/my-repo/git/trees/1234567 .

Tabii ki, halkla ilişkiler hoş geldiniz.


0

Burada kararları okuyabilirsiniz https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

İkincisi bana yardım etti. Bu komutları yanlış yaptım

1) (some-branch) git pull -> correct command was git pull origin some-branch

2) (some-branch) git push -f origin some-branch

Bu komutlardan sonra üç commit kaybettim. Onları kurtarmak için yanlış bir şekilde 'git pull' yaptığım terminale baktım ve orada şöyle çıktı gördüm

60223bf ... 0b258eb bir-dal -> kökeni / bir-dal

İkinci hash 0b258eb tam da ihtiyacım olan şeydi. Ben de bu hash'i aldım ve komut verdim

git push --force origin 0b258eb:some-branch
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.