Pull Request
Giriş — Kodunu Teslim Etmeden Önce
Bir yazılım ekibinde çalıştığını düşün. Yeni bir özellik geliştirdin, testlerini yazdın, her şey güzel çalışıyor. Şimdi bu kodu ana branch'e (main) göndermen gerekiyor. Ama direkt push mu edeceksin?
Hayır. Çünkü:
Kod kalitesini kim kontrol edecek?
Takım arkadaşların değişikliklerden haberdar olacak mı?
Bir hata varsa, main branch bozulursa ne olacak?
İşte Pull Request (kısaca PR), tam da bu sorunları çözmek için var. PR, "kodumu ana dalınıza almak istiyorum, lütfen inceleyin" demenin resmi yoludur.
Pull Request Nedir?
Analoji — Bir Makaleyi Yayınlamadan Önce
Bir gazeteci düşün. Makalesini yazıp direkt baskıya vermez. Önce editörüne gönderir. Editör okur, notlar düşer: "Bu paragraf belirsiz", "Bu iddiayı kaynakla destekle", "Başlık daha çarpıcı olabilir". Gazeteci düzeltir, tekrar gönderir. Editör onaylar, makale yayınlanır.
Pull Request tam olarak bu süreçtir:
Gazeteci (Yazar) → Developer (Branch'te çalışan)
Makale → Kod değişiklikleri
Editör → Reviewer (Kod inceleyici)
Editoryal notlar → Code review yorumları
Yayın onayı → PR approval + merge
Gazete baskısı → main branch'e mergeTeknik Tanım
Pull Request, bir branch'teki değişiklikleri başka bir branch'e (genellikle main veya develop) birleştirme isteğidir. GitHub bu isteği bir tartışma alanı haline getirir: değişiklikleri görebilir, yorum yapabilir, onaylayabilir veya reddedebilirsin.
feature/login ─── commit ─── commit ─── commit
│
Pull Request
│
▼
main ─────────────────────────── merge commitPR Oluşturma Süreci
Adım 1: Branch Oluştur ve Çalış
# Ana branch'ten yeni bir feature branch oluştur
git checkout main
git pull origin main
git checkout -b feature/user-authentication
# Kodunu yaz...
# Dosyaları düzenle, test et
# Commit'le
git add .
git commit -m "feat: add user authentication with JWT"
# Birkaç commit daha...
git add .
git commit -m "feat: add login and register endpoints"
git add .
git commit -m "test: add auth unit tests"Adım 2: Push Et
git push -u origin feature/user-authenticationTerminal çıktısı:
Enumerating objects: 15, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 8 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (12/12), 2.45 KiB | 2.45 MiB/s, done.
Total 12 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), completed with 2 local objects.
remote:
remote: Create a pull request for 'feature/user-authentication' on GitHub by visiting:
remote: https://github.com/username/project/pull/new/feature/user-authentication
remote:
To github.com:username/project.git
* [new branch] feature/user-authentication -> feature/user-authentication
Branch 'feature/user-authentication' set up to track remote branch 'feature/user-authentication' from 'origin'.💡 İpucu: Git push yaptıktan sonra terminal'de PR oluşturma linki verir. Bu linke tıklayarak doğrudan PR sayfasına gidebilirsin.
Adım 3: PR Oluştur (Web Arayüzü)
GitHub'da repo sayfasına git. Üstte sarı bir banner görürsün:
┌──────────────────────────────────────────────────────────────┐
│ 🔔 feature/user-authentication had recent pushes 2 min ago │
│ [Compare & pull request] │
└──────────────────────────────────────────────────────────────┘Compare & pull request butonuna tıkla. PR formunu doldur:
base: main ← compare: feature/user-authentication
Title: feat: Add user authentication with JWT
Description:
## Neler Değişti?
- JWT tabanlı kullanıcı kimlik doğrulama sistemi eklendi
- Login ve register endpoint'leri oluşturuldu
- Birim testleri yazıldı
## Test Edildi mi?
- [x] Unit testler geçiyor
- [x] Manuel test yapıldı
- [ ] Integration test (henüz yok, sonraki PR'da)
## Ekran Görüntüsü
(API endpoint'leri için Postman screenshot'ı)
## İlgili Issue
Closes #42
Reviewers: @ahmet @ayse
Assignees: @ben
Labels: feature, authentication
Milestone: v1.0Adım 3 (Alternatif): PR Oluştur (GitHub CLI)
# Basit PR oluşturma
gh pr create --title "feat: Add user authentication" --body "JWT auth sistemi eklendi"
# Detaylı PR oluşturma
gh pr create \
--title "feat: Add user authentication with JWT" \
--body "## Değişiklikler
- JWT auth eklendi
- Login/register endpoint'leri
Closes #42" \
--reviewer ahmet,ayse \
--assignee @me \
--label "feature,authentication" \
--milestone "v1.0"
# İnteraktif mod (adım adım sorar)
gh pr creategh pr create interaktif çıktısı:
Creating pull request for feature/user-authentication into main in username/project
? Title: feat: Add user authentication with JWT
? Body: <Received>
? What's next? Submit
https://github.com/username/project/pull/47PR Template
Her PR'da aynı yapıda bilgi istemek için template oluşturabilirsin:
# .github/PULL_REQUEST_TEMPLATE.md dosyası oluştur
mkdir -p .github
cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF'
## 📋 Açıklama
<!-- Bu PR ne yapıyor? Neden gerekli? -->
## 🔄 Değişiklik Türü
- [ ] 🐛 Bug fix
- [ ] ✨ Yeni özellik
- [ ] 💥 Breaking change
- [ ] 📝 Dokümantasyon
- [ ] 🎨 Stil/format
- [ ] ♻️ Refactoring
- [ ] ⚡ Performans
## 🧪 Test
- [ ] Mevcut testler geçiyor
- [ ] Yeni testler eklendi
- [ ] Manuel test yapıldı
## 📸 Ekran Görüntüsü (varsa)
## 🔗 İlgili Issue
<!-- Closes #issue_number -->
## ✅ Checklist
- [ ] Kod self-review yapıldı
- [ ] Yorum eklendi (gerekli yerlere)
- [ ] Dokümantasyon güncellendi
- [ ] Breaking change yok (varsa açıkla)
EOF
git add .github/PULL_REQUEST_TEMPLATE.md
git commit -m "Add PR template"Bu template, her yeni PR açıldığında otomatik olarak açıklama alanında görünür. Ekip üyeleri doldurup gönderir.
Draft Pull Request
Bazen kodun henüz hazır değildir ama erken geri bildirim almak istersin. Ya da "üzerinde çalışıyorum" demek istersin. İşte bunun için Draft PR var.
Draft PR vs Normal PR
Normal PR:
→ "Kodum hazır, incelemeye alın"
→ Merge edilebilir
→ Reviewer'lar atanabilir
Draft PR:
→ "Henüz çalışıyorum, ama bakabilirsiniz"
→ Merge edilemez (butonu devre dışı)
→ Erken geri bildirim alabilirsin
→ Hazır olduğunda "Ready for review" yaparsınDraft PR Oluşturma
# Web arayüzünde:
# "Create pull request" butonunun yanındaki oku tıkla
# → "Create draft pull request" seç
# GitHub CLI ile:
gh pr create --draft --title "WIP: Add payment integration"Draft'tan Ready'ye Geçiş
# Web arayüzünde:
# PR sayfasında "Ready for review" butonuna tıkla
# GitHub CLI ile:
gh pr ready 47 # PR numarası💡 İpucu: Draft PR'lar, büyük özellikleri parçalara ayırıp erken geri bildirim almak için harikadır. "90% bitti ama şu kısımda fikrinizi merak ediyorum" gibi durumlar için biçilmiş kaftan.
PR İnceleme Süreci
Bir PR açıldığında, reviewer'lar kodu inceler. İşte bu sürecin anatomisi:
Review Türleri
┌─────────────────────────────────────────────────────────┐
│ PR REVIEW TÜRLERİ │
├─────────────────────────────────────────────────────────┤
│ │
│ ✅ Approve │
│ "Kod iyi görünüyor, merge edilebilir" │
│ │
│ 💬 Comment │
│ "Birkaç sorum/önerim var ama engel değil" │
│ │
│ ❌ Request Changes │
│ "Bu değişiklikler yapılmadan merge edilemez" │
│ │
└─────────────────────────────────────────────────────────┘Review Akışı
Developer Reviewer GitHub
│ │ │
├── PR oluştur ──┼────────────────►│
│ │◄── bildirim ────┤
│ │ │
│ ├── kodu incele ──►│
│ ├── yorum yaz ───►│
│ ├── değişiklik ──►│
│ │ iste │
│◄── bildirim ───┤ │
│ │ │
├── düzelt ──────┼────────────────►│
├── push et ─────┼────────────────►│
│ │◄── bildirim ────┤
│ │ │
│ ├── tekrar incele►│
│ ├── onayla ──────►│
│ │ │
├── merge et ────┼────────────────►│
│ │ │Satır Bazlı Yorum Yapma
PR'ın "Files changed" sekmesinde, herhangi bir satırın yanındaki + ikonuna tıklayarak o satıra özel yorum yazabilirsin:
// auth.js dosyasında değişiklik
+ function validateToken(token) {
+ const decoded = jwt.verify(token, SECRET_KEY);
+ return decoded;
+ }Reviewer yorumu:
💬 @ahmet: Bu fonksiyon jwt.verify başarısız olursa hata fırlatır.
Try-catch ile sarmalaman lazım. Ayrıca SECRET_KEY'i environment
variable'dan al, hardcode etme.Suggesting Changes
GitHub'ın çok güçlü bir özelliği: reviewer, direkt kod önerisi yapabilir ve PR sahibi tek tıkla uygulayabilir.
Yorumda suggestion bloğu kullanarak:
```suggestion
function validateToken(token) {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return { success: true, data: decoded };
} catch (error) {
return { success: false, error: error.message };
}
}
PR sahibi **"Commit suggestion"** butonuna tıklayarak bu değişikliği doğrudan uygular. Manuel düzenleme gerekmez!
---
## Merge Stratejileri
PR onaylandıktan sonra merge zamanı gelir. GitHub üç farklı merge stratejisi sunar ve hangisini seçtiğin **projenin commit tarihçesini** doğrudan etkiler.
### 1. Create a Merge Commit (Varsayılan)
feature A───B───C / \ main ───X───────────M─── (M = merge commit)
- Tüm commit'ler olduğu gibi kalır
- Ekstra bir merge commit oluşur
- Branch'in tüm tarihçesi korunur
- `--no-ff` (no fast-forward) ile birleştirilir
```bash
# Terminal'de karşılığı:
git merge --no-ff feature/user-authNe zaman kullanılır?
Her bir commit'in tarihçesini korumak istediğinde
Hangi commit'lerin hangi feature'a ait olduğunu görmek istediğinde
Büyük ve karmaşık projelerde
2. Squash and Merge
feature A───B───C
/
main ───X───────────S─── (S = squash commit, A+B+C birleşti)Feature branch'teki TÜM commit'ler tek bir commit'e sıkıştırılır
Ana branch'in tarihçesi temiz ve lineer kalır
Detaylı commit mesajları kaybolur (ama PR'da hâlâ görünür)
# Terminal'de karşılığı:
git merge --squash feature/user-auth
git commit -m "feat: Add user authentication (#47)"Ne zaman kullanılır?
Feature branch'te çok fazla "WIP", "fix typo", "oops" commit'i varsa
Temiz, okunabilir bir main tarihçesi istiyorsan
Her PR'ın tek bir commit olarak görünmesini istiyorsan
3. Rebase and Merge
feature A───B───C
/
main ───X───A'───B'───C'─── (commit'ler yeniden yazıldı, tekil dizildi)Feature branch'teki commit'ler main'in ucuna yeniden uygulanır
Merge commit oluşmaz
Tamamen lineer bir tarihçe elde edersin
Commit hash'leri değişir (yeni commit'ler oluşur)
# Terminal'de karşılığı:
git rebase main feature/user-auth
git checkout main
git merge feature/user-auth # fast-forward olurNe zaman kullanılır?
Her commit'in anlamlı ve atomik olduğu durumlarda
Çok temiz, lineer bir tarihçe istediğinde
Commit'lerin bağımsız olarak
git bisectile aranabilir olmasını istediğinde
Karşılaştırma Tablosu
┌─────────────────────┬──────────┬──────────┬──────────┐
│ Özellik │ Merge │ Squash │ Rebase │
├─────────────────────┼──────────┼──────────┼──────────┤
│ Commit korunur │ ✅ │ ❌ │ ✅* │
│ Merge commit │ ✅ │ ❌ │ ❌ │
│ Lineer tarihçe │ ❌ │ ✅ │ ✅ │
│ PR detayı görünür │ ✅ │ ✅** │ ✅ │
│ Kolay revert │ ✅ │ ✅ │ ⚠️ │
│ Branch ilişkisi │ Görünür │ Kaybolur │ Kaybolur │
│ Tarihçe karmaşıklığı│ Yüksek │ Düşük │ Düşük │
└─────────────────────┴──────────┴──────────┴──────────┘
* Hash'ler değişir (yeni commit'ler oluşur)
** PR sayfasında orijinal commit'ler hâlâ görünürHangi Stratejiyi Seçmeli?
Açık kaynak proje (çok katkıcı) → Squash and Merge
Her katkıcının commit stili farklı, squash ile temizlenir
Kurumsal proje (düzenli ekip) → Merge Commit veya Squash
Merge commit: audit trail önemli
Squash: temiz tarihçe tercih ediliyor
Kişisel proje (tek geliştirici) → Rebase and Merge
Commit'lerin zaten düzenli, lineer tarihçe güzel görünür
Çok büyük PR (50+ commit) → Squash and Merge
50 commit'i tarihçede görmek istemezsin💡 İpucu: Bir repository'de Settings → General → Pull Requests altında hangi merge stratejilerinin kullanılabilir olacağını belirleyebilirsin. Örneğin, sadece "Squash and merge"e izin verip diğerlerini kapatabilirsin. Böylece tüm ekip aynı stratejiyi kullanmak zorunda kalır.
PR Yaşam Döngüsü
Bir PR'ın açılmasından kapanmasına kadar geçen süreçteki durumlar:
┌────────────┐
│ Open │──── Review ──── Approve ──── Merge ──── Closed
│ (Açıldı) │ (Merged)
└─────┬──────┘
│
├──── Request Changes ──── Fix ──── Re-review ──── Approve ──── Merge
│
├──── Conflict! ──── Resolve ──── Re-review
│
└──── Close without merge (Reddedildi / Vazgeçildi)PR'ı Güncel Tutma
main branch ilerlerken senin PR'ın geride kalabilir. Conflict çıkabilir. Bunu çözmek için:
# Yöntem 1: main'i merge et (merge commit oluşur)
git checkout feature/user-auth
git fetch origin
git merge origin/main
# Conflict varsa çöz
git push
# Yöntem 2: main üzerine rebase et (temiz tarihçe)
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# Conflict varsa çöz
git push --force-with-lease⚠️ Dikkat:
git push --force-with-leasekullanırken dikkatli ol. Bu komut remote'taki branch'i yeniden yazıyor. Eğer başka biri de aynı branch'e push ettiyse, onun değişiklikleri kaybolabilir.--force-with-leaseen azından bu durumu kontrol eder ve uyarır.
GitHub'da da "Update branch" butonu var — bu, main'i PR branch'ine merge eder veya rebase eder (ayara göre).
PR ile İlgili GitHub CLI Komutları
# PR listele
gh pr list
gh pr list --state open
gh pr list --state closed
gh pr list --state merged
# PR detayını görüntüle
gh pr view 47
gh pr view 47 --web # Tarayıcıda aç
# PR'ı kontrol et (branch'e geç)
gh pr checkout 47
# PR'daki değişiklikleri gör
gh pr diff 47
# PR'ı onayla
gh pr review 47 --approve --body "LGTM! 🚀"
# PR'a değişiklik iste
gh pr review 47 --request-changes --body "Lütfen hata yönetimini ekle"
# PR'ı merge et
gh pr merge 47 --merge # merge commit ile
gh pr merge 47 --squash # squash ile
gh pr merge 47 --rebase # rebase ile
# Merge sonrası branch'i sil
gh pr merge 47 --squash --delete-branch
# PR'ı kapat (merge etmeden)
gh pr close 47Linked Issues — PR ve Issue Bağlantısı
PR'ı bir issue ile ilişkilendirebilirsin. Böylece PR merge edildiğinde issue otomatik olarak kapanır:
# PR açıklamasında şu anahtar kelimeleri kullan:
Closes #42
Fixes #42
Resolves #42
# Birden fazla issue kapatmak için:
Closes #42, closes #43, closes #44
# Farklı repo'daki issue:
Closes username/other-repo#42Issue #42: "Login sayfası çalışmıyor"
│
├── PR #47: "feat: Fix login page"
│ Description: "Closes #42"
│
└── PR #47 merge edildiğinde
→ Issue #42 otomatik kapanır ✅PR Best Practices
İyi Bir PR Nasıl Olmalı?
1. KÜÇÜK TUTUN
❌ 50 dosya, 3000 satır değişiklik
✅ 5-10 dosya, 200-400 satır değişiklik
Neden? Büyük PR'lar:
- İncelenmesi zor
- Hata kaçırma olasılığı yüksek
- Conflict olasılığı yüksek
- "LGTM" (Looks Good To Me) deyip geçilir
2. TEK SORUMLULUK
❌ Auth + Database migration + CSS fix hepsi bir PR'da
✅ Her PR tek bir şey yapar
3. AÇIKLAYICI BAŞLIK
❌ "Fix stuff"
❌ "Update code"
✅ "feat: Add JWT authentication to API endpoints"
✅ "fix: Resolve login redirect loop on expired tokens"
4. BAĞLAM VER
- Neden bu değişiklik gerekli?
- Ne değişti? (özet)
- Nasıl test edildi?
- Ekran görüntüsü (UI değişikliği varsa)
- İlgili issue numarası
5. SELF-REVIEW YAP
PR'ı açmadan önce kendi kodunu bir kez incele.
Typo'lar, debug log'ları, gereksiz dosyalar...PR Boyutu ve İnceleme Kalitesi
Satır Sayısı İnceleme Kalitesi Tahmini Süre
───────────── ───────────────── ────────────
1-50 ⭐⭐⭐⭐⭐ Mükemmel 5-10 dk
50-200 ⭐⭐⭐⭐ İyi 15-30 dk
200-500 ⭐⭐⭐ Orta 30-60 dk
500-1000 ⭐⭐ Zayıf 1-2 saat
1000+ ⭐ "LGTM" 😅 Kimse okumaz💡 İpucu: Google'ın iç araştırmasına göre, 200 satırdan küçük PR'lar en yüksek kalitede incelenir. "Küçük PR, hızlı merge" — bu altın kuralı unutma.
Auto-merge ve Merge Queue
Auto-merge
Tüm kontroller (CI testleri, review onayı) geçtiğinde PR'ın otomatik merge edilmesini sağlayabilirsin:
# GitHub CLI ile auto-merge etkinleştir
gh pr merge 47 --auto --squash
# Web arayüzünde:
# PR sayfasında "Enable auto-merge" butonuna tıklaBu özelliğin çalışması için:
Repository ayarlarında auto-merge etkin olmalı
Branch protection rules tanımlı olmalı
Gerekli tüm kontroller (CI, review) geçmeli
Merge Queue (Birleştirme Kuyruğu)
Büyük ekiplerde birçok PR aynı anda merge edilmek ister. Merge queue, PR'ları sıraya alır ve her birini sırayla test edip merge eder:
PR #47 ──┐
PR #48 ──┼── Merge Queue ── Test → Merge → Test → Merge → ...
PR #49 ──┘Bu, "main branch her zaman yeşil (çalışır durumda) kalsın" ilkesini garanti eder.
Yaygın PR Hataları
1. Dev PR Açmak
# ❌ 3 haftadır tek branch'te çalışıyorsun, 80 dosya değişti
# Reviewer: "Bu PR çok büyük, parçalara ayırır mısın?"
# ✅ Büyük feature'ları küçük, bağımsız PR'lara böl:
# PR #1: Database schema değişiklikleri
# PR #2: API endpoint'leri
# PR #3: Frontend entegrasyonu
# PR #4: Testler2. Force Push ile Review Kaybetme
# ❌ Reviewer yorum yapmış, sen force push ile commit'leri yeniden yazdın
# Reviewer'ın yorumları artık hangi koda ait belli değil!
# ✅ Review sürecinde force push yerine yeni commit ekle
# Merge sırasında squash kullanarak temizle3. Conflict'i Çözmeden Beklemek
# ❌ "Conflict var ama birisi çözer" diye beklemek
# Zaman geçtikce conflict büyür!
# ✅ Conflict çıktığında hemen çöz
git fetch origin
git merge origin/main
# veya
git rebase origin/mainPratik Senaryo: Tam Bir PR Akışı
# 1. Güncel main'den başla
git checkout main
git pull origin main
# 2. Feature branch oluştur
git checkout -b feature/dark-mode
# 3. Kod yaz
cat > src/theme.js << 'EOF'
export const themes = {
light: {
background: '#ffffff',
text: '#000000',
primary: '#007bff'
},
dark: {
background: '#1a1a2e',
text: '#e0e0e0',
primary: '#4dabf7'
}
};
export function applyTheme(themeName) {
const theme = themes[themeName];
if (!theme) throw new Error(`Unknown theme: ${themeName}`);
Object.entries(theme).forEach(([key, value]) => {
document.documentElement.style.setProperty(`--${key}`, value);
});
}
EOF
# 4. Test yaz
cat > tests/theme.test.js << 'EOF'
import { themes, applyTheme } from '../src/theme';
test('should have light and dark themes', () => {
expect(themes.light).toBeDefined();
expect(themes.dark).toBeDefined();
});
test('should throw for unknown theme', () => {
expect(() => applyTheme('neon')).toThrow('Unknown theme: neon');
});
EOF
# 5. Commit ve push
git add .
git commit -m "feat: add dark mode theme support"
git push -u origin feature/dark-mode
# 6. PR oluştur
gh pr create \
--title "feat: Add dark mode theme support" \
--body "## Açıklama
Dark mode desteği eklendi. Kullanıcılar light/dark tema seçebilir.
## Test
- [x] Unit testler eklendi
- [x] Manuel test yapıldı
Closes #15" \
--reviewer senior-dev \
--label "feature,ui"
# 7. Review sonrası düzeltme gerekirse
# ... düzelt, commit et, push et
git add .
git commit -m "fix: handle theme persistence in localStorage"
git push
# 8. Onay gelince merge et
gh pr merge --squash --delete-branchÖzet
Bu derste Pull Request'in tüm detaylarını öğrendik:
Pull Request, bir branch'teki değişiklikleri ana branch'e alma isteğidir — ekip işbirliğinin temelidir
Draft PR, henüz hazır olmayan ama erken geri bildirim almak istediğin değişiklikler için kullanılır
PR Template ile ekipteki herkes aynı yapıda PR açar — tutarlılık sağlanır
Üç merge stratejisi var: Merge commit (tarihçe korunur), Squash (tek commit'e sıkışır), Rebase (lineer tarihçe) — projenin ihtiyacına göre seç
Küçük PR'lar daha hızlı ve kaliteli incelenir — 200 satır altı ideal
Linked Issues ile PR merge edildiğinde ilgili issue otomatik kapanır (
Closes #42)Auto-merge ve Merge Queue ile CI/CD süreçleriyle entegre, otomatik birleştirme yapılabilir
Bir sonraki derste GitHub'ın proje yönetim araçlarını göreceğiz: Issues, Labels, Milestones ve Projects.
AI Asistan
Sorularını yanıtlamaya hazır