Git Branch’leri ve Merge İşlemleri: Kapsamlı Uygulamalı Rehber

Branch’ler, geliştiricilerin bir çalışma hattını diğerinden ayırmasını sağlar. Yeni bir özellik kararlı kodu hemen değiştirmeden geliştirilebilir, acil bir düzeltme bağımsız hazırlanabilir ve deneysel çalışmalar ana geliştirme hattına zarar vermeden terk edilebilir.

Git’te branch oluşturmak hafiftir; çünkü branch, projenin tamamen kopyalanmış ayrı bir dizini değildir. Bir commit’e işaret eden hareketli bir referanstır. Yeni commit’ler oluşturuldukça geçerli branch referansı ileri taşınır.

Bu rehber önce branch modelini açıklar, ardından bunu eksiksiz bir uygulamalı iş akışına dönüştürür. Branch oluşturacak ve branch’ler arasında geçiş yapacak, ayrışmayı inceleyecek, fast-forward ve three-way merge işlemlerini uygulayacak, conflict’leri çözecek, güvenli olmayan entegrasyonları iptal edecek, branch’leri yeniden adlandırıp silecek ve temizlikten önce çalışmanın merge edilip edilmediğini doğrulayacaksınız.

Neler Öğreneceksiniz?

  • Bir Git branch’inin gerçekte neyi temsil ettiğini.

  • Branch’lerin, commit’lerin ve HEAD’in nasıl bağlı olduğunu.

  • Branch’lerin nasıl listelendiğini, oluşturulduğunu, değiştirildiğini, yeniden adlandırıldığını, kopyalandığını ve silindiğini.

  • Başka bir commit veya branch’ten nasıl yeni branch başlatıldığını.

  • Merge öncesinde branch’lerin nasıl karşılaştırıldığını.

  • Fast-forward ile three-way merge arasındaki farkı.

  • --ff-only, --no-ff ve --no-commit seçeneklerinin merge davranışını nasıl etkilediğini.

  • Merge conflict’lerinin nasıl anlaşıldığını ve çözüldüğünü.

  • Bir merge işleminin nasıl güvenle iptal edildiğini veya sürdürüldüğünü.

  • Silmeden önce merge edilmiş ve edilmemiş branch’lerin nasıl incelendiğini.

  • Yerel branch’ler ile remote-tracking branch’ler arasındaki farkı.

  • Yaygın branch hatalarını ve pratik ekip kurallarını.

Git Branch’i Nedir?

Branch, bir commit’e işaret eden adlandırılmış bir referanstır. Bir geliştirme hattının mevcut uç noktasını belirtir.

Bir depoda üç commit bulunduğunu varsayalım:

A---B---C  main

main adlı branch, C commit’ine işaret eder.

feature/search adlı bir branch oluşturduğunuzda Git aynı commit üzerinde başka bir referans oluşturur:

A---B---C  main
          feature/search

Hiçbir dosya kopyalanmaz ve yeni bir commit oluşturulmaz. Her iki ad da aynı commit’e işaret eder.

feature/search branch’ine geçip yeni bir commit oluşturduğunuzda yalnızca bu branch ilerler:

A---B---C  main
         \
          D  feature/search

Dolayısıyla branch, klasör yedeği değil, hareketli bir etikettir.

Branch’ler Hafif Referanslardır

Git’te branch oluşturmak düşük maliyetlidir; çünkü Git esas olarak yeni bir referans oluşturur. Proje anlık görüntüleri ve commit’ler zaten object database içinde bulunur.

Bu özellik kısa ömürlü branch’leri şu işler için pratik hale getirir:

  • Yeni özellikler.

  • Hata düzeltmeleri.

  • Deneyler.

  • Dokümantasyon güncellemeleri.

  • Sürüm hazırlığı.

  • Acil hotfix’ler.

  • Refactoring çalışmaları.

Hafif olması dikkatsiz kullanılabileceği anlamına gelmez. Kötü adlandırılmış, süresiz tutulan veya incelemeden merge edilen branch’ler depoyu anlaşılması zor hale getirebilir.

HEAD Nedir?

HEAD, çalışma ağacında şu anda checkout edilmiş konumu belirtir.

Normal bir branch iş akışında HEAD bir branch’e, branch ise bir commit’e işaret eder:

HEAD -> feature/search -> D

Yeni bir commit oluşturulduğunda geçerli branch yeni commit’e ilerler:

Önce:
HEAD -> feature/search -> D

E commit’inden sonra:
HEAD -> feature/search -> E

Diğer branch’ler otomatik olarak hareket etmez.

Deneme Deposu Oluşturun

Örneklerde Task Notes adlı küçük bir proje kullanılacaktır.

macOS, Linux veya Git Bash

mkdir git-branches-demo
cd git-branches-demo
git init -b main

cat > app.txt <<'EOF'
Task Notes
Depolama: yerel
EOF

cat > README.md <<'EOF'
# Task Notes

Git branch ve merge işlemlerini uygulamak için küçük bir proje.
EOF

git add app.txt README.md
git commit -m "Task Notes projesini oluştur"

PowerShell

New-Item -ItemType Directory git-branches-demo
Set-Location git-branches-demo
git init -b main

@"
Task Notes
Depolama: yerel
"@ | Set-Content app.txt

@"
# Task Notes

Git branch ve merge işlemlerini uygulamak için küçük bir proje.
"@ | Set-Content README.md

git add app.txt, README.md
git commit -m "Task Notes projesini oluştur"

Başlangıç deposunu doğrulayın:

git status
git branch --show-current
git log --oneline --decorate

Yerel Branch’leri Listeleyin

Şunu çalıştırın:

git branch

Geçerli branch bir yıldız işaretiyle gösterilir:

* main

Her branch’in son commit’ini gösterin:

git branch -v

Upstream durumu dahil daha fazla ilişki bilgisi gösterin:

git branch -vv

Yerel ve remote-tracking branch’leri listeleyin:

git branch -a

Yalnızca remote-tracking branch’leri listeleyin:

git branch -r

Bu yerel deneme deposunda bir remote eklenip fetch işlemi yapılana kadar remote listeleri boş kalır.

Geçiş Yapmadan Branch Oluşturun

Geçerli commit üzerinde branch oluşturun:

git branch feature/search

Branch’leri listeleyin:

git branch

Beklenen yapı:

  feature/search
* main

