← Kursa Dön
📄 Text · 30 min

Clone ve Fork

Giriş: Neden Clone ve Fork Öğreniyoruz?

Şu ana kadar sıfırdan repo oluşturduk ve remote ekledik. Ama çoğu zaman tam tersi olur: mevcut bir projeyi indirirsin (clone) veya başkasının projesine katkı yapmak istersin (fork).

Bu iki kavram, özellikle open source dünyasında kritik. Bir open source projeye katkı yapmak istiyorsan (ki bu hem kariyer hem deneyim için harika), fork → clone → branch → commit → pull request akışını bilmen gerekiyor.


🎬 Analoji: Kitap Fotokopisi ve Yeni Baskı

  • Clone = Kütüphanedeki bir kitabın fotokopisini almak. Orijinale bağlısın — yeni baskılar çıkarsa güncelleyebilirsin. Ama kütüphanedeki kitabı değiştiremezsin (push yetkisi yok, sadece okuyabilirsin).

  • Fork = Kitabın kendi baskını çıkarmak. Artık kendi kopyan var, üzerinde istediğini değiştir. Değişikliklerin iyi olduysa, orijinal yazara "Bak, şu düzeltmeleri yaptım, senin kitaba da eklemek ister misin?" diye öneri gönderirsin (Pull Request).

