Git ile Uzak Depo Yönetimi: remote, fetch ve clone Komutları

Bir projede uzak depoyla ilk kez karşılaştığınızda ne yapacağınızı bilmemek, Git öğrenme sürecinin en sinir bozucu anlarından biridir. git clone mı kullanmalıyım, git fetch mi? Remote neden birden fazla olabilir? Bu soruların cevaplarını yıllarca deneme yanılmayla öğrenen biri olarak, konuyu baştan sona pratik bir gözle ele almak istedim.

Uzak Depo Nedir ve Neden Önemlidir?

Git’in dağıtık yapısından bahsederken herkes “her kopyada tam tarih var” der, geçer. Ama bu özelliğin gerçek anlamı, uzak depolarla çalışmaya başlayınca ortaya çıkar. Uzak depo (remote repository), yerel makinenizin dışında, genellikle bir sunucuda veya servis sağlayıcısında (GitHub, GitLab, Bitbucket, kendi kurduğunuz Gitea vb.) barındırılan bir Git deposudur.

Buradaki kritik nokta şu: Git, uzak depoyu bir “kaynak” veya “hedef” olarak görür, merkezi bir otorite olarak değil. SVN’den alışkın olanlar bu farkı sindirmekte zaman zaman zorlanır. Git’te birden fazla remote tanımlamak mümkündür ve bu, özellikle açık kaynak projelere katkı verirken veya birden fazla ortam (staging, production) yönetirken işe yarar.

git remote: Temeli Anlamak

Her şeyden önce, bir depodaki remote’ları nasıl görürsünüz ve yönetirsiniz, bunu netleştirelim.

# Mevcut remote'ları listele
git remote

# Detaylı bilgi ile listele (fetch ve push URL'leri ayrı ayrı görünür)
git remote -v

Çıktı genellikle şuna benzer:

origin  [email protected]:kullanici/proje.git (fetch)
origin  [email protected]:kullanici/proje.git (push)

origin burada bir isimden ibaredir, büyüsü yoktur. Siz buna sunucu, kaynak, ana da diyebilirdiniz. Sadece topluluk convention’ı olarak origin yerleşmiştir.

Remote Eklemek ve Kaldırmak

# Yeni bir remote ekle
git remote add upstream [email protected]:orijinal-proje/proje.git

# Remote'u yeniden adlandır
git remote rename upstream kaynak

# Remote'u kaldır
git remote remove kaynak

# Remote URL'sini değiştir (SSH'tan HTTPS'e geçiş gibi durumlarda)
git remote set-url origin https://github.com/kullanici/proje.git

Burada upstream kavramına dikkat edin. Açık kaynak dünyasında fork ettiğiniz orijinal depoyu upstream olarak eklmek yaygın bir pratiktir. Kendi fork’unuz origin, orijinal proje upstream olur. Bu şekilde orijinal projedeki güncellemeleri takip edebilirsiniz.

git clone: Projeye Dahil Olmanın Başlangıç Noktası

git clone, uzak bir deponun tam kopyasını yerel makinenize alır. Sadece son sürümü değil, tüm commit geçmişini, branch’leri ve tag’leri.

Temel Kullanım

# HTTPS ile klonlama
git clone https://github.com/kullanici/proje.git

# SSH ile klonlama (CI/CD ve sunucu ortamları için tercih edilmeli)
git clone [email protected]:kullanici/proje.git

# Farklı bir dizin adıyla klonlama
git clone [email protected]:kullanici/proje.git benim-proje-dizini

SSH ile klonlamayı her zaman tercih edin. HTTPS’te token veya şifre yönetimiyle uğraşmak zorunda kalırsınız; SSH key ile bir kez kurulum yaparsınız, sonrasında sorunsuz çalışır.

Klonlama Seçenekleri

--depth: Shallow clone yapar, sadece belirtilen sayıda commit getirir. Büyük projeleri CI/CD pipeline’larında klonlarken disk alanı ve bant genişliği tasarrufu sağlar.

--branch veya -b: Belirli bir branch veya tag’ı klonlar.

--bare: Çalışma dizini olmadan sadece Git meta verilerini alır. Sunucularda merkezi depo kurarken kullanılır.

--mirror: Bare clone’un üzerine tüm ref’leri de kopyalar. Depo yedekleme senaryolarında işe yarar.

--recurse-submodules: Alt modülleri de otomatik olarak başlatır ve günceller.

--single-branch: Sadece klonlanan branch’ın geçmişini alır, diğer branch’ları getirmez.

# CI/CD için hızlı shallow clone
git clone --depth 1 [email protected]:kullanici/proje.git

# Belirli bir branch'ı klonla
git clone --branch develop [email protected]:kullanici/proje.git

# Bare repository oluştur (sunucuda merkezi depo için)
git clone --bare [email protected]:kullanici/proje.git proje.git

# Alt modüllü projeyi eksiksiz klonla
git clone --recurse-submodules [email protected]:kullanici/proje.git

Gerçek Dünya Senaryosu: CI/CD Pipeline’ında Clone Optimizasyonu

Bir pipeline’da her build’de tam clone almak, özellikle yıllık geçmişi olan büyük projelerde dakikalar alabilir. Bir finans şirketinin GitLab Runner’larında tam clone 4-5 dakika alıyordu. Shallow clone ile bu süreyi 20 saniyeye indirdik.

# Gitlab CI'da örnek
git clone --depth 1 --branch $CI_COMMIT_BRANCH 
  --single-branch $REPO_URL

# Eğer commit geçmişine ihtiyaç duyuyorsanız (örneğin versiyonlama için)
# derinliği artırabilirsiniz
git clone --depth 100 --branch main $REPO_URL

Ancak shallow clone’un bir dezavantajı var: git log ile gördüğünüz geçmiş kısıtlıdır ve bazı merge işlemleri sorun çıkarabilir. Eğer geçmişi işleyecek bir araç kullanıyorsanız (semantic release, changelog üreteci gibi), yeterli derinliği verdiğinizden emin olun.

git fetch: Uzaktan Güncelleme Almak

git fetch, uzak depodaki değişiklikleri yerel kopyanıza indirir ama çalışma dizininizi değiştirmez. Bu özellik, git pull‘dan farkını anlatan en önemli nokta.

# Varsayılan remote'dan (origin) tüm güncellemeleri al
git fetch

# Belirli bir remote'dan al
git fetch upstream

# Tüm remote'lardan al
git fetch --all

# Belirli bir branch'ı al
git fetch origin main

# Tag'ları da dahil et
git fetch --tags origin

git fetch çalıştırdıktan sonra, uzak branch’ların durumunu origin/main, origin/develop gibi isimlerle görebilirsiniz. Bunlar “remote-tracking branch” olarak adlandırılır.

# Fetch sonrası durumu görüntüle
git fetch origin
git log HEAD..origin/main --oneline

# Uzak branch'lardaki değişiklikleri görmek için
git branch -r

# Hem yerel hem uzak branch'ları görmek için
git branch -a

fetch vs pull: Neyi Ne Zaman Kullanmalı?

Bu soru sysadmin’lerin en çok kafasını karıştıran konulardan biri. Özet olarak:

git pull aslında git fetch + git merge (veya --rebase ile git rebase) işlemini birlikte yapar. Yani hem uzaktaki değişiklikleri getirir hem de o anda üzerinde olduğunuz branch’a entegre eder.

# Bu iki komut setinin etkisi aynıdır (varsayılan merge stratejisiyle):
git pull origin main

# = 
git fetch origin main
git merge origin/main

Üretim ortamında, kritik bir deployment öncesinde git fetch + git diff + git merge üçlüsünü tercih edin. Otomatik merge yerine önce neyin değiştiğini görün.

# Güvenli güncelleme akışı
git fetch origin
git diff HEAD origin/main  # Nelerin değişeceğini gör
git log HEAD..origin/main --oneline  # Commit listesine bak
git merge origin/main  # Sonra birleştir

