Git Branch Nedir: Dal Oluşturma ve Yönetimi

Ekibinizle birlikte bir projede çalışıyorsunuz ve yeni bir özellik geliştirmeniz gerekiyor. Ama aynı zamanda production’daki kritik bir bug’ı düzeltmeniz de şart. Bu iki işi aynı kod tabanında, birbirini bozmadan nasıl yürütürsünüz? İşte Git’in branch mekanizması tam olarak bu soruyu çözüyor. Yıllar içinde onlarca ekibin Git kullanımını izledim ve branch’i doğru anlayan ekiplerin neredeyse hiç “birbirimizin kodunu ezdi” sorunuyla karşılaşmadığını gördüm. Branch kavramını sağlam oturtmak, Git’in geri kalanını da çok daha anlamlı kılıyor.

Branch Nedir, Gerçekte Ne İşe Yarar

Branch, Türkçe’de “dal” anlamına geliyor ve Git’in commit geçmişini farklı yönlere doğru büyütmenizi sağlayan bir mekanizma. Ama bunu sadece “kod kopyası” olarak düşünmek yanlış. Branch, aslında belirli bir commit’e işaret eden hafif bir referans (pointer). Yeni bir branch oluşturduğunuzda Git herhangi bir dosyayı kopyalamıyor, sadece yeni bir işaret çubuku dikmiş oluyor.

Bu neden önemli? Çünkü büyük projelerde bile branch oluşturmak milisaniyeler alıyor ve disk alanı neredeyse hiç tüketmiyor. Subversion ya da eski VCS araçlarından gelen arkadaşlar için bu gerçekten zihin açıcı bir özellik.

Git’te her zaman bir branch üzerinde çalışırsınız. Hiç branch oluşturmasanız bile main veya master adında bir branch üzerindesinizdir. HEAD adı verilen özel bir pointer da her zaman “şu an üzerinde olduğunuz branch”i gösterir.

Yeni Branch Oluşturmak

En temel işlemden başlayalım. Yeni bir branch oluşturmak için iki farklı yaklaşım var:

# Sadece branch oluştur, geçiş yapma
git branch feature/user-authentication

# Branch oluştur ve hemen geçiş yap (eski yöntem)
git checkout -b feature/user-authentication

# Branch oluştur ve hemen geçiş yap (modern yöntem, Git 2.23+)
git switch -c feature/user-authentication

Ben git switch komutunu tercih ediyorum çünkü amacı çok daha net. checkout komutu hem branch değiştirmek hem de dosyaları geri almak için kullanılıyor, bu da bazen kafa karışıklığı yaratıyor. Ama eski alışkanlıkla checkout kullanmaya devam edenler de var, ikisi de çalışıyor.

Branch isimlerine gelince: Convention’a uymak gerçekten hayatı kolaylaştırıyor. Şu formatları kullanıyorum ve ekibime de öneririm:

  • feature/ozellik-adi – Yeni özellikler için
  • bugfix/bug-aciklamasi – Bug düzeltmeleri için
  • hotfix/kritik-duzeltme – Production’da acil düzeltme gerektiğinde
  • release/v1.2.0 – Release hazırlığı için
  • experiment/deneme-adi – Henüz kararlı olmayan denemeler için

Slash kullanımı (/) branch’leri görsel olarak gruplandırıyor ve bazı Git arayüzleri bunu tree şeklinde gösteriyor.

Mevcut Branch’leri Listelemek

# Sadece local branch'leri listele
git branch

# Tüm branch'leri listele (remote dahil)
git branch -a

# Remote branch'leri listele
git branch -r

# Her branch'in son commit mesajıyla birlikte listele
git branch -v

# Merge edilmiş branch'leri göster
git branch --merged

# Henüz merge edilmemiş branch'leri göster
git branch --no-merged

git branch --merged komutu düzenli temizlik için çok kullanışlı. Ana branch’e merge ettiğiniz ve artık işiniz bitmiş branch’leri bu şekilde tespit edip silebilirsiniz.

