Dosyaları depodan silen bir Git birleştirmeyi geri almanın en iyi yolu nedir?


13

Öyleyse aşağıdakileri hayal edin (ve hepimiz SourceTree'yi kullanıyoruz):

  1. Hepimiz kökeni / gelişimi üzerinde çalışıyoruz.
  2. Bir hafta tatile giderim.
  3. İş arkadaşım, kökeni birleştirmeden / yerel gelişim şubesine geri gelişmeden son birkaç gündür yerel olarak çalışıyor.
  4. Bir itme yapmaya çalışır, önce birleştirmesi gerektiği söylenir ve sonra bir çekiş yapar.
  5. Birleşme sonrası otomatik taahhüdün devam etmesini durdurarak bir çatışma yaşar.
  6. Git'in SVN gibi olduğunu varsayarsak, iş arkadaşım çalışma kopyasındaki "yeni" dosyaları atar ve birleştirme işlemini yapar - bu "yeni" dosyaları başlangıç ​​/ geliştirme başından siler.
  7. Bu revizyonun üstünde bir haftalık geliştirme çalışmaları devam ediyor.
  8. Tatilden geri dönüyorum ve işimin birkaç gününün eksik olduğunu öğrendim.

Git için çok yeniyiz (bunu kullanan ilk projemiz), ama düzeltmek için yaptığım şey şuydu:

  1. "Develop" ifadesini "develop_old" olarak yeniden adlandırın.
  2. Develop_old öğesini "develop_new" adlı yeni bir dalda birleştirin.
  3. Develop_new dalını, birleştirme işleminden önceki son işleme sıfırlayın.
  4. Cherry o zamandan bu yana her bir taahhüdü seçer ve çatışmaları elle çözer.
  5. Develop_old ve develop_new öğelerini başlangıca kadar itin.

Bu noktada, develop_new, umarım, sonraki hafta değerinde çalışmaların yeniden uygulanmasıyla tüm değişikliklerin "iyi" bir kopyasıdır. Ayrıca, "ters işlemenin" birleştirme üzerinde tuhaf şeyler yapacağını varsayıyorum, özellikle de önümüzdeki birkaç hafta değerinde çalışmalara dayandığı için - ve bu birleştirme, yapmadığımız şeylerle birlikte istediğimiz çok şey içerdiğinden t.

Bunun bir daha asla gerçekleşmeyeceğini umuyorum, ancak tekrar olursa, işleri düzeltmenin daha kolay / daha iyi bir yolunu bilmek isterim. Bu birleşmeye dayalı olarak repoda çok fazla çalışma olduğunda "kötü" bir birleştirme işlemini geri almanın daha iyi bir yolu var mı?


1
Git ağacının ekran görüntüsünü (uygun şekilde redaksiyona tabi tutulmuş) veya favori git logformatınızın çıktısını çeşitli taahhütlerde neler olduğuna dair uygun ek açıklamalarla gönderebilir misiniz ? ( git log --graph --pretty=oneline --abbrev-commit

1
Sizin için çok geç, ancak birim testleri bunu yakalardı.
nalply

1
@nalply: Bozuk birleştirme birim sınamalarını da sildiyse olmaz.
Aaronaught

Vay be, bu gerçekten sinsi kötü şans.
nalply

Yanıtlar:


6

Doğru anladıysam, bu senin durumun:

    ,-c--c--c--c--M--a--a--X ← develop
o--o--y--y--y--y-´

Bazı ortak tarihlerden sonra (o) işinizi taahhüt ettiniz (y). İş arkadaşınız (c) yerel deposu üzerinde çalıştı ve kötü birleşme (M) yaptı. Daha sonra M'nin üstünde bazı ek taahhütler (a) olabilir.

git reset --hard develop M^2
git branch coworker M^1

Şimdi grafiğiniz kötü birleşmeden önceki gibi görünüyor:

    ,-c--c--c--c ← coworker
o--o--y--y--y--y ← develop

İyi bir birleştirme yapın (G):

git checkout develop
git merge coworker

Sonuçlanan:

    ,-c--c--c--c-、
o--o--y--y--y--y--G ← develop

Şimdi ek taahhütleri nakledin:

git reset --hard X
git rebase --onto G M develop

Bu nihai sonucu verir:

    ,-c--c--c--c-、
o--o--y--y--y--y--G--a--a--X ← develop

Bunun daha fazla birleşme çatışmasına neden olabileceğini unutmayın. Ayrıca sadece geçmişi değiştirdiniz, yani tüm iş arkadaşlarınız yeni tarihe klonlama / sıfırlama / yeniden basma.

Not: Tabii ki değiştirmeniz gerekir ait G, Mve Xtaahhüt gelen id ederek komutları içinde.


Bu taahhütlerin hepsinin zaten paylaşılan bir depoya itildiği soruda oldukça açık görünüyor, bu yüzden yeniden basmanın iyi bir seçim olduğunu düşünmüyorum. Son taahhütlerin hepsini geri almak ve daha sonra, çatışmasız olanları iyi birleşmenin üzerine almak daha güvenlidir.
Aaronaught

Bu klon / reset / rebase olan bölümdü. - Yalnızca birkaç geliştirici varsa, depolarını güncellemelerini söylemek geçerli bir seçenek olabilir.
michas

1

Depoyu nasıl düzelteceğinizi düşünmeniz iyidir, ancak iş arkadaşınız sadece yeni dosyaları silmiş ve çok fazla güncellemenin üzerine yazmamışsa, silinen dosyaları geri yüklemek çok daha basit bir yaklaşım olacaktır.

Muhtemelen şimdi mevcut kaybolan kodu eklediğiniz orijinal taahhütleri sadece kiraz almaya çalışarak başlayabilirdim. Herhangi bir nedenle işe yaramazsa, eklediğiniz dosyalarla eski düzeltmeyi kontrol edin ve yeni bir taahhütte tekrar ekleyin.

Tarif ettiğiniz şey aslında benim adıma hatırlayamadığım, iyi bilinen Git anti-deseninin bir alt kümesidir - ama bunun özü, Git birleştirme sırasında herhangi bir "manuel düzenleme" yapmaktır (yani, düzenlemeler) aslında birleştirme çakışmalarını çözmeyen ancak tamamen alakasız bir değişiklik yapan) son derece kötü bir uygulama olarak kabul edilir, çünkü bunlar esas olarak birleştirme tarafından maskelenir ve kod incelemelerinde veya hata ayıklama oturumlarında kolayca göz ardı edilir.

Bu yüzden iş arkadaşınıza bunun destansı bir başarısızlık olduğunu kesinlikle açıklayın, ancak büyük bir ameliyat için hazırlanmadan önce yara bandı üzerine tokatlamayı düşünün.


Katılıyorum, eğer tüm dosyaların tamamı ise, eski dosyalarda geçmişi umursamıyorsanız, yapabileceğiniz bir şey varsa: 1. şu anda dağınık daldan yeni bir dal yapın. 2. kötü şubeye geri dönün ve kurtarma şubeniz olan başka bir yeni dal yapın 3. Kurtarma şubenizden başarısızlıktan önce taahhüdüne geri dönün. 4. Silinen dosyaları git 5 ​​dışında bir yere kopyalayın. Diğer yeni dala geçin. 6. Silinen dosyaların yeni sürümlerini yeni şubeye kopyalayın ve tamamlayın. Linus T. tarafından ünlü bir yazı olan tarihi kurtarmanın daha karmaşık bir yolu var
Elin

1
Aslında bu, kasayı nasıl kullanabileceğinizi gösterir jasonrudolph.com/blog/2009/02/25/… Bu çok daha hoş.
Elin
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.