İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Özel Ders Başvuru Ücretsiz ön görüşme Ana Sayfa

Git “You have divergent branches” Hatası git pull’da Nasıl Çözülür?

git-you-have-divergent-branches-hatasi-git-pull-da-nasil-cozulur
Bu yazıda neler var?
  1. Bu hata neden çıkar?
  2. Ayrışan dalları nasıl görürsün?
  3. Üç git pull seçeneği nasıl seçilir?
  4. pull.rebase ayarı nasıl kalıcı yapılır?
  5. Çakışma çıkarsa nasıl ilerlenir?
  6. Sık Sorulan Sorular

Git “You have divergent branches” hatasını çözmek için önce yerel ve uzak dalın commit geçmişini incele, ardından git pull --no-rebase ile birleştirme veya git pull --rebase ile yerel commit’leri uzak dalın üzerine yeniden uygulama seçeneğini kullan. git pull --ff-only ise dallar zaten ayrışmışsa işlemi durdurur; bu seçenek ayrışan geçmişleri birleştirmez.

Bu hata neden çıkar?

Yerel dalda ve uzak dalda birbirinden farklı commit’ler bulunduğunda Git, birleştirme yöntemi belirlenmemişse bu geçmişleri merge ile birleştirmek mi, yoksa yerel commit’leri rebase ile uzak dalın üzerine yeniden uygulamak mı istediğini sorabilir. Rebase, seçilen commit’lerdeki değişiklikleri yeni bir başlangıç noktasına yeniden uygulayan işlemdir.

Uzak dal, başka bir konumdaki Git deposunda bulunan daldır. Yerel ve uzak dal ortak bir commit’ten sonra birbirinde bulunmayan commit’ler içeriyorsa bu geçmişler ayrışmış sayılır.

Örneğin aynı depoyla iki bilgisayarda çalıştığını düşün. Birinci bilgisayarda A adlı bir commit oluşturuyorsun. İkinci bilgisayarda ise ortak başlangıçtan sonra farklı bir B commit’i oluşturup bunu uzak depodaki main dalına gönderiyorsun.

Birinci bilgisayarda aşağıdaki komutu çalıştırdığında, Git yapılandırmana bağlı olarak şu mesajla karşılaşabilirsin:

git pull

hint: You have divergent branches and need to specify how to reconcile them.
...
fatal: Need to specify how to reconcile divergent branches.

Buradaki ..., Git’in gösterebileceği diğer açıklama ve önerilerin kısaltılmış hâlidir. Mesajın ayrıntıları yapılandırmana göre değişebilir.

Commit geçmişinin mantığı şu şekilde gösterilebilir:

        A  (yerel main)
       /
Ortak başlangıç
       
        B  (uzak main)

Git, pull sırasında önce uzak değişiklikleri getirir, ardından bunları mevcut dalına katmaya çalışır. Ayrışma oluştuğunda dal işaretçisini doğrudan ileri taşımak anlamına gelen fast forward işlemiyle iki geçmişi birleştiremez; bunun için uygun bir yöntem seçmen gerekir.

Ayrışan dalları nasıl görürsün?

Ayrışan dalları nasıl görürsün?

Ayrışmayı görmek için önce mevcut dalını ve çalışma alanını git status ile kontrol et, ardından commit geçmişini git log ile incele. Bu kontroller, birleştirme yöntemi seçmeden önce hangi değişikliklerin commit edildiğini ve dalların nerede ayrıldığını anlamana yardımcı olur.

Mevcut dalı ve çalışma alanını kontrol et

Deponun içinde şu komutu çalıştır:

git status

Çıktının ilk satırında bulunduğun dalı görürsün. Komut ayrıca commit edilmemiş değişiklikleri, hazırlama alanına eklenmiş dosyaları ve takip edilmeyen dosyaları gösterir. Örneğin temiz bir çalışma alanında şu satırlar yer alabilir:

On branch main
nothing to commit, working tree clean

Dosyalarında commit edilmemiş değişiklikler varsa bunları incele ve birleştirme işleminden önce nasıl koruyacağına karar ver. Örnekteki main ve origin adlarını kendi deponun dal ve uzak depo adlarıyla karşılaştır.

Commit geçmişini çiz ve dalları karşılaştır

Önce mevcut dalın geçmişini kısa ve grafik biçiminde görmek için şu komutu kullan:

git log --oneline --graph

Bu komut mevcut daldan erişilebilen commit’leri gösterir; uzak dalın ayrışmış commit’i bu görünümde yer almayabilir. Yerel dalları ve uzak izleme referanslarını birlikte görmek için şu komutu çalıştır:

git log --oneline --graph --decorate --all

Örnek senaryoda çıktı aşağıdakine benzer. Kısa commit kimlikleri ve satırların sırası kendi deponda farklı olabilir:

* a1b2c3d (HEAD -> main) A: Yerel değişiklik
| * b2c3d4e (origin/main) B: Uzak değişiklik
|/
* c3d4e5f Ortak başlangıç