Yeni branch vardır, ancak HEAD hâlâ main branch’ine işaret eder.

Grafiği doğrulayın:

git log --oneline --decorate --all

Her iki branch adı aynı commit’in yanında görünmelidir.

Mevcut Bir Branch’e Geçin

Şunu kullanın:

git switch feature/search

Doğrulayın:

git branch --show-current
git status

Geçiş işlemi güvenli olmayan yerel değişikliklerin üzerine yazmadığı sürece çalışma ağacını ve index’i seçilen branch’e göre günceller.

Eski checkout Komutu

Sıklıkla şu komutla da karşılaşabilirsiniz:

git checkout feature/search

git checkout branch değiştirebilir, path’leri geri yükleyebilir ve HEAD’i detached hale getirebilir. Modern Git, branch geçişleri için git switch, dosya geri yükleme için git restore sunarak niyeti daha açık hale getirir.

Mevcut projeler ve script’ler hâlâ checkout kullanabilir; bu nedenle geliştiricilerin her iki biçimi de tanıması gerekir.

Tek Komutla Branch Oluşturup Geçiş Yapın

Yeni bir branch oluşturup ona geçin:

git switch -c feature/export

Eski eşdeğeri:

git checkout -b feature/export

-c seçeneği branch yalnızca mevcut değilse oluşturur.

Zorlayarak oluşturma biçimi:

git switch -C feature/export

-C, mevcut bir branch’i yeni başlangıç noktasına taşıyabilir. Mevcut branch referansını taşımak bazı commit’leri bu branch üzerinden ulaşılamaz hale getirebileceği için dikkatli kullanın.

Belirli Bir Başlangıç Noktasından Branch Oluşturun

Yeni branch normalde geçerli HEAD noktasından başlar. Başka bir başlangıç noktası seçebilirsiniz:

git switch -c hotfix/login main

Bir tag’den branch oluşturun:

git switch -c support/v1.0 v1.0.0

Bir commit’ten branch oluşturun:

git switch -c investigation 7a93c2e

Geçiş yapmadan oluşturun:

git branch investigation 7a93c2e

Başlangıç noktası, yeni branch ucundan ulaşılabilen ilk commit’i belirler.

İlk Feature Commit’ini Oluşturun

Gerekirse arama branch’ine geçin:

git switch feature/search

Bir feature dosyası oluşturun.

macOS, Linux veya Git Bash

cat > search.txt <<'EOF'
Görevleri anahtar kelimeye göre ara.
EOF

git add search.txt
git commit -m "Anahtar kelime arama açıklamasını ekle"

PowerShell

"Görevleri anahtar kelimeye göre ara." | Set-Content search.txt

git add search.txt
git commit -m "Anahtar kelime arama açıklamasını ekle"

Grafiği inceleyin:

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

Kavramsal olarak:

A  main
 \
  B  feature/search

Feature branch ilerledi. main ilk commit’te kaldı.

Commit Edilmemiş Değişikliklerle Branch Değiştirmek

Git, yerel değişiklikler güvenle korunabiliyorsa branch geçişine izin verebilir. Geçiş değişikliklerin üzerine yazacak veya güvenli olmayan bir durum oluşturacaksa işlemi reddeder.

Branch değiştirmeden önce çalıştırın:

git status

Ardından şu seçeneklerden birini seçin:

  • Tamamlanmış mantıksal bir değişikliği commit edin.

  • Uygun olduğunda tamamlanmamış çalışmayı stash edin.

  • İstenmeyen değişiklikleri bilinçli biçimde silin.

  • Çalışma düzenlenene kadar mevcut branch’te kalın.

Yalnızca uyarıyı atlamak için force seçeneklerini kullanmayın. Git commit edilmemiş çalışmanızı koruyor olabilir.

Önceki Branch’e Geri Dönün

Şunu kullanın:

git switch -

Bu komut daha önce checkout edilmiş branch veya konuma geri döner.

Eşdeğer revision gösterimi dahili olarak çoğu zaman şöyle ifade edilir:

@{-1}

Bu kısayol feature branch ile integration branch arasında sık geçiş yaparken kullanışlıdır.

Detached HEAD

Bir branch yerine doğrudan commit’e geçtiğinizde HEAD detached hale gelebilir:

git switch --detach HEAD~1

Bu durumda HEAD doğrudan bir commit’e işaret eder:

HEAD -> B

Yeni commit oluşturulduğunda hiçbir branch adı otomatik olarak ilerlemez.

Detached mod şu işler için kullanışlıdır:

  • Eski bir sürümü incelemek.

  • Tarihsel bir commit üzerinde test çalıştırmak.

  • Geçmişte başka bir noktayı geçici olarak keşfetmek.

Detached durumda değerli commit’ler oluşturursanız bir branch oluşturarak koruyun:

git switch -c recovery/experiment

Yeni detached commit’leri korumadan dönmek için:

git switch main

Detached HEAD doğası gereği hata değildir; ancak burada oluşturulan commit’ler branch veya tag ile korunmazsa ayrıldıktan sonra bulunmaları zorlaşabilir.

Branch’i Yeniden Adlandırın

Geçerli branch’i yeniden adlandırın:

git branch -m feature/task-search

Başka bir yerel branch’i yeniden adlandırın:

git branch -m old-name new-name

Hedef ad zaten varsa zorlayarak yeniden adlandırın:

git branch -M new-name

Force seçeneğini dikkatli kullanın. Hedef branch referansının üzerine yazabilir.

Yerel yeniden adlandırma, remote hosting platformundaki branch’i otomatik olarak yeniden adlandırmaz. Remote branch yayınlama ve temizleme işlemleri ayrı push komutları gerektirir ve remote collaboration makalelerinde ele alınacaktır.

Branch Referansını Kopyalayın

Git branch’i ve yapılandırmasını kopyalayabilir:

git branch -c feature/task-search backup/task-search

Zorlayarak kopyalayın:

git branch -C feature/task-search backup/task-search

Branch kopyalamak, aynı commit üzerinde normal branch oluşturmaktan daha az yaygındır. İlgili branch yapılandırmasını ve reflog davranışını da bilinçli olarak kopyalamak istediğinizde kullanışlıdır.

Merge Öncesinde Branch’leri Karşılaştırın

Bir branch yalnızca adı tamamlanmış gibi göründüğü için merge edilmemelidir. Commit’lerini ve içeriğini inceleyin.

Feature Branch’e Özgü Commit’leri Gösterin

