"Git push" u geri alma


591

İşte kararlı olması gereken dalımda yaptığım şey ...

% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

Daha sonra fark ettiğim gibi bunların hepsi bir hataydı. Tüm bu süreci geri almak ve alfa-0.3.0 dalını eski haline döndürmek istiyorum.

Ne yapmalıyım?



4
Bu gerçekten aynı durum değil, bir rebase'i geri almak yerel bir depo senaryosudur, bir git push'u geri almak uzak bir depoyu içerir ve sahip olduğunuz erişime bağlı olarak daha zor olabilir.
CB Bailey

Steen - haklısın - muhtemelen sanmalıyım. Tüm çektiği mübarek havuzun daha çok bir yönetici görevi olduğunu ve genel istemci tarafı git'in yığın akışı sorusu olduğu buraya ait olduğunu düşündüm.
Cyrus

Hızlı açıklama - Git kısmi bir karma değeriyle git komutuna başvurursanız , git, hash bu dize ile başlayan komuttan bahsettiğinizi varsayacaktır?
Gershom

Yanıtlar:


943

Bu depodaki diğer kullanıcıların yanlış değişiklikleri getirmediğinden veya geçmişi geri almak üzereyken kaldırılmasını istediğiniz taahhütlerin üstüne oluşturmaya çalışmadığınızdan emin olmanız gerekir.

O zaman eski referansı 'zorlamanız' gerekir.

git push -f origin last_known_good_commit:branch_name

ya da senin durumunda

git push -f origin cc4b63bebb6:alpha-0.3.0

receive.denyNonFastForwardsUzak depoda ayarlamış olabilirsiniz . Bu durumda, ifadeyi içeren bir hata alırsınız [remote rejected].

Bu senaryoda, dalı silmeniz ve yeniden oluşturmanız gerekir.

git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

Bu işe yaramazsa - belki de receive.denyDeletesayarladığınız için, depoya doğrudan erişiminizin olması gerekir. Uzak depoda, aşağıdaki sıhhi tesisat komutu gibi bir şey yapmanız gerekir.

git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8

16
Mükemmel ve iyi açıklanmış bir yanıt - çok teşekkür ederim. Bunun karşısında tökezleyen herkes için, akademik nedenlerden dolayı her iki ilk yaklaşımı da denedim ve her ikisi de çalıştı - açık bir şekilde işe yararsa, en temiz yaklaşım. Seni 10 kez Charles'a koyabilirsem, yapardım. :)
Cyrus

139
Hızlı başvuru için, buradaki ilk satırgit push -f origin last_known_good_commit:branch_name
philfreo

5
git push -f kökenli cc4b63bebb6: alpha-0.3.0 => bu bana yardımcı oldu, Not alpha-0.3.0 şube adı ve cc4b63bebb6 geri dönmek istediğimiz taahhüt kimliği. yani, bu komutu yerine getirdikten sonra cc4b63bebb6 taahhüt kimliğine gireceğiz.
kumar

22
Paylaşılan bir depoda çalışıyorsanız bu çözüm son derece tehlikelidir. En iyi uygulama olarak, paylaşılan bir repoya itilen tüm taahhütler 'değişmez' sayılmalıdır. Bunun yerine 'git
revert

1
jww - git her şeye kıyasla mevcut en zengin özellikli ve verimli kaynak kontrol aracıdır. Her takım bunu farklı kullanır. Bir haftasonunu yeni bir depoyla oynayarak ve tüm ortak senaryoları gözden geçirmeye değer. Bununla çalışmak için biraz zaman harcadığınızda, geliştirme çok daha az streslidir.
user1491819

165

Bunu da yapabileceğine inanıyorum:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

Bu son yönteme çok benzer, ancak uzak depoda uğraşmak zorunda değilsiniz.


9
Bu benim için de işe yaradı, ancak bunun uzaktan kumandanın tarihini "yeniden yazacağını" belirtmek gerekir. İstediğiniz bu olabilir, ama olmayabilir!
Tom

3
Bana gerçekten yardımcı olan bu cevap için +1. Ayrıca (" --hard" parametresinden sonra gelen) taahhüt kimliğinin şubenizi sıfırlamak istediğiniz herhangi bir taahhüdün kimliği olması gerektiğini eklemek (ve işleri netleştirmek) istedim .
Michael Dautermann

1
Tarihi güzelce yeniden yazdım ... değişiklikleri çekmiş olabilecek herkes, sadece bir zaman yaptıklarından emin oldum, git reset --hard [commit_id]böylece uzay-zaman sürekliliğiyle uğraşmadık.
Alien Life Form

9
"Git push origin + alpha-0.3.0" içindeki + ne işe yarıyor?
jpierson

1
@jpierson +, basmaya benzer şekilde gerçekleşmeye zorlar -f(ancak biraz farklı: stackoverflow.com/a/25937833/1757149 ). Denersen Onsuz git push origin alpha-0.3.0itme başarısız olur: Updates were rejected because the tip of your current branch is behind.
A__

106

git revert burada önerilen yaklaşımlardan daha az tehlikelidir:

prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert "Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

35f6af6f77f116ef922e3d75bc80a4a466f92650'yi kendi taahhüdünüzle değiştirin.


2
35f6af6f77f116ef922e3d75bc80a4a466f92650 ID ile nasıl gelirim? Bunu açıklayabilirsen bu cevap daha iyi olurdu.
Volomike

2
@Volomike (ve geleceğin Googling geliştiricileri), bu soru bunu elde etmenin birçok yolunu açıklıyor: SO
Jaime

Bu doğru cevaptır, çünkü "git reset" ile itemezsiniz (güncel şubenizin ucu uzaktaki karşılığının arkasında olduğu için güncellemeler reddedildi) veya gerçekten temiz olmayan çekmeyi zorlamanız gerekiyor.
Thomas Decaux

Bu benim için çalışıyordu. Ancak, geri alma yerel dosyalarınızdaki tüm değişiklikleri geri alacağından dikkatli olun.
user1941537

Bu yaklaşımı birçok kez seçtim, ancak interaktif bir rebase yapmak ve burada önerildiği gibi geçmişi temizlemek için git rebase -i <id-before-last-good-commit> kullanıyorum, stackoverflow.com/questions/5189560/… .
Ernesto Allely

35

Paylaşılan bir depoda çalışıyorsanız, kabul edilen çözüm (@charles bailey'den) oldukça tehlikelidir.

En iyi uygulama olarak, paylaşılan bir repoya itilen tüm taahhütler 'değişmez' sayılmalıdır. Bunun yerine 'git revert' kullanın: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things


Tam olarak reçete ettiğiniz talimatlar nelerdir? Sadece eski bağların var gibi görünüyor.
jww

32

İstediğiniz değişiklikleri kaybetmeden bunu yapmanın bir yolu:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

Sonra itmek istediğiniz dosyaları seçebilirsiniz


19

Bunu yapmanın başka bir yolu:

  1. başka bir şube oluştur
  2. "git checkout" kullanarak o daldaki önceki taahhüdü kullanıma alma
  3. yeni dalı itin.
  4. eski şubeyi sil ve sil tuşuna bas (kullan git push origin --delete <branch_name>)
  5. yeni dalı eski şubeye yeniden adlandır
  6. tekrar itin.

2


11

Birden çok işlemi geri alma git reset --hard 0ad5a7a6 (Sadece SHA1 karmasını sağla)

Son taahhüdü geri al

git reset --hard HEAD ~ 1 (son işleme değişiklikleri kaldırılacak) git reset --soft HEAD ~ 1 (son işleme değişiklikleri değişiklik yapılmayan yerel değişiklikler olarak sunulacak)


9

Senaryo 1 : 8123b7e04b3 adlı son taahhüdü geri almak istiyorsanız, komut aşağıdadır (bu benim için çalıştı):

git push origin +8123b7e04b3^:<branch_name>

Çıktı aşağıdaki gibi görünür:

Total 0 (delta 0), reused 0 (delta 0)
To https://testlocation/code.git
 + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

Ek bilgi: Senaryo 2 : Bazı durumlarda, önceki komut aracılığıyla geri aldığınız şeyi (temelde geri alma) geri almak ve sonra aşağıdaki komutu kullanmak isteyebilirsiniz:

git reset --hard 8123b7e04b3

Çıktı:

HEAD is now at cc6206c Comment_that_was_entered_for_commit

Daha fazla bilgi için: https://github.com/blog/2019-how-to-undo-almost-anything-with-git


Soru hangi silme taahhüdünü belirtmediği için Senaryo 1 kabul edilen yanıtı vermelidir. Kabul edilen cevap yalnızca son taahhüdü siler . Bu cevap tüm taahhütleri siler .
Dominic Cerisano

0

Mevcut cevaplar iyi ve doğrudur, ancak ya geri almanız gerekiyorsa push:

  1. Taahhütleri yerel olarak tutmak veya taahhüt edilmemiş değişiklikleri tutmak istiyorsunuz
  2. Kaç tane taahhütte bulunduğunu bilmiyorsun

Ref'deki değişikliği geri almak için bu komutu kullanın:

git push -f origin refs/remotes/origin/<branch>@{1}:<branch>

-2

Uzak dalı ittiğiniz son taahhüdü göz ardı etmek istiyorsanız: bu, taahhüdü kaldırmaz, yalnızca git işaretçisini daha önce HEAD ^ veya HEAD ^ 1 tarafından atıfta bulunarak gidiciye taşıyarak yok sayar.

git push origin +HEAD^:branch

Ama bu taahhüdü zaten ittiyseniz ve diğerleri şubeyi çekti. Bu durumda, şubenizin geçmişini yeniden yazmak istenmeyen bir durumdur ve bunun yerine bu taahhüdü geri almalısınız:

git revert <SHA-1>
git push origin branch

1
Evet! github ile çalışırken bu bir cazibe gibi çalıştı. Teşekkürler.
cukabeka

Soru "itme" ile ilgili o zaman Uzak dalı ile ilgilidir. Hayır HEAD bir taahhüt hakkında hareket ettirilen anlamına gelir, yani son taahhüt yok sayılır sadece bunu yapın: git push origin + HEAD ^: your_branch
mkebri
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.