Git Nedir? Her Geliştiricinin Ustalaşması Gereken Versiyon Kontrol Sistemi
İlk kez git push yaptığınızda sihir gibi hissettiriyor. Sonra ilk merge conflict'inizle karşılaşıyorsunuz ve sihir aniden kabuğa dönüşüyor.
Git, dünya genelinde milyonlarca geliştirici tarafından kullanılan dağıtık versiyon kontrol sistemidir. Ama çoğu geliştirici Git'i gerçek anlamda öğrenmeden kullanır — add, commit, push, pull döngüsünde sıkışıp kalır ve işler karıştığında panikler. Bu yazı o döngüden çıkmak için gereken zihinsel modeli inşa ediyor.
Git Neden Var?
Hayal edin: Bir projede 5 geliştirici çalışıyor. Herkes aynı dosyaları düzenliyor. Biri bir özellik eklerken diğeri kritik bir bug düzeltiyor. Üçüncüsü ise her şeyi yeniden yapılandırmaya çalışıyor.
Git olmadan bu kaos olur. Dosyaları proje_final_v2_GERÇEKSON.zip gibi isimlerle kaydedersiniz. Kimin ne değiştirdiğini bilemezsiniz. Bir şey bozulduğunda neyin değiştiğini bulamazsınız.
Git bu problemi üç temel fikirle çözer: her değişikliği kayıt altına almak, paralel çalışmaya izin vermek ve geçmişe dönmeyi mümkün kılmak.
Repository, Commit, Branch: Temel Kavramlar
Repository (Repo), projenizin tüm dosyalarını ve değişiklik geçmişini içeren yerdir. Yerel makinenizde .git klasörü olarak yaşar. git init ile oluşturulur ya da git clone ile bir yerden kopyalanır.
Commit, bir an'ın fotoğrafıdır. "Bu noktada kod tam olarak buydu" diyen bir kayıttır. Her commit'in benzersiz bir hash'i vardır — a3f8c2d gibi. Commit mesajları bu yüzden önemlidir; iyi bir commit mesajı o değişikliğin ne yaptığını değil, neden yapıldığını açıklar.
# Kötü commit mesajı git commit -m "düzeltme" # İyi commit mesajı git commit -m "fix: kullanıcı girişinde boş email ile crash düzeltildi"
Branch, bağımsız bir geliştirme hattıdır. Ana koddan ayrılıp kendi değişikliklerinizi yapabileceğiniz izole bir alan. main branch'i production kodunu temsil ederken, feature/user-auth gibi branch'ler geliştirme sürecindeki özellikleri barındırır.
git branch feature/payment-integration # branch oluştur git checkout feature/payment-integration # branch'e geç # ya da tek komutla: git checkout -b feature/payment-integration
Staging Area: Çoğunun Atladığı Kavram
Git'in anlaşılması en zor kavramlarından biri staging area (index). Çalışma dizininiz ile commit geçmişiniz arasındaki ara bölgedir.
Çalışma Dizini → Staging Area → Repository
(değişiklik) (git add) (git commit)
Neden böyle bir ara katman var? Çünkü bazen birden fazla değişiklik yaparsınız ama bunları ayrı commit'lere bölmek istersiniz. Staging area sayesinde hangi değişikliklerin bu commit'e dahil olacağını seçebilirsiniz.
git add src/auth/login.js # sadece bu dosyayı stage'le git add src/auth/ # tüm klasörü stage'le git add -p # değişiklikleri parça parça seç (çok güçlü) git status # ne stage'lendi, ne değişti gör
Merge vs Rebase: En Çok Kafayı Karıştıran Konu
İki branch'i birleştirmenin iki yolu var: merge ve rebase. İkisi de aynı sonuca ulaşır ama geçmiş farklı görünür.
Merge, iki branch'in geçmişini birleştirir ve yeni bir "merge commit" oluşturur. Geçmiş olduğu gibi korunur, ne zaman ne olduğu açıkça görünür.
git checkout main git merge feature/payment-integration
Rebase, branch'inizin commit'lerini alır ve sanki main'in en son hali üzerine yazılmış gibi yeniden uygular. Geçmiş daha temiz ve lineer görünür.
git checkout feature/payment-integration git rebase main
Hangisini kullanmalı? Genel kural: paylaşılan branch'lerde merge, kişisel feature branch'lerinde rebase. Rebase geçmişi yeniden yazar, bu yüzden başkalarının da kullandığı bir branch'te rebase yapmak sorun çıkarır.
Merge Conflict: Paniklemeden Çözme
Merge conflict, iki branch'in aynı dosyanın aynı satırını farklı şekillerde değiştirdiğinde oluşur. Git hangi versiyonun doğru olduğuna karar veremez ve sizden çözmenizi ister.
Conflict işaretleri şöyle görünür:
<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> feature/performance-improvements
HEAD sizin mevcut branch'inizdeki versiyon, altındaki ise merge etmeye çalıştığınız branch'teki versiyon. İki seçenekten birini seçer ya da ikisini birleştirirsiniz, işaretleri silersiniz ve commit'lersiniz.
git add src/config.js # conflict'i çözüldü olarak işaretle git commit # merge'i tamamla
Günlük Hayatı Kolaylaştıran Komutlar
git stash — Yarım bıraktığınız değişiklikleri geçici olarak saklar. Acil bir bug fix yapmanız gerektiğinde branch değiştirmeden önce idealdir.
git stash # değişiklikleri sakla git stash pop # sakladıklarını geri getir git stash list # saklananları listele
git log — Commit geçmişini gösterir. --oneline ile özet görünüm, --graph ile görsel ağaç.
git log --oneline --graph --all
git diff — Neyin değiştiğini gösterir. Commit'lemeden önce ne yaptığınızı gözden geçirmek için kritik.
git diff # stage'lenmemiş değişiklikler git diff --staged # stage'lenmiş değişiklikler git diff main..feature/x # iki branch arasındaki fark
git reset ve git revert — Hataları geri almak için. reset geçmişi değiştirir (dikkatli kullanın), revert yeni bir commit ile değişikliği geri alır (güvenli).
git revert a3f8c2d # o commit'i geri alan yeni commit oluşturur git reset --soft HEAD~1 # son commit'i geri al, değişiklikler kalır
Branch Stratejileri: Takımlarda Nasıl Çalışılır
Git Flow — main, develop, feature/*, release/*, hotfix/* branch'lerinden oluşan yapılandırılmış bir strateji. Büyük ekipler ve planlı release döngüleri için uygundur.
GitHub Flow — Daha basit. Sadece main ve feature branch'leri var. Her özellik bir branch'te geliştirilir, Pull Request açılır, review sonrası `main``e merge edilir. Sürekli deployment yapan ekipler için idealdir.
Trunk-Based Development — Herkes doğrudan main'e küçük commit'ler atar. Feature flag'ler ile henüz hazır olmayan özellikler gizlenir. CI/CD ile birlikte en hızlı delivery sağlar.
Hangi strateji doğru? Takımınızın büyüklüğüne, release sıklığınıza ve olgunluk seviyenize göre değişir. Beş kişilik bir startup için GitHub Flow yeterliyken, yüzlerce geliştirici olan bir üründe Git Flow daha fazla kontrol sağlar.
.gitignore: Neyi Commit Etmemelisiniz
Her projede commit edilmemesi gereken dosyalar var. node_modules, build çıktıları, .env dosyaları, IDE ayarları. .gitignore dosyası bu dosyaları Git'in radarından çıkarır.
# .gitignore örneği
node_modules/
dist/
.env
.env.local
*.log
.DS_Store
.idea/
.vscode/
En önemli kural: .env dosyalarını asla commit etmeyin. API anahtarları, database şifreleri, secret'lar — bunlar .env'de yaşar ve .gitignore'da olur.
Git Öğrenmek Bitmez
git bisect ile binary search yaparak hangi commit'in bug'ı eklediğini bulabilirsiniz. git cherry-pick ile başka bir branch'ten tek bir commit'i alabilirsiniz. git reflog ile sildiğinizi sandığınız her şeyi geri getirebilirsiniz.
Git, ne kadar derine inerseniz o kadar güçlü bir araç. Ama derinliğe inmek için temeli sağlam kurmak şart. add, commit, push döngüsünün ötesine geçtiğinizde, Git bir versiyon kontrol aracı olmaktan çıkıp kodunuzu anlayan bir iş arkadaşına dönüşür.