.gitignore dosyası: dosyaları Git'ten nasıl hariç tutarsınız ve eklenmiş olanları nasıl kaldırırsınız
Proje kökündeki .gitignore dosyası, Git'in izlemesini istemediğiniz dosya ve klasör kalıplarını listeler: bağımlılıklar, derleme çıktıları, günlükler, gizli bilgiler. Kurallar yalnızca izlenmeyen dosyalara uygulanır; bu yüzden zaten commit edilmiş bir dosyayı git rm --cached ile indeksten çıkarmanız gerekir.
gitignore mekanizması, Git'e şunu söyleyen bir yoldur: «Bu dosyalara dokunma, git status'ta gösterme ve git add . ile ekleme.» Kurallar, projeyle birlikte commit edilen ve tüm ekibin kullandığı .gitignore adlı bir metin dosyasına yazılır. Asıl incelik şudur: ignore yalnızca Git'in henüz izlemediği dosyalara etki eder.
.gitignore'a genellikle neler yazılır
- Bağımlılıklar:
node_modules/,vendor/,.venv/— bunları paket yöneticisi yeniden kurar. - Derleme çıktıları:
dist/,build/,*.class,__pycache__/. - Günlükler ve geçici dosyalar:
*.log,tmp/,*.swp. - Gizli bilgiler ve yerel ayarlar:
.env, anahtarlar, yerel yapılandırmalar. - İşletim sistemi ve editör çöpleri:
.DS_Store,Thumbs.db,.idea/— bunları genel ignore'da tutmak daha iyidir; aşağıda anlatılıyor.
Kural basit: depoda insanların yazdığı şeyler olmalı; programların ürettiği ya da belirli bir makineye bağlı olan şeyler olmamalı.
.gitignore nasıl oluşturulur
Bu, repository'nin kökünde duran sıradan bir metin dosyasıdır. Oluşturun, her satıra bir kalıp yazın ve commit edin:
cat > .gitignore <<'EOF'
# bağımlılıklar
node_modules/
# derleme
dist/
# günlükler
*.log
# gizli bilgiler
.env
EOF
git add .gitignore
git commit -m "chore: .gitignore eklendi"
Popüler diller ve çatılar için hazır şablonlar github/gitignore deposunda bulunur; GitHub ve GitLab proje oluşturulurken bir şablon seçmenizi sağlar. Bunları temel alın ve gereksizleri çıkarın.
.gitignore sözdizimi
| Kalıp | Neyi yok sayar |
|---|---|
*.log | Herhangi bir klasördeki tüm .log dosyaları |
build/ | Her seviyedeki build klasörü (sondaki eğik çizgi = yalnızca klasörler) |
/build | Yalnızca kökteki build (baştaki eğik çizgi, .gitignore'un bulunduğu klasöre bağlar) |
docs/*.pdf | docs içindeki pdf'ler, ama docs/old/ içindekiler değil |
docs/**/*.pdf | docs ve tüm alt klasörlerdeki pdf'ler |
**/temp | Herhangi bir klasördeki temp |
!keep.log | İstisna: keep.log yok sayılmaz |
file?.txt | ? — herhangi bir tek karakter |
[ab].txt | a.txt ya da b.txt |
# yorum | Yorum satırı |
Önemli ayrıntı: içinde eğik çizgi olmayan kalıp (config.json) her seviyede eşleşir; baştan ya da ortadan eğik çizgi içeren kalıp (/config.json, src/config.json) ise bu .gitignore'un bulunduğu klasöre göre çalışır.
Ünlem işaretiyle istisna
*.log
!important.log
Tuzak: üst klasör yok sayılıyorsa içindeki bir dosyayı «geri» alamazsınız. Git, yok sayılan klasörlerin içine girmez; bu yüzden şu çalışmaz:
logs/
!logs/keep.txt # çalışmaz
Doğrusu, klasörün kendisini değil içeriğini yok saymaktır:
logs/*
!logs/keep.txt
Aynı yöntemle depoda boş bir klasörü de saklarsınız: Git boş klasörleri tutmaz, bu yüzden içine bir .gitkeep dosyası koyup yalnızca onu izin verirsiniz.
Kuralı nereye yazabilirsiniz
| Yer | Neyi etkiler | Repository'ye girer mi |
|---|---|---|
Kök ve alt klasörlerdeki .gitignore | Tüm ekip | Evet |
.git/info/exclude | Yalnızca bu klon | Hayır |
core.excludesFile ile tanımlanan genel dosya | Kendi tüm repository'leriniz | Hayır |
İşletim sisteminizin ve IDE'nizin çöplerini ortak .gitignore'u kirletmemek için genel ignore dosyasına yazmak mantıklıdır:
git config --global core.excludesFile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global
core.excludesFile tanımlı değilse ve ~/.config/git/ignore varsa, Git onu okur.
.gitignore neden çalışmıyor
En sık şikâyet: «.gitignore'a ekledim ama Git hâlâ değişiklik gösteriyor.» Sebep neredeyse her zaman aynıdır: dosya zaten izleniyordur. Ignore, bir kez commit'e girmiş dosyalara etki etmez.
Hangi kuralın devreye girdiğini (ya da neden girmediğini) görmek için git check-ignore kullanılır:
git check-ignore -v logs/app.log
# .gitignore:3:*.log logs/app.log
Çıktı dosyayı ve kuralın satırını gösterir. Boş çıktı, dosyanın yok sayılmadığı anlamına gelir. Diğer bir sebep, kalıp satırının sonundaki boşluklar ya da dosyanın yanlış kodlanmasıdır (örneğin PowerShell ile oluşturulduğunda UTF-16).
Commit edilmiş bir dosyayı git rm --cached ile kaldırmak
git rm, dosyayı hem indeksten hem diskten siler. --cached bayrağıyla yalnızca indeksten siler: dosya sizde kalır, ama artık izlenmez.
echo ".env" >> .gitignore
git rm --cached .env
git commit -m "chore: .env artık izlenmiyor"
git push
Klasör için -r gerekir:
git rm -r --cached node_modules/
Ne commit edildiğinden emin değilseniz, indeksi tamamen yeniden kurabilirsiniz: git rm -r --cached ., sonra git add . ve commit. Commit öncesi git status'a bakın; indeksten çıkarılan dosyalar orada görünür.
Dikkat: gizli bilgiler geçmişte kalır
git rm --cached, dosyayı sonraki commit'lerden çıkarır ama geçmişten çıkarmaz. Depoya bir parola ya da token girdiyse, onu klonu olan herkes görebilir. Gizli bilgiyi ele geçmiş kabul edip yenisini üretmek gerekir. Geçmişi yeniden yazmak için git filter-repo gibi araçlar vardır, ama bu, sonraki tüm commit'lerin hash'lerini değiştirir ve ekiple önceden anlaşmayı gerektirir.
Bir başka sonuç: --cached ile indeksten çıkarılan dosya, meslektaşlarınız git pull yaptığında kendi disklerinden de silinir. .env için bunu önceden haber verin ya da depoda bir .env.example şablonu tutun.
git rm: dosya silme
git rm old.py # hem diskten hem indeksten sil
git rm -r legacy/ # klasörü sil
git rm -n '*.tmp' # kuru çalıştırma: neyin silineceğini göster
git rm -f changed.py # commit edilmemiş değişiklikleri olan dosyayı sil
Dosyayı sıradan rm ile silerseniz Git onu «deleted» olarak görür ve silmeyi git add ya da git rm ile eklemeniz gerekir. git rm iki adımı birden yapar. -f olmadan, commit edilmemiş değişiklikleri olan dosyayı silmeyi reddeder; bu, işinizi kaybetmemeniz için bir korumadır.
git mv: yeniden adlandırma ve taşıma
git mv utils.py helpers.py
git mv helpers.py src/helpers.py
git mv, mv + eski yolun git rm'i + yeni yolun git add'i anlamına gelen bir kısayoldur. Git yeniden adlandırmayı ayrıca kaydetmez: git status, git log --follow ve git diff çıktılarında içerik benzerliğine bakarak hesaplar. Bu yüzden git mv ile normal mv sonrası git add -A aynı sonucu verir.
Pratik öneri: yeniden adlandırmayı ve içerik değişikliğini ayrı commit'lerde yapın. Dosya adı değişirken içeriği de çok değişirse Git onu aynı dosya olarak tanımayabilir ve --follow ile geçmiş kopar.
Windows ve macOS'ta (büyük/küçük harfe duyarsız dosya sistemleri) yalnızca harf büyüklüğünü değiştirmek için git mv readme.md README.md kullanın; sıradan bir yeniden adlandırmayı Git fark etmeyebilir.
Kuralların önceliği
Bir dosyanın içinde kurallar yukarıdan aşağıya okunur ve en son eşleşen kazanır. Bu yüzden !keep.log istisnası, *.log kuralından aşağıda olmalıdır; yoksa üzerine yazılır. Dosyalar arasında öncelik şöyledir: alt klasördeki .gitignore, köktekinden önemlidir; genel ignore ve .git/info/exclude en düşük önceliğe sahiptir.
Bir web projesi için .gitignore örneği
Aşağıda Node.js ön yüzü ve Python arka ucu olan bir proje için çalışan bir örnek var. Yorumlara dikkat edin: altı ay sonra kimse bu kuralların neden eklendiğini hatırlamayacaktır.
# --- bağımlılıklar ---
node_modules/
.venv/
# --- derleme ve önbellekler ---
/dist
/build
__pycache__/
*.pyc
.pytest_cache/
coverage/
# --- günlükler ---
*.log
npm-debug.log*
# --- ortam ve gizli bilgiler ---
.env
.env.*
!.env.example
# --- kullanıcı yüklemeleri, ama klasör kalsın ---
uploads/*
!uploads/.gitkeep
Burada iki istisna tekniği kullanılmıştır: .env.* yerel ortam dosyalarının tümünü gizler, ama .env.example şablonu depoda kalır; uploads klasörü ise .gitkeep sayesinde klonlarda bulunur.
Neyi yok saymamalısınız
Ignore'da abartmak da zarar verir. Bağımlılık kilit dosyaları — package-lock.json, poetry.lock, composer.lock — uygulamalarda genellikle commit edilir: herkesin ve CI'nin aynı paket sürümlerini kurmasını sağlarlar. Ortak biçimlendirme ayarları (.editorconfig, linter yapılandırmaları) da depoda durmalıdır.
Tartışmalı bir durum IDE ayarlarıdır. .vscode/ klasörü çoğu zaman tamamen yok sayılır, ama önerilen eklentileri ve derleme görevlerini paylaşmak için commit edilebilir: önce .vscode/*, sonra !.vscode/extensions.json. Kararı ekip verir; önemli olan, ortak depoda kişisel yolların ve anahtarların bulunmamasıdır.
Senaryo: yanlışlıkla node_modules commit edildi
Yeni başlayanların klasik hatası: .gitignore oluşturulmadan git add . çalıştırılır ve commit'e on binlerce dosya girer. Düzeltmesi üç adımdır:
echo "node_modules/" >> .gitignore
git rm -r --cached node_modules
git commit -m "chore: node_modules repository'den çıkarıldı"
Commit henüz sunucuya gönderilmediyse ağır dosyaların geçmişte kalmaması için onu yeniden yazmak daha iyidir: git reset --soft HEAD~1, ardından aynı komutlar ve yeni bir commit. Push edildiyse dosyalar zaten geçmişte kalmıştır ve geçmişi yeniden yazmadan klonun boyutu küçülmez.
Bunun tekrarlanmaması için .gitignore'u ilk git add'den önce oluşturun ve commit öncesi git status'a alışın: yeni dosyaların listesi şüpheli derecede uzunsa durup bakmanın zamanı gelmiştir.
Kısaca
.gitignore, yeni bir projede commit edilmesi gereken ilk dosyadır: bağımlılıklar, derleme çıktıları, günlükler ve gizli bilgiler repository'de olmamalıdır. Ignore yalnızca izlenmeyen dosyalara uyguladığı için, zaten eklenmiş olanları git rm --cached ile çıkarın ve kuralları git check-ignore -v ile test edin. Silme ve yeniden adlandırma için git rm ve git mv kullanın; böylece değişiklikler hemen indekse girer. İlk repository ve indeks çalışmaları Git kursunda uygulamalı olarak ele alınmaktadır.
Sık sorulan sorular
.gitignore dosyasının kendisi commit edilmeli mi?
Evet; kuralların tüm ekip için geçerli olması için. Kişisel istisnaları ise .git/info/exclude veya genel ignore dosyasına yazın.
Birden fazla .gitignore dosyası olabilir mi?
Evet. .gitignore'u herhangi bir alt klasöre koyabilirsiniz; kuralları o klasöre göre çalışır ve kök kurallarına ek olarak uygulanır.
Yok sayılan bir dosyayı yine de commit etmek istersem?
git add -f yol/dosya kullanın. Bundan sonra dosya izlenir ve .gitignore ona artık etki etmez.
Projedeki tüm yok sayılan dosyaları nasıl görürüm?
git status --ignored ya da git ls-files --others --ignored --exclude-standard komutlarını çalıştırın.
Commit edilmiş bir dosyadaki değişiklikleri geçici olarak izlemeyi nasıl bırakırım?
git update-index --skip-worktree dosya komutu vardır, ama bu yerel bir ayardır ve .gitignore'un yerini tutmaz.
Bu konu “Sıfırdan Güvenilir Geliştiriciye Git” kursunda uygulamalı olarak ayrıntılı işleniyor.
Kursa git