Branch’ler Arasında Gezinmek

# Var olan bir branch'e geçiş
git switch feature/user-authentication

# Bir önceki branch'e dön (cd - gibi çalışır)
git switch -

# Belirli bir commit'ten branch oluştur
git switch -c hotfix/login-bug abc123f

git switch - komutu favorilerimden biri. Tıpkı terminal’de cd - ile önceki dizine döndüğünüz gibi, bir önceki branch’e geri döndürüyor. Özellikle main ve geliştirme branch’i arasında sürekli gidip gelirken çok işe yarıyor.

Gerçek Dünya Senaryosu: Paralel Geliştirme

Diyelim ki bir e-ticaret sitesinin backend’ini geliştiriyorsunuz. Sprint’te hem “sepet özelliği” hem de “ödeme entegrasyonu” var. Ayrı ekip üyeleri bunları alıyor:

# Mevcut durumu kontrol et
git log --oneline -5
# abc123 Add product listing API
# def456 Fix database connection pool
# ghi789 Initial project setup

# Feature branch'leri oluştur
git switch -c feature/shopping-cart
# ... kodlama, commit'ler ...

git switch main
git switch -c feature/payment-integration
# ... kodlama, commit'ler ...

Bu noktada her iki geliştirici de main‘den bağımsız çalışıyor. Birinin yarım bıraktığı kod diğerini etkilemiyor.

Şimdi production’da kritik bir bug bulundu. main‘in şu anki haline hotfix uygulamanız gerekiyor:

# main'e dön
git switch main

# Hotfix branch aç
git switch -c hotfix/null-pointer-checkout

# Düzeltmeyi yap ve commit et
git add .
git commit -m "Fix: null pointer exception in checkout process"

# main'e merge et
git switch main
git merge hotfix/null-pointer-checkout

# Hotfix branch'ini sil
git branch -d hotfix/null-pointer-checkout

Bu akış sayesinde yarım kalmış feature’lar production’ı etkilemiyor. Hotfix temiz bir şekilde uygulandı.

Branch’leri Silmek

# Merge edilmiş branch'i sil (güvenli)
git branch -d feature/shopping-cart

# Merge edilmemiş branch'i zorla sil (dikkatli kullanın)
git branch -D experiment/failed-idea

# Remote branch'i sil
git push origin --delete feature/old-feature

-d parametresi: Branch merge edilmişse siler, edilmemişse uyarı verir.

-D parametresi: Merge durumuna bakmaksızın zorla siler. Bu komutu kullanmadan önce branch’in commit’lerinin başka bir yerde var olduğundan emin olun.

Remote branch silme konusunda ekip içi iletişim önemli. Başka birinin üzerinde çalıştığı branch’i remote’dan silmek gereksiz sürtüşmeye yol açıyor.

Tracking Branch Kavramı

Remote repository ile çalışırken “tracking branch” kavramını anlamak önemli. Tracking branch, local branch’inizin hangi remote branch’i takip ettiğini belirtiyor.

# Remote'dan branch'i çek ve tracking ayarla
git checkout --track origin/feature/payment-integration

# Ya da kısaca
git switch feature/payment-integration
# Git, aynı isimde remote branch varsa otomatik tracking kurar

# Mevcut branch'e tracking ekle
git branch -u origin/feature/payment-integration

# Tracking bilgilerini görüntüle
git branch -vv

git branch -vv komutu gerçekten sevdiğim bir komut. Her local branch’in hangi remote’u takip ettiğini ve kaç commit geride ya da ileride olduğunu gösteriyor:

* feature/shopping-cart    3a2b1c0 [origin/feature/shopping-cart: ahead 2] Add cart item removal
  main                     f1e2d3c [origin/main] Merge pull request #42
  feature/payment          9b8a7c6 [origin/feature/payment: behind 1] Initial payment setup