Remote Tracking Branch’larını Temizlemek

Uzak depoda silinen branch’lar, fetch yaptığınızda yerel remote-tracking listesinden otomatik olarak silinmez. Zamanla git branch -r çıktısı karışık hale gelir.

# Uzak depoda silinmiş branch'ların yerel iz bilgilerini temizle
git fetch --prune origin

# Veya kısaca
git fetch -p

# Tek seferlik değil, her zaman prune yapmak için config'e ekle
git config --global fetch.prune true

Bu ayarı global config’e eklemek iyi bir pratik. Özellikle aktif bir ekipte çalışıyorsanız, zamanla onlarca gereksiz remote tracking ref birikir.

Birden Fazla Remote ile Çalışmak

Şimdi daha gerçekçi bir senaryoya geçelim. Diyelim ki açık kaynak bir projeye katkı veriyorsunuz.

# Orijinal projeyi fork ettin, kendi fork'unu klonladın
git clone [email protected]:senin-kullanici-adin/orijinal-proje.git
cd orijinal-proje

# Orijinal projeyi upstream olarak ekle
git remote add upstream [email protected]:orijinal-sahip/orijinal-proje.git

# Durumu kontrol et
git remote -v

Çıktı:

origin  [email protected]:senin-kullanici-adin/orijinal-proje.git (fetch)
origin  [email protected]:senin-kullanici-adin/orijinal-proje.git (push)
upstream  [email protected]:orijinal-sahip/orijinal-proje.git (fetch)
upstream  [email protected]:orijinal-sahip/orijinal-proje.git (push)
# Orijinal projeden güncellemeleri al
git fetch upstream

# Kendi main branch'ını güncelle
git checkout main
git merge upstream/main

# Ya da rebase ile daha temiz bir geçmiş için
git rebase upstream/main

# Kendi fork'unu da güncelle
git push origin main

Bu akış, fork-based iş akışının temelini oluşturur. Birçok şirkette de aynı pattern kullanılır, farklı ortamlar için farklı remote’lar tanımlanır.

Fetch Sonrası Branch Takibi

Remote bir branch’ı yerelde takip etmek (tracking) için çeşitli yollar var:

# Remote branch'ı yerelde oluştur ve takibe al
git checkout -b feature/yeni-ozellik origin/feature/yeni-ozellik

# Daha kısa yol (Git otomatik tracking kurar)
git checkout feature/yeni-ozellik

# Mevcut branch'ı remote ile ilişkilendir
git branch --set-upstream-to=origin/feature/yeni-ozellik feature/yeni-ozellik

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

git branch -vv çıktısı, her branch’ın hangi remote branch’ı takip ettiğini ve yerel ile uzak arasındaki commit farkını gösterir:

* main          a1b2c3d [origin/main] Son commit mesajı
  develop       d4e5f6g [origin/develop: ahead 2, behind 1] Başka commit
  feature/local 7h8i9j0 Lokal branch, uzak takibi yok

Bu çıktıyı okumak, ekip içinde kimin nerede olduğunu anlamak için çok faydalıdır.

Refspec: İleri Seviye Fetch Kontrolü

Çoğu durumda varsayılan fetch davranışı yeterlidir ama zaman zaman daha ince kontrol gerekir. Refspec, hangi uzak ref’lerin hangi yerel ref’lere eşleneceğini tanımlar.

# Sadece main ve release/* branch'larını al
git fetch origin refs/heads/main:refs/remotes/origin/main 
  'refs/heads/release/*:refs/remotes/origin/release/*'

# .git/config içinde kalıcı refspec tanımı
# [remote "origin"] bölümünde fetch = +refs/heads/*:refs/remotes/origin/*
# Bu varsayılandır, tüm branch'ları getirir