git log --oneline main..feature/task-search

Main’e Özgü Commit’leri Gösterin

git log --oneline feature/task-search..main

Her İki Taraftaki Benzersiz Commit’leri Gösterin

git log --left-right --graph --oneline main...feature/task-search

Ayrışmadan Sonraki Feature Değişikliklerini Karşılaştırın

git diff --stat main...feature/task-search
git diff main...feature/task-search

Ortak Atayı Gösterin

git merge-base main feature/task-search

Merge base, branch’ler ayrıldıktan sonra yapılan değişiklikleri değerlendirmek için kullanılan en uygun ortak atalardan biridir.

git merge Ne Yapar?

git merge, başka bir commit veya branch’teki değişiklikleri geçerli branch’e dahil eder.

Yön çok önemlidir.

Arama özelliğini main içine merge etmek için:

git switch main
git merge feature/task-search

Geçerli branch, diğer branch’in değişikliklerini alır. Komutu feature branch üzerindeyken çalıştırmak, main branch’ini feature branch’e merge etmeye çalışır.

Her merge öncesinde doğrulayın:

git branch --show-current
git status

Fast-Forward Merge

Geçerli branch, feature branch ayrıldıktan sonra yeni commit almamışsa fast-forward mümkündür.

Önce:

A---B  main
     \
      C---D  feature

Daha doğru gösterimle, main B commit’ine işaret eder ve feature branch doğrudan onun devamıdır:

A---B---C---D  feature
     ^
     main

Sonra:

A---B---C---D  main, feature

Git yalnızca main referansını ileri taşır. Ayrışmış mevcut branch geçmişi olmadığı için merge commit oluşturması gerekmez.

Merge işlemini uygulayın:

git switch main
git merge feature/task-search

Sonuç fast-forward güncellemesi olarak raporlanabilir.

Yalnızca Fast-Forward’a İzin Verin

Şunu kullanın:

git merge --ff-only feature/task-search

Bu komut yalnızca Git geçerli branch’i merge commit oluşturmadan ileri taşıyabiliyorsa başarılı olur.

Geçmişler ayrışmışsa strateji seçmek yerine işlem durur.

Bu seçenek doğrusal entegrasyon isteyen ve beklenmeyen ayrışmanın açıkça ele alınmasını gerektiren iş akışlarında kullanışlıdır.

--no-ff ile Merge Commit Zorlayın

Fast-forward mümkün olsa bile merge commit isteyebilirsiniz:

git merge --no-ff feature/task-search

Geçmiş şöyle olur:

A---B-------M  main
     \     /
      C---D    feature

Merge commit, feature branch çevresinde görünür bir entegrasyon sınırı bırakır.

Olası yararları:

  • Tamamlanmış bir özelliği geçmişte tek bir branch grubu olarak görünür kılmak.

  • Entegrasyon bağlamı içeren merge mesajı sağlamak.

  • Tüm özelliği daha sonra geri almak için kolayca tanımlamak.

Olası maliyetleri:

  • Ek merge commit’leri.

  • Daha karmaşık bir grafik.

  • Her küçük branch için merge commit oluşturulduğunda gereksiz gürültü.

Doğru tercih ekip geçmişi politikasına bağlıdır.

Three-Way Merge

Her iki branch ortak atalarından sonra commit içeriyorsa three-way merge gerekir.

Örnek:

          C---D  feature
         /
A---B---E---F    main

Git üç önemli anlık görüntüyü dikkate alır:

  1. Branch’lerin ortak olduğu merge base.

  2. Geçerli branch ucu.

  3. Merge edilen branch ucu.

Değişiklikler otomatik olarak birleştirilebiliyorsa Git merge sonucunu oluşturur ve normalde merge commit kaydeder:

          C---D
         /     \
A---B---E---F---M  main

Merge commit’in iki parent’ı vardır: önceki geçerli branch ucu ve merge edilen branch ucu.

Three-Way Merge Örneği Oluşturun

Temiz bir main branch’inden reporting branch oluşturun:

git switch -c feature/report

Bir report dosyası ekleyin:

macOS, Linux veya Git Bash

cat > report.txt <<'EOF'
Tamamlanan görevleri raporla.
EOF

git add report.txt
git commit -m "Tamamlanan görev raporu açıklamasını ekle"

PowerShell

"Tamamlanan görevleri raporla." | Set-Content report.txt

git add report.txt
git commit -m "Tamamlanan görev raporu açıklamasını ekle"

main branch’ine geçin ve bağımsız bir değişiklik yapın:

git switch main

macOS, Linux veya Git Bash

cat >> README.md <<'EOF'

## Depolama

Görevler yerel olarak saklanır.
EOF

git add README.md
git commit -m "Yerel görev depolamasını belgele"

PowerShell

@"

## Depolama

Görevler yerel olarak saklanır.
"@ | Add-Content README.md

git add README.md
git commit -m "Yerel görev depolamasını belgele"

Branch’ler artık ayrışmıştır. Feature branch’i merge edin:

git merge feature/report

Değişiklikler farklı dosyaları etkilediği için Git bunları otomatik olarak birleştirmeli ve merge commit oluşturmalıdır.

Sonucu inceleyin:

git log --oneline --graph --decorate --all
git show --stat --summary HEAD

Commit Etmeden Önce Merge Sonucunu İnceleyin

Şunu kullanın:

git merge --no-commit --no-ff feature/report

Bu komut merge işlemini yapar, ancak merge commit oluşturmadan önce durarak sonucu incelemenize ve düzenlemenize izin verir.

İnceleyin:

git status
git diff --staged
git diff --check

Testleri çalıştırın, ardından commit edin:

git commit

Neden --no-ff kullanılır? Fast-forward güncellemesi merge commit oluşturmaz; bu nedenle --no-commit, var olmayan bir merge commit öncesinde duramaz. Merge commit amaçlandığında iki seçeneği birlikte kullanmak entegrasyonu inceleme için durdurur.

Merge Base Var mı Önceden Kontrol Edin

Ortak atayı inceleyin:

git merge-base main feature/report

Bir branch’in diğerinin atası olup olmadığını kontrol edin:

git merge-base --is-ancestor feature/report main

Komut exit status üzerinden sonuç verir:

  • Başarı, ilk revision’ın ikincinin atası olduğu anlamına gelir.

  • Sıfır dışı durum, atası olmadığı anlamına gelir.