“ahead 2” demek: Local’de 2 commit var, henüz push edilmedi. “behind 1” demek: Remote’da 1 commit var, henüz pull edilmedi.

Branch Geçmişini Görselleştirmek

Terminal’de branch yapısını görselleştirmek için şu komutu sıkça kullanırım:

# ASCII art ile branch geçmişi
git log --oneline --graph --all --decorate

# Daha okunabilir format
git log --oneline --graph --all --decorate --format="%C(yellow)%h%Creset %C(green)%d%Creset %s"

Çıktı şuna benzer bir şey olur:

* 3a2b1c0 (HEAD -> feature/shopping-cart) Add cart item removal
* 7d6e5f4 Add cart total calculation
| * 9b8a7c6 (feature/payment) Initial payment setup
|/
* f1e2d3c (main) Merge pull request #42
* a4b5c6d Add product listing

Bu görünüm branch’lerin nerede ayrıldığını ve birleştiğini anlamak için oldukça yardımcı. Büyük projelerde bunu açık tutmak, “hangi commit nerede” sorusunu hızla yanıtlamanızı sağlıyor.

Orphan Branch: Sıfırdan Başlayan Branch

Az bilinen ama çok kullanışlı bir özellik: orphan branch. Bu tür branch’lerin geçmişi olmaz, tıpkı repository’yi sıfırdan başlatmak gibi.

# Geçmişsiz yeni bir branch oluştur
git switch --orphan gh-pages

# Ya da eski syntax ile
git checkout --orphan documentation

# Mevcut index'i temizle
git rm -rf .

# Yeni dosyalar ekle ve commit et
echo "# Docs" > README.md
git add README.md
git commit -m "Initial documentation"

GitHub Pages için gh-pages branch’i buna iyi bir örnek. Projenizin kaynak kodundan tamamen bağımsız bir geçmişe sahip olmasını istiyorsunuz. Dokümantasyon projelerinde ya da deploy artifact’larını ayrı tutmak istediğinizde de işe yarıyor.

Branch Stratejileri: Takım İçin Yapısal Düşünmek

Branch mekanizmasını öğrenmek bir şey, onu ekip olarak nasıl kullanacağınıza karar vermek başka bir şey. Birkaç yaygın yaklaşımı özetleyeyim:

Git Flow en köklü strateji. main, develop, feature/, release/, hotfix/* branch tiplerini tanımlıyor. Büyük ekipler ve düzenli release döngüleri olan projeler için uygun. Ama küçük ekipler için fazla karmaşık olabiliyor.

GitHub Flow çok daha sade. Sadece main ve kısa ömürlü feature branch’leri var. Her şey pull request üzerinden main‘e gidiyor. Sürekli deployment yapan ekipler için ideal.

Trunk-Based Development ise en radikal yaklaşım. Herkes direkt main‘e push ediyor ya da çok kısa ömürlü branch’ler kullanıyor. Feature flag’lerle henüz hazır olmayan özellikleri kapatıyorsunuz. CI/CD olgunluğu yüksek büyük teknoloji şirketlerinin tercih ettiği yöntem.

Hangi stratejiyi seçeceğiniz ekibinizin büyüklüğüne, release sıklığınıza ve CI/CD olgunluğunuza bağlı. Ben genellikle küçük-orta ekiplere GitHub Flow’u öneriyorum: anlaması kolay, uygulama sürtüşmesi az.

Yaygın Hatalar ve Çözümleri

Yanlış branch’te çalışmaya başlamak: Bunu herkes yaşıyor. Fark ettiğinizde henüz commit etmediyseniz:

# Değişiklikleri stash'e al
git stash

# Doğru branch'e geç
git switch feature/correct-branch

# Değişiklikleri geri al
git stash pop

Branch ismini yanlış yazmak: Commit’ler yapıldıktan sonra branch adını değiştirmek gerekirse:

# Branch adını değiştir
git branch -m eski-isim yeni-isim

# Şu an üzerinde olduğunuz branch'in adını değiştir
git branch -m yeni-isim

# Remote'daki adı da güncelle
git push origin --delete eski-isim
git push origin yeni-isim
git branch -u origin/yeni-isim yeni-isim

Detached HEAD durumu: Bu durum, bir branch yerine doğrudan bir commit’e geçiş yaptığınızda oluşur:

# Detached HEAD'e ne zaman düşersiniz?
git checkout abc123f  # Doğrudan commit hash'ine geçiş

# HEAD durumunu kontrol et
git status
# HEAD detached at abc123f

# Kurtarma: Bulunduğunuz noktadan branch oluşturun
git switch -c kayip-degisikliklerim

# Ya da sadece HEAD'i branch'e geri dönün
git switch main

Detached HEAD durumunda yaptığınız commit’ler kaybolabilir. Commit hash’lerini biliyorsanız kurtarabilirsiniz ama en iyisi bu durumdan hemen çıkmak.

Remote Branch’lerle Senkronizasyon

# Remote'daki değişiklikleri fetch et (merge yapmadan)
git fetch origin

# Belirli bir remote branch'i fetch et
git fetch origin feature/new-api

# Remote'da silinmiş branch referanslarını temizle
git fetch --prune

# Ya da kısaca
git fetch -p

git fetch --prune komutunu düzenli kullanın. Remote’da silinmiş branch’lerin “hayalet” referansları local’de kalıyor ve git branch -a çıktısını gereksiz yere kalabalıklaştırıyor. Bu komutu global olarak da ayarlayabilirsiniz:

git config --global fetch.prune true

Bu ayarla her git fetch otomatik olarak temizlik yapıyor.

Branch’leri Karşılaştırmak

İki branch arasındaki farkı anlamak için:

# feature branch'inde olup main'de olmayan commit'ler
git log main..feature/shopping-cart --oneline

# main'de olup feature'da olmayan commit'ler
git log feature/shopping-cart..main --oneline

# İki branch arasındaki dosya farklarını göster
git diff main...feature/shopping-cart

# Sadece değişen dosya isimlerini göster
git diff --name-only main...feature/shopping-cart

İki nokta (..) ile üç nokta (...) arasındaki fark ince ama önemli. İki nokta “bu commit’ten bu commit’e kadar” derken, üç nokta “ortak ata’dan bu yana her iki branch’te olan değişiklikler” anlamına geliyor. Branch karşılaştırmasında genellikle üç nokta daha kullanışlı.

Sonuç

Branch, Git’in en güçlü özelliklerinden biri ve doğru kullanıldığında ekip verimliliğini ciddi ölçüde artırıyor. Özetlemek gerekirse:

  • Branch oluşturmak hesaplı ve hızlı, sık sık kullanmaktan çekinmeyin
  • git switch komutunu tercih edin, amacı daha net
  • Branch isimlerine convention uygulayın, ekip içi anlaşmazlık yaratmaz
  • git branch -vv ve git log --graph komutlarını rutin kontrollerinize ekleyin
  • git fetch --prune ile referanslarınızı temiz tutun
  • Ekibinizin büyüklüğüne ve iş akışına uygun bir branch stratejisi seçin

Branch yönetimi alışkanlık gerektiriyor. İlk başta biraz kurumsal gelebilir, “bu kadar branch’e ne gerek var” diye düşünebilirsiniz. Ama birkaç kez “yanlış branch’e commit ettim” ya da “arkadaşımın yarım kodu benim çalışmamı bozdu” durumunu yaşadıktan sonra, bu alışkanlığın ne kadar değerli olduğunu bizzat görüyorsunuz. Git’te merge ve rebase konularına geçmeden önce branch mekanizmasını sindirmek, ilerleyen süreçte pek çok şeyi daha kolay anlamanızı sağlıyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir