Git Ignore Dosyası Oluşturma ve Kullanımı
Yeni bir projeye başladığınızda Git reponuza ilk commit’i atmadan önce yapmanız gereken en önemli şeylerden biri .gitignore dosyasını doğru kurmaktır. Bunu ihmal ettiğinizde ne olur? Birkaç hafta sonra git status çıktınızda yüzlerce gereksiz dosya görürsünüz, takım arkadaşlarınız sizin IDE ayar dosyalarınızı kendi makinelerine çeker ve her şey karışır. Üstelik hassas bilgi içeren bir .env dosyasını yanlışlıkla commit’lemişseniz, bu sefer iş ciddi bir hal alır. Bu yazıda .gitignore dosyasının nasıl çalıştığını, nasıl yazıldığını ve gerçek dünya projelerinde nasıl kullanılması gerektiğini mümkün olduğunca pratik bir şekilde ele alacağız.
.gitignore Nedir ve Neden Bu Kadar Önemlidir?
.gitignore, Git’e hangi dosyaların ve dizinlerin takip edilmemesi gerektiğini söyleyen düz metin bir yapılandırma dosyasıdır. Git, bu dosyada listelenen kalıplarla eşleşen dosyaları untracked olarak değil, tamamen “görünmez” olarak değerlendirir. Yani git status, git add . veya git diff gibi komutlar bu dosyaları hiç görmez.
Peki neden bu kadar kritik? Şu senaryoları düşünelim:
- Node.js projesinde
node_modules/klasörü yüz binlerce dosya içerebilir. Bunları repoya eklemek hem repoyu şişirir hem de anlamsız bir yük oluşturur. - Python projesinde
__pycache__/ve.pycdosyaları her makinede farklı binary içerik üretir, merge conflict’lere davetiye çıkarır. .envdosyanızda veritabanı şifreleri, API anahtarları, JWT secret’ları duruyorsa bunların GitHub’a gitmesi felakete yol açabilir.- JetBrains IDE’nin ürettiği
.idea/klasörü ya da VS Code’un.vscode/klasörü sizin özel yapılandırmalarınızı içerir, başkasının makinesinde farklı davranır.
Bu sorunları yaşayan birçok ekip gördüm. Özellikle .env kazaları gerçekten can sıkıcı sonuçlar doğuruyor. Birinin AWS secret key’ini public repoya gönderdiği ve birkaç dakika içinde o key’in kötüye kullanıldığı vakalar sektörde yaygın.
Temel Sözdizimi ve Kalıp Kuralları
.gitignore dosyasının sözdizimi oldukça sezgisel ama bazı nüansları var. Bunları doğrudan örneklerle görelim.
# Bu bir yorum satırıdır
# Boş satırlar yoksayılır
# Spesifik bir dosyayı yoksay
.env
secrets.txt
# Belirli bir uzantıdaki tüm dosyaları yoksay
*.log
*.tmp
*.swp
# Spesifik bir dizini yoksay (sondaki / önemli)
node_modules/
dist/
build/
__pycache__/
# Belirli bir dizin içindeki dosyayı yoksay
config/database.yml
# Tüm alt dizinlerdeki belirli dosyaları yoksay
**/secrets.json
# Yoksama kuralını geçersiz kıl (! ile)
*.log
!important.log
# Sadece kök dizindeki bir dosyayı yoksay
/TODO
# İki yıldız ile her seviyedeki eşleşme
logs/**/*.log
Birkaç kritik noktayı vurgulamak istiyorum:
Sondaki / işareti: node_modules yazarsanız bu isimde hem dosyayı hem dizini yoksayar. node_modules/ yazarsanız sadece dizini hedef alırsınız. Alışkanlık olarak dizinleri her zaman / ile sonlandırın.
! (ünlem) operatörü: Daha önce tanımlanmış bir yoksama kuralını belirli dosyalar için iptal eder. Örneğin tüm log dosyalarını yoksaymak ama error.log‘u takip etmek istiyorsanız kullanışlıdır. Ama dikkat: eğer bir dizin zaten yoksanmışsa, o dizin içindeki dosyaları ! ile geri getiremezsiniz.
(çift yıldız): Dizin derinliği fark etmeksizin eşleşme sağlar. /logs ifadesi reponun herhangi bir seviyesindeki logs adlı dizini yakalar.
Yaygın Proje Türleri için .gitignore Şablonları
Node.js / JavaScript Projesi
# Bağımlılıklar
node_modules/
.pnp
.pnp.js
# Build çıktıları
dist/
build/
out/
.next/
.nuxt/
# Ortam değişkenleri (EN ÖNEMLİSİ)
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Log dosyaları
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.log
# Runtime dosyalar
pids/
*.pid
*.seed
*.pid.lock
# Coverage raporları
coverage/
.nyc_output/
# IDE/Editor dosyaları
.idea/
.vscode/
*.suo
*.ntvs*
*.njsproj
*.sln
Python Projesi
# Byte-compile / optimize edilmiş / DLL dosyaları
__pycache__/
*.py[cod]
*$py.class
*.pyc
# Virtual environment'lar
venv/
env/
.venv/
.env/
ENV/
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Test araçları
.pytest_cache/
.coverage
htmlcov/
.tox/
.nox/
# Jupyter Notebook
.ipynb_checkpoints
# Ortam dosyaları
.env
*.env
config/secrets.py
# mypy type checker
.mypy_cache/
.dmypy.json
Java / Maven / Gradle Projesi
# Compiled class dosyaları
*.class
# Log dosyaları
*.log
# BlueJ dosyaları
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
# Gradle
.gradle/
build/
gradle-wrapper.jar
# IDE dosyaları
.idea/
*.iws
*.iml
*.ipr
.classpath
.project
.settings/
gitignore.io ile Otomatik Şablon Oluşturma
Her seferinde sıfırdan yazmak zorunda değilsiniz. gitignore.io (artık toptal.com/developers/gitignore adresinde) sitesi ve aynı adlı CLI aracı, belirttiğiniz teknoloji stack’ine göre kapsamlı .gitignore dosyaları üretiyor.
# curl ile direkt oluştur
curl -sL https://www.toptal.com/developers/gitignore/api/python,django,visualstudiocode > .gitignore
# Veya gi aracını kullanabilirsiniz
# Önce aracı kurun
git config --global alias.ignore '!gi() { curl -sL https://www.toptal.com/developers/gitignore/api/$@ ;}; gi'
# Kullanımı
git ignore node,react,linux,macos,windows > .gitignore
# Hangi template'ler var?
curl -sL https://www.toptal.com/developers/gitignore/api/list
Bu araç güzel bir başlangıç noktası sunuyor ama körce kullanmayın. Üretilen dosyayı mutlaka projenize göre gözden geçirin, gereksiz satırları silin, projeye özgü ihtiyaçlarınızı ekleyin.
Zaten Commit’lenmiş Dosyaları .gitignore’a Eklemek
İşte sık yaşanan ve insanları çıldırtan durum: .gitignore‘a bir kural eklediniz ama ilgili dosya zaten daha önce commit’lenmişti. Bu durumda .gitignore o dosya için işe yaramaz. Git o dosyayı hala takip etmeye devam eder.
Çözüm: Dosyayı Git’in index’inden (staging area) kaldırmanız gerekiyor, ancak disk üzerinden silmeden.
# Tek bir dosyayı index'ten kaldır
git rm --cached .env
# Bir dizini recursive olarak index'ten kaldır
git rm --cached -r node_modules/
# Tüm staging area'yı temizleyip .gitignore'u yeniden uygula
git rm --cached -r .
git add .
# Değişikliği commit'le
git commit -m "chore: .gitignore kuralları düzenlendi, tracked dosyalar temizlendi"
Önemli uyarı: Eğer .env gibi hassas bir dosyayı daha önce commit’lediyseniz, yukarıdaki işlem sadece gelecekteki commit’lerden o dosyayı çıkarır. Dosya hala Git geçmişinde duruyor. Geçmişi temizlemek için git filter-branch veya daha modern olan git filter-repo aracını kullanmanız gerekir. Bu konu ayrı bir yazının konusu, ama şunu söyleyeyim: production’da bu durumla karşılaşırsanız, commit’lenen tüm secret’ları geçersiz sayın ve yenilerini oluşturun. Geçmiş temizleme işlemi, özellikle paylaşımlı repolarda, o secret’ın güvenli olduğunun garantisi değildir.
Global .gitignore Yapılandırması
Bazı dosyalar proje bazında değil, makine bazında yoksanmalı. OS’un ürettiği .DS_Store (macOS), Thumbs.db (Windows) veya kullandığınız editörün konfigürasyon dosyaları bunların başında gelir. Bunları her projenin .gitignore‘una eklemek yerine global bir konfigürasyon kullanmak daha temiz.
# Global gitignore dosyası oluştur
touch ~/.gitignore_global
# Git'e bu dosyanın yerini söyle
git config --global core.excludesfile ~/.gitignore_global
# Dosyaya yaygın OS/IDE kalıpları ekle
cat >> ~/.gitignore_global << 'EOF'
# macOS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
# Windows
Thumbs.db
Desktop.ini
$RECYCLE.BIN/
# Linux
*~
.nfs*
# JetBrains IDEs
.idea/
*.iml
# VS Code
.vscode/
*.code-workspace
# Vim
*.swp
*.swo
*.swn
# Emacs
*~
#*#
/.emacs.desktop
/.emacs.desktop.lock
EOF
Global gitignore’u kişisel makinenize özgü şeylere saklayın. Proje .gitignore‘unu ise projeye özgü şeyler için kullanın ve onu repoya dahil edin, böylece tüm ekip aynı temel kurallardan yararlanır.
Proje İçinde Alt Dizin .gitignore Dosyaları
.gitignore sadece proje kökünde bulunmak zorunda değil. Her dizinde kendi .gitignore dosyası olabilir ve bu dosya sadece o dizin ile alt dizinlerini etkiler. Büyük monorepo yapılarında veya farklı dillerin bir arada kullanıldığı projelerde bu yaklaşım işleri çok düzenli tutar.
proje/
├── .gitignore # Genel kurallar
├── frontend/
│ ├── .gitignore # Sadece frontend için (node_modules, dist vb.)
│ └── src/
├── backend/
│ ├── .gitignore # Sadece backend için (venv, __pycache__ vb.)
│ └── app/
└── infra/
├── .gitignore # Terraform için (.terraform, *.tfstate vb.)
└── terraform/
Örnek bir infra/.gitignore:
# Terraform
.terraform/
.terraform.lock.hcl
*.tfstate
*.tfstate.backup
*.tfstate.*.backup
terraform.tfvars
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Ansible vault şifresi
.vault_pass
vault-password-file
# Geçici dosyalar
*.retry
.gitignore Kurallarını Debug Etmek
Bazen bir kural yazıyorsunuz ama dosya hala takip ediliyor gibi görünüyor ya da tam tersi, takip etmesi gereken bir dosyayı yoksayıyorsunuz. Bu durumda git check-ignore komutu hayat kurtarıcı:
# Bir dosyanın neden yoksandığını öğren
git check-ignore -v somefile.log
# Çıktı formatı:
# .gitignore:3:*.log somefile.log
# (hangi dosya):(hangi satır):(hangi kural) (hedef dosya)
# Birden fazla dosyayı kontrol et
git check-ignore -v *.tmp dist/ .env
# Verbose mod ile hangi dosyaların yoksandığını listele
git status --ignored
# Sadece ignored dosyaları göster
git ls-files --others --ignored --exclude-standard
Bir keresinde bir ekibin .gitignore‘unda config/*.yml kuralı vardı ama config/database.yml hala commit’leniyordu. git check-ignore -v çalıştırdığımızda sorun hemen ortaya çıktı: Dosya zaten index’e eklenmiş yani tracked durumdaydı. .gitignore sadece untracked dosyalara uygulanır. git rm --cached config/database.yml ile çözüldü.
Takım İçin .gitignore Yazarken Dikkat Edilmesi Gerekenler
Birkaç yılda edindiğim pratik notlar:
- Projeye özgü vs. kişisel:
node_modules/,dist/,*.loggibi şeyler projenin.gitignore‘unda olmalı..idea/,.vscode/,.DS_Storegibi kişisel tercihler global gitignore’a gitmeli. Projenin.gitignore‘unda IDE dosyaları görüyorsanız, bu ekip içinde global gitignore kullanımının yaygınlaşmadığının işareti.
- Build artifact’larını her zaman yoksayın:
dist/,build/,target/,bin/gibi dizinler her zaman.gitignore‘da olmalı. Bunları repoya almak hem boyutu şişirir hem de CI/CD pipeline’larında tutarsızlığa yol açar.
- Konfigürasyon şablonları ekleyin:
.envdosyasını yoksasanız bile.env.exampledosyasını repoya ekleyin. İçinde gerçek değerler değil, hangi ortam değişkenlerinin gerektiğini gösteren iskelet bulunsun. Bu yeni geliştiricilerin projeyi kurarken ne yapmaları gerektiğini anlamalarına yardımcı olur.
- Çok geniş kurallardan kaçının:
veya.jsongibi çok geniş kurallar zaman zaman takip etmeniz gereken dosyaları da yutabilir. Mümkün olduğunca spesifik olun.
- .gitignore’u erken yazın: Proje başlangıcında
.gitignore‘u oluşturun, ilk commit’e dahil edin. Sonradan temizlemek hem zahmetli hem de riskli.
Sonuç
.gitignore ilk bakışta basit bir metin dosyası gibi görünse de, doğru kurgulanmadığında projenin uzun vadeli sağlığını ciddi biçimde etkiler. Gereksiz dosyalarla şişmiş bir repo, hassas bilgilerin yanlışlıkla açığa çıkması, takım arkadaşları arasındaki anlamsız çakışmalar… Bunların hepsi önlenebilir sorunlar.
Pratikte önerdiğim akış şu: Yeni proje başladığınızda önce gitignore.io‘dan teknoloji stack’inize uygun bir başlangıç şablonu alın, projeye özel ihtiyaçlarınıza göre uyarlayın, kişisel IDE ve OS dosyalarınızı global gitignore’a taşıyın ve mevcut projelerinizde git ls-files --others --ignored --exclude-standard ile hangi dosyaların zaten sızdığına bakın. Bugün on dakika harcayarak yapacağınız bu düzenleme, ileride saatlerce sürebilecek temizlik işlerinden sizi kurtarır.
