Ana içeriğe geç

Git Revert Merge Commit: Örneklerle Bir Rehber

Commit geçmişini koruyarak ve olası çatışmaları çözerek `git revert` ile bir Git birleştirmesini güvenle geri almayı öğrenin.
· 7 dk. oku

Yapay Zeka ile Keşfedin

Tamamlanmamış çalışmayı yanlışlıkla ana dala entegre etmek ya da otomatik testlerden kaçan kritik bir hatayı gözden kaçırmak gibi nedenlerle sorunlu kodu birleştirirsek bir uygulamayı riske atabiliriz.

Bu yazıda, commit geçmişini koruyup projenin bütünlüğünü sağlayarak bir birleştirmeyi güvenle geri almak için git revert kullanımını adım adım göstereceğim.

git revert Nasıl Çalışır

git revert komutunu, Git’in geri al komutuna benzetebiliriz. Ancak git revert commit’leri silmez ya da dalın önceki bir durumuna atlamaz. Bunun yerine, belirli bir commit’in yaptığı değişiklikleri geri alan yeni bir commit oluşturur.

git revert nasıl çalışır görseli

<commit_hash> özetine sahip bir commit’i geri almak için sözdizimi:

git revert <commit_hash>

git log komutunu kullanarak commit’leri özetleriyle birlikte listeleyebiliriz. git log çıktısı commit’leri en güncelden en eskiye doğru şöyle listeler:

git log ile commit özetini bulma

Örneğin, çıkarma fonksiyonunu (subtract) uygulayan commit’i geri almak için şu komutu kullanırdık:

git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151

git revert kullanarak belirli bir commit’in değişikliklerini, commit geçmişini etkilemeden geri alabiliriz.

git revert sihirli değildir; commit geçmişine bağlı olarak elle çözülmesi gereken çatışmalar ortaya çıkabilir.

Elle Değişiklik Yapmaya Kıyasla git revert Avantajları

Elle çatışma çözmemiz gerekebilecekse git revert neden faydalı? Değişiklikleri elle geri almak daha kolay değil mi? Avantajlarına bakalım:

  • Geçmişi korur: git revert, belirtilen commit’in değişikliklerini geri alan ve tüm commit geçmişini koruyan yeni bir commit yaratır. Bu, değişikliklerin ve geri almaların şeffaf bir geçmişini sürdürmeye yardımcı olur.
  • Atomik geri alma: Geri almaların atomik ve tutarlı olmasını sağlar. Değişiklikleri elle silip commit’lerken insan hatası riski vardır. 
  • Çatışma farkındalığı: Orijinal commit’e bağımlı entegrasyonlar veya değişiklikler varsa çatışmalar aracılığıyla uyarılmamızı sağlar. Zahmetli görünebilir, ancak istenmeyen yan etkilere karşı koruma sağlar.
  • Meta veriler: git revert ile oluşturulan yeni commit, neyin geri alındığını bağlamsal olarak açıklayan meta veriler ve bir commit mesajı içerir; bu da gelecekteki anlaşılırlığı artırır. git revert olmadan bu bağlam kaybolabilir.

Farklı Senaryolarda Birleştirmeyi Geri Alma

Bu bölümde bir birleştirmeyi nasıl geri alacağımızı öğreniyoruz. Örnek olması açısından, main dalında şu komutu çalıştırarak feature adlı bir dalı main dalına birleştirdiğimizi varsayıyoruz:

git merge feature

Burada öğrendiklerimizi, adları uygun şekilde değiştirerek herhangi iki dala uygulayabiliriz.

Commit oluşturmayan bir birleştirmeyi geri alma

git merge komutu her zaman yeni bir commit oluşturmaz. Yalnızca main dalı feature dalından ayrışmışsa bir commit oluşturulur. git revert’in çalışması için bir commit gerektiğinden bu durumda kullanamayız.Ayrışan Git dalları nedir açıklaması

main ve feature dalları, main üzerinde feature’ın atası olmayan yeni commit’ler oluşturulduğunda ayrışır. Başka bir deyişle, feature oluşturulduktan sonra main üzerinde yeni commit’ler yapılmıştır.

Dallar ayrışmamışsa, main dalında git merge feature komutunu çalıştırdığımızda Git hızlı ileri (fast-forward) birleştirmesi kullanır. Bu, main dalının HEAD işaretçisinin, feature dalının HEAD’ine taşınması anlamına gelir.

<code data-mce-selected=

git merge sonucuna bakarak bunun olduğunu gözlemleyebiliriz:

Hızlı ileri (Fast-forward) ile birleştirildiğini anlama

Böyle bir birleştirmeyi geri almak için yalnızca main dalının HEAD’ini önceki konumuna taşımamız gerekir. Bunun için:

  1. git reflog kullanarak önceki HEAD’i belirleyin
  2. <previous_head> yerine önceki HEAD’i koyarak git reset --hard <previous_head> ile HEAD’i geri alın.

git reflog çıktısı şu şekilde görünecektir:

Eski HEAD referansını bulma

“checkout: moving from feature to main” diyen satıra bakarak önceki HEAD’i belirleyebiliriz (dallarımızın adı feature ve main olduğu için bu şekilde yazar). 

Bu durumda önceki head fe59838. Birleştirmeyi geri almak için main dalının HEAD’ini buna geri taşımak üzere şu komutu kullanırız:

git reset --hard fe59838

HEAD’i geri aldığımızda ne olur görseli

Commit oluşturan bir birleştirmeyi geri alma

main ve feature dalları ayrışmışsa, iki dalı birleştirdiğimizde birleştirme commit’i denilen yeni bir commit oluşturulur. 

Birleştirme commit’i görseli

Birleştirme commit’i bir daldaki değişiklikleri diğerine uygular. Bu durumda, feature dalındaki değişiklikler main dalına uygulanır.

main dalındaki değişiklikleri geri almak için birleştirme commit’inde git revert kullanırız. Bu, main dalına birleştirmeyle gelen değişiklikleri geri alan yeni bir commit oluşturur ve main dalını birleştirme öncesindeki durumuna fiilen döndürür.

Önce, birleştirme commit’inin özetini belirlememiz gerekir. Bunu git log komutuyla yapabiliriz:

Birleştirme commit özetini belirleme

Birleştirme commit’inin iki ebeveyni olduğundan, git revert sözdizimi biraz farklıdır. Değişiklikleri main dalına göre geri almak istediğimizi belirtmek için -m 1 seçeneğini kullanmamız gerekir:

git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d

Bir git birleştirme commit’ini geri aldığımızda ne olur görseli

Bir Commit’i Geri Alırken Çatışma Çözümü

Bazen, özellikle geri alınan commit daha sonraki değişikliklerle çakışıyorsa, commit’i geri alırken çatışmalar ortaya çıkabilir. Bu gibi durumlarda:

  1. Git geri almayı durdurur: Çatışmaları elle çözmemiz gerekir. Git, çatışmalı dosyaları işaretler ve müdahale ister.
  2. Çatışmaları çözün: Her çatışmalı dosyayı açın, Git’in işaretlediği çatışmaları çözün ve değişiklikleri kaydedin.
  3. Çözülen dosyaları aşamaya alın: git add <file-path>
  4. Geri almaya devam edin: git revert --continue

Sonuç

git revert ile birleştirme commit’lerini geri almak, her değişikliğin ve düzeltmenin commit geçmişinde belgelendiğinden emin olmanızı sağlar.

Ayrıca, git reset ile git revert’i hangi senaryolarda uygulamak gerektiğini anlamak, özellikle iş birliğine dayalı iş akışları veya yalnızca yerel değişiklikler söz konusu olduğunda daha iyi kararlar vermemizi sağlar.

Bu konuyla ilgili daha fazlasını aşağıdaki SSS bölümünde okuyabilirsiniz. Git hakkında daha fazla öğrenmek isterseniz şu kaynakları öneririm:

SSS

İtilmiş bir birleştirmeyi git revert ile geri alabilir miyim?

Evet, git revert’in birleştirmelerdeki başlıca kullanım alanı budur. Değişiklikler yerel ise birleştirmeyi geri almak için git reset daha kolaydır.

Başka kişilerin değişiklikleri görmesi için bunları uzak depoya itmemiz gerekir. Dolayısıyla, halihazırda itilmiş bir birleştirmeyi geri almak için şunları yaparız:

git revert -m 1 <merge_commit_hash>
git push origin <branch_name>

<merge_commit_hash> yerine birleştirme commit’inin özetini ve <brach_name> yerine birleştirmenin yapıldığı dalın adını koyarak.

git revert kullandıktan sonra birleştirme commit’i silinir mi?

Hayır. Birleştirme commit’i geçmişte kalır, ancak yaptığı değişiklikler yeni commit tarafından geri alınır. git revert ile bir birleştirmeyi geri almanın amacı commit geçmişini korumaktır.

Birleştirmeyi geri almak için git revert dışında yollar var mı?

Birleştirmeyi geri almanın alternatif bir yolu git reset kullanmaktır. Bu yöntem dalı birleştirme commit’inden önceki bir duruma sıfırlar. Bu yaklaşım daha müdahalecidir ve diğer işbirlikçiler çalışmalarını sıfırlamayı planladığımız commit’ler üzerine kurduysa sorunlara yol açabilir. Bu nedenle, başkalarını etkilemeyeceğinden emin olduğumuz durumlarda önerilir.

git reset --hard <commit_hash>
git push --force

Geri dönmek istediğimiz commit’in özetiyle <commit_hash>’i değiştirerek.

Birleştirmeyi geri almak için git reset’i ne zaman kullanmalıyım?

Birleştirmeyi geri almak için git reset’i yalnızca birleştirmenin yerelde gerçekleştiği ve henüz itilmediği durumlarda kullanmanızı öneririm.

François Aubry

Yazar

François Aubry

CheapGPT’te full-stack mühendisi ve kurucuyum. Öğretmek her zaman tutkum oldu. Öğrencilik yıllarımdan itibaren diğer öğrencilere ders verme ve yardımcı olma fırsatlarını hevesle aradım. Bu tutku beni doktora yapmaya yönlendirdi; bu süreçte akademik çalışmalarımı desteklemek için araştırma görevlisi olarak da görev aldım. O yıllarda, geleneksel sınıf ortamında bağlar kurmaktan ve öğrenmeyi kolaylaştırmaktan büyük bir tatmin duydum. Ancak çevrim içi öğrenme platformlarının ortaya çıkmasıyla birlikte dijital eğitimin dönüştürücü potansiyelini fark ettim. Nitekim üniversitemizde bu tür bir platformun geliştirilmesinde aktif rol aldım. Geleneksel öğretim ilkelerini yenilikçi dijital yöntemlerle bütünleştirmeye derinden bağlıyım. Tutkum, yalnızca ilgi çekici ve bilgilendirici olmakla kalmayan, aynı zamanda bu dijital çağdaki öğrenenler için erişilebilir kurslar tasarlamaktır.

Konular

İlgili