Pratikte refspec’e doğrudan ihtiyaç duyduğunuz nadir senaryolar: Pull Request ref’lerini yerelde görmek istediğinizde (özellikle GitHub ve GitLab’da) bu konuya girebilirsiniz.

# GitHub PR'larını yerelde fetch etmek
git fetch origin 'refs/pull/*/head:refs/remotes/origin/pr/*'

# Artık PR'lara checkout yapabilirsiniz
git checkout origin/pr/42

Bu, kod review süreçlerinde PR’ı yerelde test etmenizi sağlar.

Gerçek Dünya Senaryosu: Çoklu Ortam Yönetimi

Bir e-ticaret platformunda üç farklı ortam vardı: development, staging ve production. Her ortam için ayrı Git deposu yerine, aynı depo üzerinde farklı remote’lar tanımlandı.

# Proje setup
git clone [email protected]:platform/eticaret.git
cd eticaret

# Staging ve production remote'larını ekle
git remote add staging [email protected]:eticaret.git
git remote add production [email protected]:eticaret.git

# Her ortamın son durumunu gör
git fetch --all

# Staging'deki ile production'daki farkı gör
git log staging/main..production/main --oneline

# Production'a deploy (main branch'ını production'a gönder)
git push production main

Evet, bu pattern bazı durumlarda abartılı gelebilir ama geçiş dönemlerinde, özellikle Kubernetes veya container orchestration’a geçmeden önce, bu tür Git tabanlı deployment akışları yaygındı.

Sık Karşılaşılan Sorunlar ve Çözümleri

Sorun: git fetch sonrası eski branch’lar hala görünüyor

# Uzak depoda silinmiş branch'ları temizle
git remote prune origin

# Veya fetch ile birlikte
git fetch --prune

Sorun: Remote URL yanlış girilmiş, push çalışmıyor

# Mevcut URL'yi kontrol et
git remote get-url origin

# Düzelt
git remote set-url origin [email protected]:dogru-kullanici/proje.git

# Fetch ve push için farklı URL kullanmak istersen
git remote set-url --push origin [email protected]:dogru-kullanici/proje.git

Sorun: Shallow clone’da git log çok kısıtlı

# Shallow clone'u derinleştir
git fetch --deepen=50

# Tamamen derin yap (shallow olmaktan çıkar)
git fetch --unshallow

Sorun: Büyük dosyalar clone’u yavaşlatıyor, Git LFS kullanıyorsunuz

# LFS olmadan sadece pointer'ları al, büyük dosyaları indirme
GIT_LFS_SKIP_SMUDGE=1 git clone [email protected]:kullanici/buyuk-proje.git

# Sonradan ihtiyaç duyduğun dosyaları al
git lfs pull --include="dizin/buyuk-dosya.bin"

Sonuç

git remote, git clone ve git fetch üçlüsü, Git’in dağıtık doğasını en açık şekilde ortaya koyan komutlardır. Bunları yüzeysel bilmek günlük işleri yürütmeye yeter, ama derinlemesine anlamak hem sorunları hızlı çözmenizi hem de iş akışlarını akıllıca tasarlamanızı sağlar.

Özellikle vurgulamak istediğim birkaç pratik kural var:

  • git pull yerine git fetch + git diff + git merge kullanmayı alışkanlık edinin, üretim ortamında özellikle.
  • fetch.prune true ayarını global config’e ekleyin, remote tracking referans kirliliğini önler.
  • SSH kullanın, token yönetimi derdi çıkarmaz.
  • CI/CD’de --depth 1 ile shallow clone yapın, pipeline süreleriniz ciddi ölçüde düşer.
  • Birden fazla remote‘u gerektiğinde kullanmaktan çekinmeyin, fork iş akışlarında ve çoklu ortam senaryolarında çok işe yarar.

Git’in bu temel mekanizmaları kavrandığında, daha karmaşık iş akışları, submodule yönetimi veya rebase stratejileri çok daha anlaşılır hale gelir. Temel sağlamsa, geri kalanı üzerine kolayca inşa edilebilir.

Bir yanıt yazın

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