Script ve release kontrollerinde kullanışlıdır.

Merge Conflict Nedir?

Merge conflict, Git’in güvenli birleşik sonucu otomatik olarak belirleyemediği durumda oluşur.

Yaygın nedenler:

  • Her iki branch’in aynı satırları farklı biçimde değiştirmesi.

  • Bir branch’in diğerinin değiştirdiği dosyayı silmesi.

  • Her iki branch’in aynı path’te farklı dosyalar eklemesi.

  • Dosya veya dizinin uyumsuz biçimlerde yeniden adlandırılması.

  • Binary dosyaların her iki branch’te değiştirilmesi.

Conflict bozulma değildir. Git rakip bilgileri korur ve geliştiriciden amaçlanan sonucu seçmesini ister.

Kontrollü Merge Conflict Oluşturun

Temiz bir main branch’inden başlayın. Yeni branch oluşturun:

git switch -c feature/cloud-storage

app.txt dosyasını şöyle değiştirin:

Task Notes
Depolama: bulut

Stage edip commit edin:

git add app.txt
git commit -m "Bulut görev depolamasını kullan"

main branch’ine dönün:

git switch main

Aynı satırı farklı biçimde değiştirin:

Task Notes
Depolama: şifreli yerel veritabanı

Commit edin:

git add app.txt
git commit -m "Şifreli yerel görev depolamasını kullan"

Şimdi merge edin:

git merge feature/cloud-storage

Git durmalı ve app.txt içinde conflict raporlamalıdır.

Conflict Durumunu Okuyun

Çalıştırın:

git status

Git unmerged path’leri tanımlar ve devam etmek veya iptal etmek için komutları gösterir.

Kısa durum şöyle görünebilir:

UU app.txt

UU, her iki tarafın dosyayı değiştirdiğini ve conflict’in çözülmediğini gösterir.

Diğer conflict kodları silme/değiştirme, ekleme/ekleme veya başka birleşimleri ifade edebilir.

Conflict İşaretlerini Anlayın

Conflict içeren dosyayı açın. Metin conflict’i şöyle görünebilir:

Task Notes
<<<<<<< HEAD
Depolama: şifreli yerel veritabanı
=======
Depolama: bulut
>>>>>>> feature/cloud-storage

Bölümlerin anlamı:

  • <<<<<<< HEAD: Geçerli branch’ten gelen içerik.

  • =======: Ayırıcı.

  • >>>>>>> feature/cloud-storage: Merge edilen branch’ten gelen içerik.

Son dosya conflict işaretlerini değil, gerçek amaçlanan içeriği içermelidir.

Conflict’i Manuel Olarak Çözün

Doğru ürün kararının her iki modu da desteklemek olduğunu varsayalım. Dosyayı şöyle düzenleyin:

Task Notes
Depolama: isteğe bağlı bulut senkronizasyonuna sahip şifreli yerel veritabanı

Ardından dosyayı stage ederek çözülmüş olarak işaretleyin:

git add app.txt

Çözülmemiş dosyaları kontrol edin:

git status
git diff --check

Birleşik sonucu inceleyin:

git diff --staged

Merge işlemini tamamlayın:

git commit

Veya şunu kullanın:

git merge --continue

git merge --continue, conflict’ler çözüldükten ve stage edildikten sonra merge işlemini tamamlar. Git merge mesajı için editörü açabilir.

Conflict Sırasında Index Stage’lerini Kullanın

Çözülmemiş merge sırasında index, conflict içeren path için birden fazla stage saklayabilir:

  • Stage 1: Merge-base sürümü.

  • Stage 2: Geçerli branch sürümü.

  • Stage 3: Diğer branch sürümü.

Bunları inceleyin:

git ls-files -u

Base sürümünü gösterin:

git show :1:app.txt

Geçerli tarafı gösterin:

git show :2:app.txt

Diğer tarafı gösterin:

git show :3:app.txt

Bu yöntem yalnızca conflict işaretlerini okumaktan daha kesin olabilir.

Normal Merge Sırasında Ours ve Theirs

Normal bir merge sırasında:

  • Ours, merge başladığında checkout edilmiş geçerli branch’i ifade eder.

  • Theirs, merge edilen branch veya commit’i ifade eder.

Conflict içeren bir dosyanın geçerli tarafını alın:

git checkout --ours app.txt
git add app.txt

Gelen tarafı alın:

git checkout --theirs app.txt
git add app.txt

Modern restore sözdizimi desteklenen iş akışlarında index stage’lerini seçebilir:

git restore --ours app.txt
git restore --theirs app.txt

Bu komutları otomatik kullanmayın. Çalışma dosyasını tek tarafla değiştirir ve diğer taraftaki değerli değişiklikleri silebilir. Stage etmeden önce sonucu inceleyin.

Ayrıca rebase sırasında işlemin bakış açısı farklı olduğu için “ours” ve “theirs” anlamları sezgiye aykırı hale gelebilir. Her zaman geçerli işlemi ve dosya içeriğini doğrulayın.

Merge Tool Kullanın

Desteklenen görsel veya terminal tabanlı merge tool yapılandırıldıktan sonra çalıştırın:

git mergetool

Merge tool şunları gösterebilir:

  • Ortak base.

  • Geçerli branch sürümü.

  • Gelen sürüm.

  • Önerilen sonuç.

Tool tamamlandıktan sonra dosyaları ve depo durumunu inceleyin. Bazı araçlar proje politikasına göre silinmesi veya yok sayılması gereken yedek dosyalar bırakabilir.

Merge İşlemini İptal Edin

Merge devam etmemeliyse:

git merge --abort

Git merge öncesindeki durumu yeniden oluşturmaya çalışır.

Abort işlemi, merge başlamadan önce çalışma ağacı temiz olduğunda en güvenilir şekilde çalışır. Önceden var olan commit edilmemiş değişiklikler geri yüklemeyi karmaşıklaştırabilir.

Bu nedenle entegrasyon öncesinde temiz çalışma ağacı güçlü biçimde önerilir.

Eski İş Akışlarında Görülen Alternatif

Şu komutla karşılaşabilirsiniz:

git reset --merge

İlgili kurtarma durumlarında kullanılabilir; ancak aktif merge sırasında git merge --abort niyeti daha açık ifade eder.

Conflict Çözümünü Yeniden Başlatın

Conflict yanlış düzenlendiyse ancak tüm merge iptal edilmeyecekse conflict görünümünü dikkatlice geri yükleyin.

Bir yaklaşım, merge işleminin mevcut index durumu üzerinden dosyanın çözülmemiş stage’lerini geri yüklemektir; ancak davranış hangi içeriğin stage edildiğine veya üzerine yazıldığına bağlıdır.

Yeni başlayanlar için en güvenli seçenekler genellikle şunlardır:

  • Stage etmeden önce version-control destekli editör işlemlerini kullanmak.

  • Stage’leri git show :1:, :2: ve :3: ile incelemek.

  • Çözüm süreci güvenilmez hale geldiyse merge işlemini iptal edip yeniden başlatmak.

Kaynağını artık anlamadığınız bir dosyayla devam etmeyin.

Conflict Çözüm İş Akışı

  1. git status çalıştırın.

  2. Tüm unmerged path’leri belirleyin.

  3. Her conflict’i açın ve iki tarafın amacını anlayın.

  4. Gerektiğinde testleri, gereksinimleri, ilgili commit’leri ve ekip arkadaşlarını inceleyin.

  5. Dosyayı doğru birleşik duruma getirin.

  6. Tüm conflict işaretlerini kaldırın.

  7. Path’i çözülmüş olarak işaretlemek için git add path çalıştırın.

  8. Hiç unmerged path kalmayana kadar tekrarlayın.

  9. Testleri ve statik kontrolleri çalıştırın.

  10. Stage edilmiş sonucu inceleyin.

  11. git merge --continue veya git commit ile merge işlemini tamamlayın.

  12. Son grafiği ve uygulama davranışını inceleyin.

Devam Eden Merge İşlemini İnceleyin

Yararlı komutlar:

git status
git diff
git diff --staged
git diff --check
git ls-files -u

Conflict sırasında:

  • git diff, çözülmemiş combined diff bilgisini gösterir.

  • git diff --staged, merge commit için hazırlanmış çözülmüş içeriği gösterir.

  • git ls-files -u, unmerged index girişlerini listeler.

  • git diff --check, eklenen satırlardaki whitespace hatalarını ve kalan conflict işaretlerini bulmaya yardımcı olur.

Merge Mesajları

Merge commit oluşturulduğunda Git bir mesaj önerir. Kendi mesajınızı verebilirsiniz:

git merge --no-ff feature/report -m "Tamamlanan görev raporlama özelliğini merge et"

Veya editörün açılmasına izin verin:

git merge --no-ff --edit feature/report

Yararlı bir merge mesajı şunları açıklayabilir:

  • Hangi özellik veya düzeltmenin entegre edildiğini.

  • Açık olmayan bir conflict’in neden belirli şekilde çözüldüğünü.

  • Önemli uyumluluk veya deployment gereksinimlerini.

  • Ekip kurallarına göre ilgili issue veya review referanslarını.

Merge mesajını açık commit’lerin ve review geçmişinin yerine kullanmayın.

Merge Strategy ve Strategy Seçenekleri

Git, -s ile seçilen merge strategy’leri ve -X ile verilen strategy’ye özel seçenekleri destekler.

Normal iki başlı merge işlemlerinde Git’in varsayılan stratejisi yaygın branch entegrasyonu için tasarlanmıştır ve yeniden adlandırmaları ve birçok otomatik birleşimi işler.

Karşılaşabileceğiniz örnekler:

git merge -s ort feature/report
git merge -Xours feature/report
git merge -Xtheirs feature/report

-Xours ve -Xtheirs seçenekleri tüm diğer branch’i veya geçerli branch’i atmakla aynı değildir. Conflict içeren hunk’larda hangi tarafın tercih edileceğini etkilerken conflict içermeyen değişiklikleri yine dahil eder.

Strategy seçeneklerini, politika bilinçli değilse ve sonuç test edilmemişse conflict’leri susturmak için kullanmayın.

ours Strategy Farklıdır

Şu komut:

git merge -s ours obsolete-branch

Diğer geçmişi merge edilmiş olarak kaydederken sonuç için geçerli tree’yi kullanan bir merge oluşturur.

Bu davranış -Xours seçeneğinden temelden farklıdır. ours strategy, sonuçta diğer tree’nin içeriğini yok sayar. Bu gelişmiş bir geçmiş işlemidir ve normal conflict çözüm kısayolu olarak kullanılmamalıdır.

Birden Fazla Branch’i Merge Edin

Git uygun, conflict içermeyen durumlarda birden fazla head ile octopus merge yapabilir:

git merge branch-a branch-b branch-c

Strategy otomatik çözebildiğinde ikiden fazla parent’a sahip merge oluşturur.

Octopus merge genellikle birbirinden bağımsız ve önceden test edilmiş topic branch’leri birleştirmek için kullanılır. Çok parent’lı conflict’i anlamak zor olduğu için karmaşık conflict çözümü için uygun değildir.

Zaten Merge Edilmiş Branch’leri Bulun

Uçları HEAD üzerinden ulaşılabilir yerel branch’leri listeleyin:

git branch --merged

HEAD içine tam olarak merge edilmemiş branch’leri listeleyin:

git branch --no-merged

Belirli bir branch’e göre kontrol edin:

git branch --merged main
git branch --no-merged main

Branch temizliği öncesinde kullanışlıdır.

Bir branch’in --merged main altında görünmesi, branch ucunun main üzerinden ulaşılabilir olduğu anlamına gelir. Özelliğin merge commit ile entegre edildiğini kanıtlamaz; fast-forward, rebase veya eşdeğer değişiklikler yorumu etkileyebilir.

Bir Commit’i İçeren Branch’leri Bulun

Belirli commit’i içeren branch’leri listeleyin:

git branch --contains <commit>

Commit’i içermeyen branch’leri listeleyin:

git branch --no-contains <commit>

Şu soruları yanıtlamaya yardımcı olur:

  • Güvenlik düzeltmesi release branch’e ulaştı mı?

  • Hangi maintenance branch’ler bu patch’i içeriyor?

  • Bu geçici branch, ucu kaybolmadan silinebilir mi?

Yerel Branch’i Güvenle Silin

Branch’i yalnızca üzerinde değilken silin:

git branch -d feature/report

Küçük -d güvenlik kontrolü yapar ve uygun upstream veya geçerli geçmiş içine tam merge edilmemiş branch’i normalde silmeyi reddeder.

Zorlayarak silin:

git branch -D feature/report

-D, force delete işlemine eşdeğerdir. Commit’ler başka yerde ulaşılamaz durumda olsa bile branch referansını kaldırır.

Force silme öncesinde:

git log --oneline main..feature/report
git branch --contains feature/report
git reflog show feature/report

Çalışma hâlâ önemli olabilir diye düşünüyorsanız körlemesine silmek yerine yedek tag veya branch oluşturun.

Branch Silmek Commit’leri Hemen Silmez

Branch adı bir referanstır. Silmek referansı kaldırır; alttaki commit nesnelerini hemen silmez.

Commit’ler başka branch, tag, remote-tracking referansı veya başka bir referans üzerinden ulaşılabilir oldukları sürece kalır.

Yakın zamanda silinen yerel branch uçları da sınırlı süre reflog üzerinden bulunabilir. Ancak unreachable nesneler daha sonra prune edilebilir.

Reflog bir kurtarma aracıdır, kalıcı branch arşivi değildir.

Yerel Branch’ler ve Remote-Tracking Branch’ler

Yerel branch, checkout edip commit oluşturabileceğiniz branch’tir:

main
feature/search

Remote-tracking branch, fetch işleminden sonra Git’in remote branch’in en son bilinen durumunu kaydettiği referanstır:

origin/main
origin/feature/search

Normalde doğrudan origin/main üzerinde commit oluşturmazsınız. Remote bilgisi fetch edildiğinde hareket eder.

Remote-tracking branch’e dayalı yerel branch oluşturun:

git switch -c feature/search --track origin/feature/search

Birçok yaygın durumda Git yerel adı otomatik çıkarabilir:

git switch feature/search

Remote yayınlama, upstream yapılandırması, push, fetch ve remote branch silme konuları collaboration ve server durumunu içerdiği için ayrı ele alınacaktır.

Upstream Branch Nedir?

Yerel branch bir upstream branch’i takip edecek şekilde yapılandırılabilir. Bu ilişki, yerel branch’in ahead veya behind durumunu raporlamaya ve yapılandırmaya bağlı olarak pull ve push gibi işlemler için varsayılanlar sağlamaya yardımcı olur.

Tracking bilgisini inceleyin:

git branch -vv

Mevcut yerel branch için upstream ayarlayın:

git branch --set-upstream-to=origin/feature/search feature/search

Kaldırın:

git branch --unset-upstream feature/search

Upstream, parent commit veya merge base ile aynı şey değildir. Yerel branch’i ilişkili başka bir remote veya yerel branch’e bağlayan yapılandırmadır.

Üst Düzeyde Merge ve Rebase Karşılaştırması

Merge geçmişleri birleştirir ve birden fazla parent’a sahip commit oluşturabilir. Rebase commit’leri yeni bir base üzerine yeniden uygular ve yerine geçen yeni commit’ler oluşturur.

Merge:

          C---D
         /     \
A---B---E---F---M

Kavramsal olarak rebase:

A---B---E---F---C'---D'

Rebase doğrusal geçmiş oluşturabilir, ancak commit kimliklerini yeniden yazar. Merge mevcut commit’leri korur ve entegrasyonu açıkça kaydeder.

Bu makale merge’e odaklanır. Conflict bakış açısı, paylaşılan geçmiş güvenliği ve kurtarma davranışı farklı olduğu için rebase ayrı öğrenilmelidir.

Branch Adlandırma Kuralları

Yararlı adlar amacı açıklar:

feature/task-search
fix/login-timeout
hotfix/payment-callback
docs/local-setup
refactor/order-service
release/2.4

Şu tür adlardan kaçının:

test
new
final
branch2
john-work
changes

İyi kurallar:

  • Yazılması ve okunması yeterince kısa.

  • Amacı tanımlayacak kadar özel.

  • Ekip genelinde tutarlı.

  • Depo ve otomasyon kurallarıyla uyumlu.

  • Özel veya hassas bilgi içermeyen.

Bazı ekipler ticket kimliklerini ekler:

feature/APP-142-task-search

Kesin stil, tutarlılık ve açıklıktan daha az önemlidir.

Pratik Feature Branch İş Akışı

1. Güncel Integration Branch’ten Başlayın

git switch main
git status

Remote kullanılan projelerde branch oluşturmadan önce ekip iş akışına göre fetch ve update işlemlerini yapın.

2. Feature Branch Oluşturun

git switch -c feature/task-search

3. Odaklı Commit’ler Oluşturun

git add -p
git diff --staged
git commit -m "Görev anahtar kelime eşlemesini ekle"

4. Feature Değişikliklerini İnceleyin

git log --oneline main..feature/task-search
git diff main...feature/task-search

5. Testleri Çalıştırın

# Projenin gerçek test komutunu kullanın
php vendor/bin/phpunit

6. Hedef Branch’e Merge Edin

git switch main
git merge --no-ff feature/task-search

Ekip tarafından belirlenen merge modunu kullanın. Bazı ekipler yalnızca fast-forward entegrasyonu tercih ederken bazıları merge commit’leri korur.

7. Entegre Sonucu Doğrulayın

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

Yalnızca feature branch üzerinde değil, merge edilmiş sonuç üzerinde de ilgili tam test paketini çalıştırın.

8. Tamamlanan Yerel Branch’i Silin

git branch -d feature/task-search

Pratik Hotfix İş Akışı

Feature branch tamamlanmadan acil production sorunu çıktığını varsayalım.

1. Tamamlanmamış Feature Çalışmasını Koruyun

Tutarlı bir checkpoint commit edin veya ekip uygulamasına göre stash edin.

2. Production Base’e Geçin

git switch main

3. Hotfix Branch Oluşturun

git switch -c hotfix/login-timeout

4. Düzeltmeyi Uygulayın ve Test Edin

git add -p
git commit -m "Giriş sağlayıcısı zaman aşımını artır"

5. Düzeltmeyi Entegre Edin

git switch main
git merge --no-ff hotfix/login-timeout

6. Düzeltmeyi Diğer Aktif Hatlara Taşıyın

Depo iş akışına bağlı olarak güncel base’i feature branch’e merge edin veya onaylı başka entegrasyon yöntemi kullanın.

git switch feature/large-change
git merge main

Bu, aktif feature branch’in daha sonra eski davranışı yeniden getirmesini önler.

Manuel Çalıştırma: Fast-Forward Merge

Başlangıç Geçmişi

A  main

Branch Oluşturun

git switch -c feature/a

İki Commit Oluşturun

A---B---C  feature/a
^
main

Main’e Dönün

git switch main

Merge Edin

git merge feature/a

Sonuç

A---B---C  main, feature/a

Merge commit gerekmez. Geçerli branch işaretçisi C commit’ine ilerler.

Manuel Çalıştırma: Three-Way Merge

Başlangıç Geçmişi

A---B  main

Feature Çalışması

     C---D  feature
    /
A---B      main

Bağımsız Main Çalışması

     C---D  feature
    /
A---B---E---F  main

Main Üzerindeyken Merge Edin

git switch main
git merge feature

Sonuç

     C---D
    /     \
A---B---E---F---M  main

Yeni merge commit M, eski main ucu ile feature ucunu parent olarak içerir.

Manuel Çalıştırma: Conflict ve Çözüm

Base Dosyası

Depolama: yerel

Main Şöyle Değiştirir

Depolama: şifreli yerel veritabanı

Feature Şöyle Değiştirir

Depolama: bulut

Merge Denemesi

git switch main
git merge feature/cloud-storage

Conflict Durumu

<<<<<<< HEAD
Depolama: şifreli yerel veritabanı
=======
Depolama: bulut
>>>>>>> feature/cloud-storage

Çözülmüş Ürün Kararı

Depolama: isteğe bağlı bulut senkronizasyonuna sahip şifreli yerel veritabanı

Çözülmüş Olarak İşaretleyin ve Devam Edin

git add app.txt
git diff --staged
git merge --continue

Doğrulayın

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

Yaygın Branch Hataları

Yanlış Başlangıç Noktasından Branch Oluşturmak

Yeni branch oluşturmadan önce geçerli branch’i ve yakın geçmişi her zaman inceleyin.

Geçerli Branch’i Unutmak

Commit veya merge öncesinde çalıştırın:

git branch --show-current
git status

Commit veya merge işleminden önce.

Branch’i Klasör Kopyası Sanmak

Branch geçmişe işaret eden bir referanstır. Branch değiştirmek çalışma ağacını başka bir geçmiş hattına göre günceller.

Merge Öncesinde Commit Edilmemiş Değişiklikler Bırakmak

Önceden var olan değişiklikler conflict çözümünü ve abort davranışını karmaşıklaştırır.

Yanlış Yönde Merge Etmek

git merge other geçerli branch’i değiştirir. Önce amaçlanan hedef branch’e geçin.

Conflict’i Yalnızca Derlenen Sürümü Tutarak Çözmek

Sözdizimsel olarak geçerli sonuç gereksinimleri ihlal edebilir veya davranışı sessizce kaldırabilir. Her iki değişikliği anlayın ve testleri çalıştırın.

Ours veya Theirs Seçeneklerini İncelemeden Kullanmak

Tüm dosya için tek taraf seçmek diğer taraftaki geçerli çalışmayı silebilir.

Merge Edilmemiş Branch’i -D ile Silmek

Force silme benzersiz commit’lere giden en kolay referansı kaldırabilir.

Tamamlanan Branch’leri Süresiz Tutmak

Eski branch’ler gürültü oluşturur ve aktif çalışma ile tarihsel kalıntıları ayırmayı zorlaştırır.

Ekip Politikası Olmadan --no-ff veya --ff-only Kullanmak

Her iki seçenek de geçmişi şekillendirir. Bilinçli ve tutarlı uygulanmalıdır.

Yerel Branch ile origin/branch’i Karıştırmak

Remote-tracking branch, fetch edilmiş remote durumunu kaydeder. Normal commit oluşturduğunuz yerel branch değildir.

Branch ve Merge İçin En İyi Uygulamalar

  • Branch’leri doğru ve güncel base üzerinden oluşturun.

  • Açıklayıcı ve tutarlı branch adları kullanın.

  • Her branch’te tek bir ana amaç bulundurun.

  • Entegrasyon öncesinde odaklı commit’ler oluşturun.

  • Merge öncesinde geçerli branch’i kontrol edin.

  • Merge işlemlerine temiz çalışma ağacıyla başlayın.

  • Entegrasyon öncesinde benzersiz commit’leri ve üç noktalı diff’i inceleyin.

  • Testleri hem feature branch’te hem merge edilmiş sonuçta çalıştırın.

  • Conflict’leri yalnızca metin tercihiyle değil, amaçlanan davranışa göre çözün.

  • Merge’i tamamlamadan önce conflict çözümlerini inceleyin.

  • Force silmeyi yalnızca benzersiz çalışmanın artık gerekmediğini kanıtladıktan sonra kullanın.

  • Gürültüyü azaltmak için tamamlanan kısa ömürlü branch’leri silin.

  • Ekibin fast-forward, merge commit, squash merge veya rebase yöntemlerinden hangisini kullandığını belgeleyin.

Branch Komutları Referansı

KomutAmacı
git branchYerel branch’leri listelemek
git branch -vvBranch uçlarını ve upstream ilişkilerini göstermek
git branch nameGeçiş yapmadan branch oluşturmak
git switch nameMevcut branch’e geçmek
git switch -c nameBranch oluşturup ona geçmek
git switch -Önceki checkout konumuna dönmek
git switch --detach revisionDetached HEAD ile revision incelemek
git branch -m old newYerel branch’i yeniden adlandırmak
git branch -d nameGüvenli biçimde merge edilmiş yerel branch’i silmek
git branch -D nameYerel branch’i zorlayarak silmek
git branch --merged mainmain içine merge edilmiş branch’leri listelemek
git branch --no-merged mainmain içine merge edilmemiş branch’leri listelemek
git branch --contains commitBelirli commit’i içeren branch’leri listelemek

Merge Komutları Referansı

KomutAmacı
git merge branchBranch’i geçerli branch’e merge etmek
git merge --ff-only branchYalnızca fast-forward güncellemesine izin vermek
git merge --no-ff branchFast-forward mümkün olsa bile merge commit oluşturmak
git merge --no-commit --no-ff branchMerge commit hazırlayıp inceleme için durmak
git merge --continueConflict’ler çözüldükten sonra merge’i tamamlamak
git merge --abortMerge öncesi duruma dönmeyi denemek
git merge-base A BEn uygun ortak atayı göstermek
git mergetoolYapılandırılmış merge çözüm aracını açmak
git ls-files -uUnmerged index girişlerini listelemek
git diff --checkDeğişikliklerde whitespace hatalarını ve conflict işaretlerini kontrol etmek

Merge Öncesi Kontrol Listesi

  • Geçerli branch amaçlanan merge hedefidir.

  • Çalışma ağacı ve index temizdir.

  • Feature branch amaçlanan commit’leri içerir.

  • Branch diff’i incelenmiştir.

  • İlgili testler entegrasyon öncesinde başarılıdır.

  • Gerekli merge modu bilinmektedir: fast-forward, merge commit veya başka onaylı yöntem.

  • İlgisiz yerel değişiklikler işlemi etkilemeyecektir.

  • Yüksek riskli entegrasyon için kurtarma yolu vardır.

Merge Sonrası Kontrol Listesi

  • Çözülmemiş path kalmamıştır.

  • Tracked dosyalarda conflict işaretleri kalmamıştır.

  • Birleşik kod testleri ve statik kontrolleri geçmektedir.

  • Merge commit veya fast-forward sonucu geçmişte görünmektedir.

  • Uygulama iki değişiklik grubuyla birlikte doğru çalışmaktadır.

  • Tamamlanan branch güvenle silinebilir.

  • Gerekirse kritik düzeltmeler diğer uzun ömürlü branch’lere aktarılmıştır.

Sık Sorulan Sorular

Branch Oluşturmak Tüm Projeyi Kopyalar mı?

Hayır. Git commit’e işaret eden hafif bir referans oluşturur. Branch değiştirdiğinizde çalışma ağacı güncellenir.

git branch ile git switch -c Arasındaki Fark Nedir?

git branch name branch’i oluşturur ancak geçiş yapmaz. git switch -c name branch’i oluşturur ve checkout eder.

Git Neden Branch Değiştiremiyor?

Yerel değişikliklerin üzerine hedef branch tarafından yazılabilir. Geçiş öncesinde değişiklikleri commit edin, stash edin, silin veya güvenli biçimde düzenleyin.

Hangi Branch Merge Sonucunu Alır?

Şu anda checkout edilmiş branch, git merge komutunda belirtilen branch’i alır.

Fast-Forward Merge Nedir?

Diğer branch zaten doğrudan bir devam olduğu ve birleştirilmesi gereken ayrışmış geçerli branch commit’leri bulunmadığı için geçerli branch referansının ileri taşınmasıdır.

--no-ff Her Zaman Merge Commit Oluşturur mu?

Normal ve anlamlı bir branch merge işleminde fast-forward’ı engeller ve merge commit ister. Özel durumlar ve komut koşulları için resmî dokümantasyon incelenmelidir.

--no-commit Neden Merge İşlemimi Durdurmadı?

Fast-forward güncellemesinde durulacak merge commit yoktur. İncelenebilir merge commit gerektiğinde --no-ff --no-commit kullanın.

Merge Conflict Bir Git Hatası mıdır?

Hayır. Git’in doğru birleşik içeriği otomatik olarak güvenle seçemediğini ve insan kararı gerektiğini gösterir.

Conflict’i İptal Edebilir miyim?

Evet. git merge --abort kullanın. Geri yükleme, merge öncesinde çalışma ağacı temiz olduğunda en güvenilirdir.

Her Zaman Ours veya Theirs mı Seçmeliyim?

Hayır. Gerçek conflict’lerin çoğu birleşik sonuç gerektirir. Tüm taraflardan yalnızca birini seçmek gerekli davranışı silebilir.

Merge Sonrasında Branch’i Silebilir miyim?

Evet. Branch çalışmasının amaçlanan hedef üzerinden ulaşılabilir olduğunu doğruladıktan sonra git branch -d name kullanın.

Branch Silindikten Sonra Commit’lere Ne Olur?

Başka bir referans üzerinden ulaşılabilir oldukları sürece kalırlar. Benzersiz unreachable commit’ler daha sonra prune edilebilir; ancak yerel reflog geçici kurtarma fırsatı sağlayabilir.

Branch ile Upstream Arasındaki Fark Nedir?

Branch commit’e işaret eden hareketli referanstır. Upstream ise yerel branch’i durum ve varsayılan senkronizasyon davranışları için başka bir branch’e bağlayan yapılandırmadır.

Merge mi Rebase mi Kullanmalıyım?

İki yöntem geliştirme hatlarını farklı biçimlerde entegre eder. Merge mevcut commit’leri korur ve entegrasyonu merge commit ile kaydedebilir. Rebase commit’leri yeni base üzerinde yeniden oluşturur. Ekip tarafından belirlenen iş akışını kullanın ve paylaşılan geçmişi rastgele yeniden yazmayın.

Sonuç

Git branch’leri, geliştirme çalışmalarının bağımsız hatlarda ilerlemesini sağlayan hafif referanslardır. Projeyi kopyalamadan veya kararlı kodu hemen değiştirmeden feature, deney, düzeltme ve release çalışmalarını ayırmayı kolaylaştırırlar.

Merge bu hatları yeniden bir araya getirir. Fast-forward, ayrışma olmadığında branch referansını ileri taşır. Three-way merge ortak ata ve iki branch ucunu kullanarak değişiklikleri birleştirir. Git doğru birleşik içeriği belirleyemediğinde rakip sürümleri korur ve bilinçli conflict çözümü ister.

Güvenli entegrasyon iş akışı merge komutundan önce başlar: temiz çalışma ağacı kullanın, hedef branch’i doğrulayın, benzersiz commit’leri ve diff’leri inceleyin ve testleri çalıştırın. Conflict sırasında her iki niyeti anlayın, doğru birleşik sonucu stage edin ve otomatik olarak tek tarafı seçmek yerine son uygulamayı doğrulayın.

Entegrasyondan sonra grafiği inceleyin, branch ucunun amaçlanan hedef üzerinden ulaşılabilir olduğunu doğrulayın ve tamamlanan kısa ömürlü branch’leri silin. Sonuç yalnızca çalışan kod değil, gelecekteki geliştiricilerin anlayabileceği bir geçmiş olmalıdır.

Bir sonraki makale Git stash ve tag konularına odaklanacaktır: çalışmayı geçici olarak kenara alma, stash edilen değişiklikleri kurtarma, release işaretleri oluşturma, lightweight ve annotated tag’leri karşılaştırma ve tag’leri güvenle yayınlama.

Resmî Kaynaklar ve Ek Okumalar