Uzak daldan birkaç işlem kalıcı olarak nasıl kaldırılır


490

Biliyorum bu tarihin yeniden yazılması kötü yada yada.

Ancak uzak şubeden birkaç taahhüt kalıcı olarak nasıl kaldırılır?


96
Evet, gerçekten kötü yada yada, ama bir nedenden dolayı favorim olmalıyım.
James Morris

44
Bunun aptalca olduğunu biliyorum, ancak bazen bok olur - giriş bilgilerini test etmek ve gerçek giriş kimlik bilgileri olan kodunuzda düz metin şifreleri kullanmak gibi. Ve
whoops

6
gerçek giriş bilgileri .. Evet bana bazı whoopos hatırlatıyor
Merhaba Evren


2
Bunun ne kadar tehlikeli olduğu ve asla nasıl yapılmaması gerektiği konusunda bu akademik spielden çok yoruldum. Git geçmişinden bir şeyler kaldırmak ve diğer geliştiricilerin çatışmaları / kırılması ile başa çıkmak için çok daha iyi olduğu zamanlar vardır. Gerçekten bu kadar basit. Bunu görmezden gelen insanlar muhtemelen hiçbir zaman bir sınıf ortamının dışında çalışmamışlardır.
ezmek

Yanıtlar:


368

Sen git reset --hardyerel şube size çalışma ağacı ve dizinden değişiklikleri kaldırmayı ve git push --forceuzaktan revize yerel şube. ( buradaki uzak dalı silip yeniden itmeyi içeren başka bir çözüm )

Bu SO yanıtı , özellikle insanlar kendi yerel depoları için uzak tarihe bağlıysa, böyle bir komutun tehlikesini göstermektedir.
İnsanları , man sayfasının UPSTREAM REBASE'DEN KURTARMA bölümüne yönlendirmeye hazır olmalısınız .git rebase


Git 2.23 (Ağustos 2019, dokuz yıl sonra) ile yeni komutu kullanırsınız git switch.
Yani: ( kaldırılacak taahhüt sayısı ile değiştirin )git switch -C mybranch origin/mybranch~n
n

Bu, endeksi ve çalışma ağacını, bir olduğu gibi geri yükleyecektir git reset --hard.


Garip. Bunu zaten denemiş gibi hissediyorum. Bazı yeniden basma ile birlikte - bir cazibe gibi çalışır. Teşekkürler.
Arnis Lapsa

7
@Arnis: mükemmel o zaman;) push --forceuzakta
VonC