CLONE:                          FORK:
┌──────────┐                   ┌──────────┐
│ GitHub'da│  git clone        │ GitHub'da│  Fork (GitHub'da)
│ Başkası- │─────────────►     │ Başkası- │──────────────►
│ nın repo │  (fotokopi al)    │ nın repo │  (kendi kopyan)
└──────────┘                   └──────────┘
     │                              │
     ▼                              ▼
┌──────────┐                   ┌──────────┐
│ Bilgisa- │                   │ Senin    │  git clone
│ yarında  │                   │ Fork'un  │─────────────►
│ kopya    │                   │(GitHub'da)│
└──────────┘                   └──────────┘
     │                              │
     │ push? ❌ Yetkin yok          ▼
     │                         ┌──────────┐
     │                         │ Bilgisa- │
     │                         │ yarında  │
     │                         │ kopya    │
     │                         └──────────┘
     │                              │
     │                              │ push? ✅ Kendi fork'un
     │                              │ PR? ✅ Orijinal repo'ya

git clone — Projeyi İndir

Temel Kullanım

# HTTPS ile clone
$ git clone https://github.com/tolgahan/web-projem.git
Cloning into 'web-projem'...
remote: Enumerating objects: 156, done.
remote: Counting objects: 100% (156/156), done.
remote: Compressing objects: 100% (89/89), done.
Receiving objects: 100% (156/156), 45.2 KiB | 2.12 MiB/s, done.
Resolving deltas: 100% (67/67), done.

$ cd web-projem
$ ls
README.md  index.html  src/  style.css

# SSH ile clone (SSH key ayarlıysa)
$ git clone git@github.com:tolgahan/web-projem.git

Clone ne yapar:

  1. Klasör oluşturur (repo adıyla)

  2. .git dizini ve tüm geçmişi indirir

  3. origin remote'unu otomatik ayarlar

  4. Varsayılan branch'i checkout eder

$ git remote -v
origin  https://github.com/tolgahan/web-projem.git (fetch)
origin  https://github.com/tolgahan/web-projem.git (push)

$ git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/develop
  remotes/origin/main

Farklı Klasör Adıyla Clone

# Farklı isimle clone
$ git clone https://github.com/tolgahan/proje.git benim-projem
$ cd benim-projem

# Mevcut dizine clone (dizin boş olmalı)
$ mkdir projem && cd projem
$ git clone https://github.com/tolgahan/proje.git .

Belirli Branch'i Clone

# Sadece belirli bir branch'i clone
$ git clone -b develop https://github.com/tolgahan/proje.git
$ cd proje
$ git branch
* develop

Shallow Clone: Hızlı İndirme

Büyük projelerde tüm geçmişi indirmek uzun sürer. Sadece son birkaç commit'i indirmek istersen:

# Son 1 commit (en hızlı)
$ git clone --depth 1 https://github.com/torvalds/linux.git
# Linux kernel: tüm geçmişi indirmek ~4GB
# --depth 1 ile ~200MB

# Son 10 commit
$ git clone --depth 10 https://github.com/torvalds/linux.git

# Sonradan tam geçmişi almak istersen
$ git fetch --unshallow

💡 İpucu: CI/CD pipeline'larında --depth 1 çok yaygın. Build yapmak için geçmişe gerek yok — sadece son kod lazım. Bu, build süresini önemli ölçüde kısaltır.

Partial Clone: Akıllı İndirme

Git 2.22+'da partial clone özelliği var:

# Blob'ları (dosya içerikleri) hemen indirme
$ git clone --filter=blob:none https://github.com/tolgahan/proje.git
# Dosyalar sadece checkout edildiğinde isteğe bağlı indirilir

# Belirli boyutun üstündeki blob'ları indirme
$ git clone --filter=blob:limit=1m https://github.com/tolgahan/proje.git
# 1MB üstündeki dosyalar checkout'ta indirilir

Fork — Başkasının Projesini Kopyala

Fork Nedir?

Fork, bir Git komutu değil — GitHub/GitLab/Bitbucket'ın sunduğu bir özellik. Başkasının repository'sinin, senin GitHub hesabına tam bir kopyasını oluşturur.

Orijinal Repo:                    Senin Fork'un:
github.com/django/django    →    github.com/tolgahan/django
                                 (tam kopya, senin hesabında)

Fork vs Clone

┌─────────────────┬──────────────────┬──────────────────────┐
│                 │     Clone        │        Fork           │
├─────────────────┼──────────────────┼──────────────────────┤
│ Nerede olur?    │ Bilgisayarında   │ GitHub'da             │
│ Komut           │ git clone        │ GitHub'da "Fork"      │
│                 │                  │ butonuna tıkla        │
│ Push yapabili-  │ ❌ (başkasının   │ ✅ (kendi fork'una)   │
│ yor musun?      │  reposuna)       │                      │
│ Amacı           │ Kodu indirmek    │ Katkı yapmak veya    │
│                 │                  │ kendi versiyonunu     │
│                 │                  │ geliştirmek           │
│ Remote          │ origin = orijinal│ origin = fork         │
│                 │                  │ upstream = orijinal   │
└─────────────────┴──────────────────┴──────────────────────┘

Fork Workflow: Adım Adım

Open source'a katkı yapmanın standart akışı:

┌───────────────────────────────────────────────────────────────┐
│                    FORK WORKFLOW                              │
│                                                               │
│  1. GitHub'da "Fork" butonuna tıkla                          │
│     → github.com/asil-proje/repo                             │
│     → github.com/tolgahan/repo (fork oluştu)                 │
│                                                               │
│  2. Fork'unu clone'la                                        │
│     $ git clone git@github.com:tolgahan/repo.git             │
│                                                               │
│  3. Upstream remote ekle                                     │
│     $ git remote add upstream https://github.com/asil/repo   │
│                                                               │
│  4. Feature branch aç                                        │
│     $ git switch -c fix/typo-in-readme                       │
│                                                               │
│  5. Değişiklik yap, commit at                                │
│     $ git add . && git commit -m "fix: README typo"          │
│                                                               │
│  6. Fork'una push et                                         │
│     $ git push origin fix/typo-in-readme                     │
│                                                               │
│  7. GitHub'da Pull Request aç                                │
│     → "Compare & pull request" butonuna tıkla                │
│     → asil-proje/repo'ya PR gönder                           │
│                                                               │
│  8. Code review → onay → merge                               │
│     → Asıl proje maintainer'ı inceler                        │
└───────────────────────────────────────────────────────────────┘

Pratik Uygulama

# 1. Fork'u clone'la
$ git clone git@github.com:tolgahan/awesome-project.git
$ cd awesome-project

# 2. Remote durumunu kontrol et
$ git remote -v
origin  git@github.com:tolgahan/awesome-project.git (fetch)
origin  git@github.com:tolgahan/awesome-project.git (push)

# 3. Upstream (asıl proje) remote'u ekle
$ git remote add upstream https://github.com/original-author/awesome-project.git

$ git remote -v
origin    git@github.com:tolgahan/awesome-project.git (fetch)
origin    git@github.com:tolgahan/awesome-project.git (push)
upstream  https://github.com/original-author/awesome-project.git (fetch)
upstream  https://github.com/original-author/awesome-project.git (push)

# 4. main'i güncel tut (upstream'den çek)
$ git fetch upstream
$ git switch main
$ git merge upstream/main
# veya
$ git rebase upstream/main

# 5. Feature branch aç
$ git switch -c fix/improve-documentation

# 6. Değişiklik yap
$ echo "## Kurulum\n\ngit clone ..." >> README.md
$ git add README.md
$ git commit -m "docs: README'ye kurulum adımları eklendi"

# 7. Fork'una push et
$ git push origin fix/improve-documentation

# 8. GitHub'da PR aç (browser'da)

Upstream Senkronizasyonu: Fork'unu Güncel Tut

Fork'un, orijinal projenin bir anlık kopyası. Zaman geçtikçe orijinal proje ilerler, fork'un geride kalır. Düzenli senkronizasyon gerekir.

# 1. Upstream'deki güncel değişiklikleri çek
$ git fetch upstream
remote: Enumerating objects: 25, done.
remote: Counting objects: 100% (25/25), done.

# 2. main'e geç
$ git switch main

# 3. Upstream'in main'i ile birleştir
$ git rebase upstream/main
# veya
$ git merge upstream/main

# 4. Fork'unu da güncelle (GitHub'daki kopyan)
$ git push origin main

Senkronizasyon Akışı

upstream/main:  [A]←[B]←[C]←[D]←[E]←[F]    (asıl proje ilerlemiş)

Senin main:     [A]←[B]←[C]                  (fork'un eski)

$ git fetch upstream
$ git rebase upstream/main

Senin main:     [A]←[B]←[C]←[D]←[E]←[F]    (artık güncel!)
$ git push origin main                       (fork'unu da güncelle)

⚠️ Dikkat: main branch'inde doğrudan commit yapma. Upstream sync'i kolaylaştırmak için main'i her zaman upstream ile aynı tutun. Tüm çalışmalarını feature branch'lerinde yap.

GitHub'da Sync Fork

GitHub, fork'ları senkronize etmek için web arayüzünde bir buton ekledi:

GitHub Fork Sayfanda:
┌─────────────────────────────────────────────────┐
│ This branch is 15 commits behind original:main  │
│                                                 │
│ [Sync fork ▼]    [Contribute ▼]                 │
│                                                 │
│ → "Update branch" tıkla                         │
└─────────────────────────────────────────────────┘

Bu, command line kullanmadan senkronizasyon yapmanı sağlar. Ama terminali bilmek her zaman daha güçlü ve esnek.


Open Source Contribution: Pratik Rehber

İlk Katkını Yapmak

# 1. Proje bul — "good first issue" etiketli issue'ları ara
#    GitHub'da: github.com/topics/good-first-issue

# 2. Projeyi anla
$ git clone git@github.com:tolgahan/proje.git
$ cd proje
$ cat README.md            # Proje ne yapıyor?
$ cat CONTRIBUTING.md      # Katkı kuralları ne?
$ ls                       # Yapı nasıl?

# 3. Fork + Clone + Upstream
$ # (yukarıdaki adımları takip et)

# 4. İyi bir branch ismi seç
$ git switch -c fix/issue-42-login-validation

# 5. Küçük, odaklı değişiklikler yap
$ # Tek bir şeyi düzelt/ekle — dev bir PR gönderme

# 6. Projenin kurallarına uy
$ # - Commit mesajı formatı (Conventional Commits?)
$ # - Kod stili (linter?)  
$ # - Test yazmak gerekiyor mu?

# 7. Push ve PR
$ git push origin fix/issue-42-login-validation
$ # GitHub'da PR aç, issue'a referans ver (Fixes #42)

İyi Bir Pull Request Nasıl Olur?

## PR Başlığı
fix: Login formunda email validasyonu düzeltildi

## Açıklama
### Ne değişti?
- Email regex pattern'ı güncelendi
- Hata mesajı daha açıklayıcı yapıldı
- Edge case testleri eklendi

### Neden?
Mevcut pattern, "user@domain" gibi TLD'siz adresleri
kabul ediyordu. RFC 5322'ye uygun pattern'a geçildi.

### Test
- [x] Mevcut testler geçiyor
- [x] Yeni testler eklendi (3 test case)
- [x] Manuel test yapıldı

### İlişkili Issue
Fixes #42

### Ekran Görüntüsü (gerekiyorsa)
[Login form screenshot]

Contribution Kuralları

✅ YAPILMASI GEREKENLER:
─────────────────────────
1. CONTRIBUTING.md'yi oku — her projenin kuralları farklı
2. Issue aç veya mevcut issue'a yorum yap — "bunu ben yapayım"
3. Küçük PR'lar gönder — 1000 satırlık dev PR kimse review etmek istemez
4. Test yaz — testleri geçen PR kabul edilme şansı çok daha yüksek
5. Sabırlı ol — maintainer'lar gönüllü, cevap gecikebilir

❌ YAPILMAMASI GEREKENLER:
─────────────────────────
1. Sormadan büyük değişiklik yapma
2. Projenin stilini değiştirme (tab→space vs.)
3. İlgisiz değişiklikleri aynı PR'a koyma
4. main'e direkt push etmeye çalışma
5. Review yorumlarını görmezden gelme

💡 İpucu: İlk open source katkın büyük bir özellik olmak zorunda değil. Typo düzeltme, dokümantasyon iyileştirme, test ekleme — hepsi değerli katkılar. Başla, pratiğini yap, özgüven kazan. Zamanla daha büyük katkılara geçersin.


Sparse Checkout: Dev Repo'dan Sadece İstediğini İndir

Büyük bir monorepo düşün — yüzlerce proje, binlerce klasör. Sen sadece frontend/ diziniyle ilgileniyorsun. Tüm repo'yu indirmek gereksiz. Sparse checkout ile sadece ihtiyacın olan dizinleri indirebilirsin.

# 1. Sparse checkout ile clone
$ git clone --filter=blob:none --sparse https://github.com/big-org/monorepo.git
$ cd monorepo

# 2. Sadece istediğin dizinleri ekle
$ git sparse-checkout set frontend/ shared/utils/
# Sadece frontend/ ve shared/utils/ dizinleri indirildi!

$ ls
frontend/  shared/

# 3. Başka bir dizin de lazım oldu
$ git sparse-checkout add backend/api/
$ ls
backend/  frontend/  shared/

# 4. Tüm dosyaları görmek istersen
$ git sparse-checkout disable
Ne zaman kullanılır?
─────────────────────
✅ Büyük monorepo'larda (Google, Meta tarzı)
✅ CI/CD pipeline'larında (sadece ilgili modülü indir)
✅ Disk alanı kısıtlı ortamlarda
✅ --depth 1 ile birlikte ultra hızlı clone

💡 İpucu: --filter=blob:none + --sparse + --depth 1 üçlüsü, dev repo'ları saniyeler içinde indirmeni sağlar. Linux kernel'i gibi GB'larca repo bile bu yöntemle hızlıca kullanılabilir hale gelir.


Clone vs Fork Karar Ağacı

Projeye sadece bakmak/kullanmak istiyorum
└── git clone yeterli

Projeye katkı yapmak istiyorum
├── Projede push yetkim var mı?
│   ├── EVET (ekip üyesiyim) → git clone + branch + push
│   └── HAYIR (dışarıdan katkı) → Fork + Clone + PR
│
Projenin kendi versiyonumu yapmak istiyorum
└── Fork

Pratik Senaryo: Tam Fork Workflow

# Senaryo: "awesome-tools" projesine yeni bir araç ekliyorsun

# 1. Fork (GitHub'da "Fork" butonuna tıkla)

# 2. Fork'u clone'la
$ git clone git@github.com:tolgahan/awesome-tools.git
$ cd awesome-tools

# 3. Upstream ekle
$ git remote add upstream https://github.com/community/awesome-tools.git

# 4. Güncel ol
$ git fetch upstream
$ git rebase upstream/main

# 5. Feature branch
$ git switch -c docs/add-new-tool

# 6. Değişiklik yap
$ echo "- [Git Kraken](https://gitkraken.com) - Git GUI client" >> tools.md
$ git add tools.md
$ git commit -m "docs: GitKraken eklendi"

# 7. Push (kendi fork'una)
$ git push origin docs/add-new-tool

# 8. GitHub'da PR aç
# → "Compare & pull request"
# → Base repo: community/awesome-tools, base: main
# → Head repo: tolgahan/awesome-tools, compare: docs/add-new-tool
# → PR açıklaması yaz
# → "Create pull request"

# 9. Review sürecini bekle
# → Maintainer yorum yapabilir, değişiklik isteyebilir
# → Değişiklik gerekiyorsa:
$ git add tools.md
$ git commit -m "docs: GitKraken açıklaması güncellendi"
$ git push origin docs/add-new-tool
# PR otomatik güncellenir

# 10. PR merge edildi! 🎉
# → Temizlik
$ git switch main
$ git fetch upstream
$ git rebase upstream/main
$ git push origin main
$ git branch -d docs/add-new-tool
$ git push origin --delete docs/add-new-tool

Özet

  • `git clone` bir repository'nin tam kopyasını bilgisayarına indirir — origin remote'u otomatik ayarlanır

  • Fork, GitHub'da başkasının repo'sunu kendi hesabına kopyalar — push yetkisi kazanırsın

  • Fork workflow: Fork → Clone → Upstream ekle → Branch → Commit → Push → Pull Request

  • Upstream remote'u orijinal projeyi temsil eder — düzenli fetch upstream + rebase ile fork'unu güncel tut

  • --depth 1 ile shallow clone yaparak büyük projeleri hızlıca indirebilirsin

  • Open source katkılarda CONTRIBUTING.md'yi oku, küçük başla, sabırlı ol


*Bir sonraki derste SSH vs HTTPS, SSH key yönetimi ve birden fazla GitHub hesabı kullanmayı öğreneceğiz!*