HEAD -> main, üzerinde bulunduğun yerel dalı; origin/main ise uzak daldan son getirilen durumu gösteren yerel izleme referansını belirtir. Çizimde A yalnızca yerel dalda, B ise uzak izleme referansındadır; çizgilerin birleştiği commit ortak başlangıçtır.

Uzak izleme referansı canlı olarak güncellenmez. Uzak depoda hata mesajından sonra yeni commit’ler oluşturulmuş olabileceği için, güncel referansları görmek istediğinde git fetch origin çalıştırıp grafik komutunu yeniden kullanabilirsin. Bu işlem uzak bilgileri getirir, ancak onları mevcut dalınla birleştirmez.

Üç git pull seçeneği nasıl seçilir?

Üç git pull seçeneği nasıl seçilir?

Seçim, ayrışan commit geçmişini birleştirmek, yerel commit’leri yeniden uygulamak veya yalnızca fast forward işlemine izin vermek istemene bağlıdır. Bu seçeneklerin davranışlarını Git pull dokümantasyonunda da inceleyebilirsin.

Örneklerde aynı depoyu iki bilgisayarda kullandığını varsayalım. Birinci bilgisayardan uzak depoya bir commit gönderildi, ikinci bilgisayarda ise bu değişiklik alınmadan ayrı bir commit oluşturuldu. Aşağıdaki her seçenek, ikinci bilgisayarda aynı başlangıç durumundan çalıştırılıyor.

Merge ile iki geçmişi birleştirmek

--no-rebase, indirilen dalı mevcut dalınla merge işlemiyle birleştirir. İki geçmişin birleşme noktasını korumak istediğinde bu yöntemi tercih edebilirsin.

git pull --no-rebase
git log --oneline --graph --all

Çakışma çıkmadığında ve merge commit oluşturulduğunda örnek çıktı şöyle görünebilir:

*   f34a901 Merge remote-tracking branch
|
| * b22c202 Birinci bilgisayardaki değişiklik
* | a11b101 İkinci bilgisayardaki değişiklik
|/
* c33d303 Ortak başlangıç

İki commit geçmişte ayrı kollar olarak kalır ve yeni merge commit bu kolları birleştirir. Çakışma varsa işlemi tamamlamadan önce çakışan değişiklikleri çözmen gerekir.

Rebase ile yerel commit’i uzak dalın üzerine taşımak

--rebase, bu örnekte ikinci bilgisayardaki yerel commit’i indirilen uzak dalın güncel ucunun üzerine yeniden uygular. Daha doğrusal bir geçmiş tercih edildiğinde kullanılabilir.

git pull --rebase
git log --oneline --graph --all

İşlem başarıyla tamamlandığında örnek görünüm şöyledir:

* d44e404 İkinci bilgisayardaki değişiklik
* b22c202 Birinci bilgisayardaki değişiklik
* c33d303 Ortak başlangıç

Yeniden uygulanan commit’in kimliği değişir. Commit daha önce başkalarıyla paylaşıldıysa rebase ortak geçmişi etkileyebilir; bu durumda ekipte kullanılan yöntemi gözeterek karar ver.

Yalnızca fast forward güncellemesine izin vermek

--ff-only, güncelleme dal işaretçisi ileri taşınarak yapılabiliyorsa işlemi tamamlar. Yerel ve uzak geçmiş ayrışmışsa birleştirme yapmadan durur; örneğin uzak daldaki commit yerel dalın doğrudan devamı olduğunda kullanılabilir.

git pull --ff-only
git log --oneline --graph --all

Bu senaryoda ilk komut fatal: Not possible to fast-forward, aborting. mesajıyla durur. Ardından çalıştırılan git log, iki kolu ayrı göstermeye devam eder:

* a11b101 İkinci bilgisayardaki değişiklik
| * b22c202 Birinci bilgisayardaki değişiklik
|/
* c33d303 Ortak başlangıç

Başarısız olan birleştirme yerel dalı ilerletmez; ancak git pull önce fetch çalıştırdığı için uzak dalı izleyen yerel referans güncellenmiş olabilir. Görünüm sırası Git’in commit’leri sıralama biçimine göre değişebilir.

pull.rebase ayarı nasıl kalıcı yapılır?

Kalıcı tercihini, kapsamına göre mevcut depoda veya genel Git yapılandırmasında ayarlayabilirsin. Genel ayar kullanıcı düzeyindeki depolar için geçerlidir; depo düzeyindeki ayar aynı anahtar için genel tercihi geçersiz kılabilir.

KapsamAyarEtkisiDikkat edilmesi gereken durum
Yalnız bu depopull.rebase falseVarsayılan tercih merge olur.Depodaki diğer ilgili ayarlar ve komut seçenekleri sonucu etkileyebilir.
Yalnız bu depopull.rebase trueVarsayılan tercih rebase olur.Paylaşılmış commit’lerin geçmişini değiştirmemeye dikkat et.
Kullanıcının tüm depoları--global ile aynı ayarlarGenel kullanıcı tercihini belirler.Depoya veya dala özgü ayarlar farklı davranışa yol açabilir.

Mevcut depo için aşağıdaki komutlardan tercih ettiğin birini çalıştırabilirsin:

git config pull.rebase false
git config pull.rebase true