Ben kullanılan BFG Repo-Cleaner taahhüt istedi ve kökeni iterek sert geçen etmek Sıfırlanmasını sonra, üzerinde orijinal dosya ile bir "isimsiz" şube ile beni terk bazı hassas verilerin, kurtulmak için, bütün (cezası gitti:
Rodrirokr

Taahhüdün URL'sinin hala canlı olduğuna dikkat edin (en azından bir süreliğine), bu yüzden birisinin taahhüdün URL'si varsa (tanrıya verdiniz, nedenini biliyorsa), koda erişebilecekler.
Mosh Feu

1
@MoshFeu True: git gcuzak tarafta her zaman yeterince sık çalıştırılmaz. Örneğin GitHub'da: twitter.com/githubhelp/status/387926738161774592?lang=es
VonC

248

Sadece kullanmayı unutmayınız last_working_commit_idolmayan bir çalışma geri alırken, taahhüt

git reset --hard <last_working_commit_id>

Bu yüzden istemediğimiz duruma sıfırlamamalıyız commit_id.

O zaman emin olun, uzak şubeye itmeliyiz:

git push --force

10
Mükemmel, zarif, en basit cevap. Hem uzak hem de yerel olarak ihtiyaç duyduğum son stab taahhüdüne döndüm
lauWM

2
Bu da yerel değişikliklerimi kaybetmeme neden oldu. Bunu beklemiyordum. Ama meh, repo çalışmak için kişisel şifrenizi taahhüt etmekten daha iyi.
Airwavezx

3
git stash ile yerel değişikliklerinizi kaydedebilirsiniz .... bazı şeyler yapın .... ve git stash pop (yerel değişiklikleriniz geri döndü)
MonTea

Bu bana "uzak: hata: hızlı ileri olmayan ref / kafa / master (ilk önce
çekmelisiniz

@Airwavezx ne git reset --hardyapması gerekiyor.
Luke

146

Önemli: "git push -f" üzerinde hangi dalları belirttiğinizden emin olun, aksi halde diğer dalları da değiştirebilirsiniz! [*]

Bu öğreticide gösterilen üç seçenek vardır . Bağlantının kopması durumunda, burada ana adımları bırakacağım.

  1. Tüm taahhüdü geri alma
  2. Son taahhüdü sil
  3. Taahhütleri listeden sil

1 Tüm taahhüdü geri döndür

git revert dd61ab23

2 Son taahhüdü sil

git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>

veya şube yerel olarak kullanılabiliyorsa

git reset HEAD^ --hard
git push <<remote>> -f

Burada + dd61 ... işlem karmanızdır ve git x ^ 'i x'in ebeveyni olarak ve + ise zorla hızlı haber verilmeyen bir itme olarak yorumlar.

3 İşlemi listeden silin

git rebase -i dd61ab23^

Bu açılır ve tüm taahhütlerin listesini gösteren bir editör açılır. Kurtulmak istediğinizi silin. Rebase'i bitirin ve repo yapmak için gücü zorlayın.

git rebase --continue
git push <remote_repo> <remote_branch> -f

5
"Git push <remote_repo> <remote_branch> -f" üzerinde hangi dalları belirttiğinizden emin olun yoksa yanlışlıkla diğer dalları da değiştirebilirsiniz!
Nigel Sheridan-Smith

Sadece 1. ve 2. adımlar işi yaptı ve orijinal soruyu yanıtladı. (Adım 3'ü çalıştırmayın)
Saad Benbouzid

Bunlar, atılacak adımlar değil, farklı senaryolar için seçenekler. Benim durumumda, etkileşimli rebase (Seçenek 3) aradığım şeyi yaptı.
Steve Blackwell

Yine de 3. adımı yapmak zorunda kaldım. Bu @Saad'ı neden çalıştırmıyorsun? Neyse ki benim <<uzaktan>> sadece varsayılan 'orijin' ve <remote_branch> varsayılan 'usta' idi
Bart

30

Örneğin, son 3taahhütleri silmek istiyorsanız , dosya sisteminden (çalışma ağacı) değişiklikleri kaldırmak ve yerel şubenizdeki geçmişini (dizin) işlemek için aşağıdaki komutu çalıştırın:

git reset --hard HEAD~3

Ardından, uzak dalı geçmişini yeniden yazmaya zorlamak için aşağıdaki komutu (yerel makinenizde) çalıştırın:

git push --force

Tebrikler! Hepsi tamam!

Bazı notlar:

İstediğiniz taahhüt kimliğini çalıştırarak alabilirsiniz.

git log

Sonra yerini alabilir HEAD~Nile <desired-commit-id>böyle:

git reset --hard <desired-commit-id>

Eğer dosya sisteminde değişiklikleri koruyup istiyorsanız sadece endeksi (tarih işlemek), kullanım değiştirmek --softgibi bayrak git reset --soft HEAD~3. Ardından, en son değişikliklerinizi kontrol etme ve tümünü veya bir kısmını tutma veya bırakma şansınız olur. İkinci durumda runnig git statuso zamandan bu yana değişen dosyaları gösterir <desired-commit-id>. --hardSeçeneği kullanırsanız , git statusyerel şubenizin uzak olanla tam olarak aynı olduğunu söyleyecektir. Eğer kullanmıyorsanız --hardne de --soft, varsayılan mod olduğu kullanılır --mixed. Bu modda git help reset:

Dizini sıfırlar ancak çalışma ağacını sıfırlamaz (yani, değiştirilen dosyalar korunur ancak kesinleştirme için işaretlenmez) ve güncellenmeyenleri bildirir.


10

Bu çok geç olabilir ama bana yardımcı olan havalı 'nükleer' seçenek. Temel olarak komutu kullanarak filter-branchtüm git geçmişiniz boyunca çok sayıda dosya üzerinde dosyaları kaldırabilir veya bir şeyi değiştirebilirsiniz.

En iyi burada açıklanmaktadır .


9
Çok geç değil. Benzer sorunları olan gezginler için yararlı olabilir :)
Arnis Lapsa

9

Bu blog gönderisine benzer şekilde pctroll'un cevabından sadeleştirme .

# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote

2
Benim için çalışıyor, teşekkürler. Ve uzak şube geçmişinden bir taahhüdü (örn. Pwd içerir) kalıcı olarak silmek istiyorum, bu nasıl?
Smiles

1
Benim için de işe yarıyor, ama Smiles ile aynı sorum var, kimsenin tarihteki taahhüdümü / saygılarımı görmek istemiyorum .. bunu nasıl kaldırırım?
Roberto Rodriguez

4

Bazen bu sorunu çözmenin en kolay yolu, kodun iyi olduğunu bildiğiniz yerden yeni bir şube yapmaktır. Ardından, daha sonra diğer taahhütleri kiraz seçmeniz gerektiğinde, hatalı şube geçmişini yalnız bırakabilirsiniz. Bu ayrıca hiçbir taahhüt geçmişini kaybetmemenizi sağlar.

Yerel errant şubenizden:

git log

şubenin olmasını istediğiniz kesin karmayı kopyalayın ve git günlüğünden çıkın

git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch

Şimdi tam istediğiniz gibi yeni bir şubeniz var.

Ayrıca, yeni şubenizde olmayan errant şubesinden belirli bir taahhüt tutmanız gerekiyorsa, ihtiyacınız olan belirli taahhüdü kiraz olarak seçebilirsiniz:

git checkout the_errant_branch
git log

İyi şubeye çekmeniz ve git günlüğünden çıkmanız gereken tek işlemin kesin karmasını kopyalayın.

git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied

Sırtını sıvazla.


çok kolay ve ölü ayaklı bir dalınız varsa kimin umurunda? yeni bir dal yap ve onunla iş yap!
Andrew Fox

Bu gerçekten mükemmel bir cevap. Kiraz toplama komisyonları yerine veya uzak dalı manipüle etmek yerine bunu yaptığım için mutluyum.
Magnilex

0
 git reset --soft commit_id
 git stash save "message"
 git reset --hard commit_id
 git stash apply stash stash@{0}
 git push --force
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.