Aynı tercihi genel kullanıcı ayarı olarak belirlemek için --global ekle:

git config --global pull.rebase false
git config --global pull.rebase true

Yalnızca fast forward isteyen bir varsayılan için pull.ff ayarını kullanabilirsin. Mevcut depodaki tercih için ilk, genel tercih için ikinci komutu seç:

git config pull.ff only
git config --global pull.ff only

Ayarları değiştirmeden önce mevcut değerleri ve kaynaklarını kontrol etmen yararlıdır. Özellikle pull.ff, dala özgü rebase ayarları ve komut satırında verilen seçenekler birlikte değerlendirilmelidir.

git config --show-origin --get-all pull.rebase
git config --show-origin --get-all pull.ff

Bir anahtar tanımlı değilse ilgili komut değer göstermeyebilir. Genel tercihi değiştirmeden önce kullandığın depoların çalışma biçimini değerlendir; ortak dallarda rebase seçimi ekip geçmişini etkileyebilir.

Çakışma çıkarsa nasıl ilerlenir?

Merge veya rebase sırasında çakışma çıkarsa önce etkilenen dosyaları git status ile gör, ardından değişiklikleri düzenleyip kullandığın işleme devam et. Git, otomatik olarak birleştiremediği değişikliklerde senden karar vermeni ister.

Örneğin bir metin dosyasında şu işaretlerle karşılaşabilirsin:

<<<<<<< HEAD
Merhaba dünya
=======
Merhaba Git
>>>>>>> gelen-değişiklik

İşaretler arasındaki içerikleri incele ve dosyada kalmasını istediğin metni belirle. Gerekirse iki değişikliği birleştir, ardından <<<<<<<, ======= ve >>>>>>> işaretlerini silerek dosyayı kaydet. Rebase sırasında HEAD etiketinin hangi değişikliği gösterdiğini varsaymak yerine içeriği dikkatle kontrol et.

Düzenlediğin her dosyayı git add dosya_adi ile çözümlenmiş olarak işaretle. Bütün çakışmaları giderdikten sonra merge işlemini git commit ile tamamlayabilir veya rebase işlemine git rebase --continue ile devam edebilirsin. Rebase sırasında sonraki commit’lerde de çakışma çıkarsa aynı adımları tekrarla.

İşlemden vazgeçmek için devam eden rebase sırasında git rebase --abort, merge sırasında ise git merge --abort kullanabilirsin. Merge başlamadan önce commit edilmemiş değişikliklerin varsa, iptal işlemi bunları her durumda eski hâline getiremeyebilir.

Geçmişi zorla değiştiren komutlara dikkat et. git push --force, pull sırasında ortaya çıkan ayrışmayı birleştirmez; uzak dalın geçmişinin üzerine yazarak ortak dalda başkalarının çalışmalarını etkileyebilir. git reset --hard ise commit edilmemiş yerel değişiklikleri geri döndürülemez biçimde silebilir. Ne yaptığından ve hangi verilerin etkileneceğinden emin olmadan bu komutları kullanma.

Yöntemi seçerken şu kontrol listesinden yararlanabilirsin:

  • Kişisel dal: Geçmişin yeniden yazılmasını kontrol edebiliyorsan rebase seçeneğini değerlendir.
  • Ortak dal: Ekibin çalışma düzenine uygun bir merge tercih et.
  • Yalnızca fast forward beklenen durum: Yerel geçmişin ayrışmadığından emin olmak için --ff-only kullan.

Sık Sorulan Sorular

git pull --rebase yerel commit’lerimi siler mi?

git pull --rebase, yerel commit’lerdeki değişiklikleri alınan uzak geçmişin üzerine yeniden uygulamayı amaçlar; yeniden oluşturulan commit’lerin kimlikleri değişebilir. Eşdeğer değişiklikler veya çakışmalar gibi durumlarda sonucu kontrol etmek gerekir.

git pull --ff-only hangi durumda kullanılmalıdır?

git pull --ff-only, uzak daldaki güncellemelerin yerel dalın ucunu ileri taşıyarak alınmasını beklediğin durumlarda kullanılmalıdır. Yerel ve uzak geçmiş ayrışmışsa işlem durur; senin ayrıca merge veya rebase yöntemi seçmen gerekir.

pull.rebase ayarını yalnızca mevcut depo için nasıl değiştiririm?

pull.rebase ayarını yalnızca mevcut depoda değiştirmek için deponun içindeyken git config --local pull.rebase true komutunu çalıştırabilirsin. Merge davranışını tercih ediyorsan aynı komutta true yerine false yazabilirsin.

Divergent branches hatasında git push --force kullanmalı mıyım?

Divergent branches hatasını çözmek için git push --force kullanmamalısın; bu komut uzak geçmişin üzerine yazarak başka kişilerin çalışmalarını etkileyebilir. Önce dallardaki commit’leri inceleyip çalışma düzenine uygun pull yöntemini seç.

Komutları çalıştırmadan önce dalın durumunu kontrol etmek ve birleştirme yöntemini çalışma düzenine göre seçmek, sonraki adımları daha anlaşılır kılar.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara