gitignore Oluşturucu
Dil ve araç şablonlarından .gitignore dosyanızı hazırlayın. Her bloğun neden gerektiğini ve daha önce commit ettiğiniz dosyaları nasıl çıkaracağınızı anlatır.
Diller
Çatılar
Araçlar
İşletim sistemleri
Editörler
Yukarıdan en az bir hazır ayar seçin, dosya burada oluşacak.
Özet (TL;DR)
- .gitignore yalnızca takip edilmeyen dosyalar için çalışır. Bir kez commit edilmiş dosya, kurala eklense bile takip edilmeye devam eder.
- Zaten commit edilmiş bir dosyayı çıkarmanın yolu
git rm --cached dosya, ardından commit. Bu diskteki dosyayı silmez. - Aynı desen birden fazla preset'te geçtiğinde araç ikincisini atıyor;
node_modules/üç kez yazılmış bir dosya çıkmıyor. - .env geçmişe girdiyse anahtarı iptal edip yenisini üretin; dosyayı silmek geçmişteki değeri geri almaz.
Bir kez commit edilen dosya repoda kalır
Projenin ilk gününde git add . yazıldığında node_modules da, .env de, .DS_Store da indeksin içine giriyor. Sonra biri .gitignore ekliyor ve dosyaların kaybolmasını bekliyor. Kaybolmuyorlar. Bu davranış bir hata değil, tasarımın kendisi: .gitignore Git'e "şu ana kadar tanımadığın dosyaları da tanıma" diyor, "tanıdıklarını unut" demiyor.
Yani ignore kuralı yazmadan önce dosyanın durumu neyse, ondan sonra da o kalıyor. Takip ediliyorsa takip edilmeye devam ediyor, her değişikliği git status çıktısında görünüyor ve her commit'e giriyor.
Takipten çıkarmanın doğru komutu
Çözüm dosyayı indeksten çıkarmak. --cached bayrağı burada kritik: onsuz komut dosyayı diskten de siliyor ve .env üzerinde bunu yapmak günü bitiriyor.
# Tek dosyagit rm --cached .envgit commit -m "chore: .env takipten cikarildi" # Bir klasorun tamamigit rm -r --cached node_modulesgit commit -m "chore: node_modules takipten cikarildi" # .gitignore'u guncelledikten sonra tum repoyu yeniden degerlendirgit rm -r --cached .git add .git commit -m "chore: gitignore kurallari uygulandi"Uyarı
git rm -r --cached . komutu indeksi tamamen boşaltıyor, git add . ise .gitignore kurallarına uyanları geri koyuyor. Çalışma dizinindeki dosyalara dokunmuyor ama commit etmeden önce mutlaka git status çıktısına bakın: yanlışlıkla ignore ettiğiniz gerçek bir kaynak dosyası varsa bu adımda silinmiş görünür.Desen sözdizimi
Kuralların çoğu tek satırlık glob ifadeleri ama dördü davranışı ciddi biçimde değiştiriyor ve karıştırılıyor.
| Desen | Anlamı | Neyi tutmaz |
|---|---|---|
| build/ | Herhangi bir dizindeki build klasörü | build adlı bir dosyayı |
| /build | Yalnızca repo kökündeki build | src/build yolunu |
| *.log | Her dizindeki .log uzantılı dosyalar | logs/ klasörünü |
| !important.log | Önceki kuralın istisnası | Üst dizini ignore edilmişse hiçbir şeyi |
| docs//*.pdf | docs altında kaç seviye olursa olsun PDF | docs dışındaki PDF'leri |
Negasyonun bir tuzağı var: üst dizin komple ignore edilmişse alt dosyayı ! ile geri getiremezsiniz. Git ignore edilmiş bir dizinin içine hiç inmiyor, dolayısıyla içerideki istisna kuralını hiç görmüyor. Bu yüzden .vscode/* yazılıp ardından !.vscode/settings.json yazılıyor, .vscode/ yazılıp sonra istisna eklenmiyor. Araçtaki VS Code preset'i tam olarak bu sırayı koruyor.
Sızan gizli bilgi
.env neredeyse her preset'te var, çünkü içindeki şey genelde bir veritabanı şifresi veya bir API anahtarı. Buradaki mesele dosyanın kendisi değil, geçmiş. .env bir kez push edildiyse değeri artık repo geçmişinde duruyor ve dosyayı sonraki bir commit'te silmek onu geçmişten çıkarmıyor. Fork alanlar, clone edenler, CI önbellekleri ve GitHub'ın kendi arşivi o commit'i tutmaya devam ediyor.
Tek gerçek çözüm anahtarı iptal etmek ve yenisini üretmek. Sağlayıcının panelinden eski anahtarı revoke edin, yenisini yalnızca çalışma ortamına ve CI secret deposuna koyun. Geçmişi git filter-repo ile temizlemek isterseniz yapabilirsiniz ama bu bütün commit hash'lerini değiştirdiği için ekipteki herkesin yeniden clone alması gerekiyor, üstelik anahtarı zaten çeken biri varsa hiçbir şeyi geri almıyor.
Global gitignore ve editör dosyaları
Bir ekip repo'sunda .DS_Store, *.swp veya .idea/ satırları görmek genelde tartışma çıkarıyor, çünkü bunlar projenin değil kişinin dosyaları. Kendi makinenize özel gürültüyü paylaşılan dosyaya sokmak yerine global bir gitignore tanımlayabilirsiniz:
git config --global core.excludesfile ~/.gitignore_global # ~/.gitignore_global icerigi.DS_Store*.swp.idea/.vscode/Repo içindeki .gitignore ise projenin kendi çıktılarına ayrılıyor: derleme klasörleri, bağımlılıklar, önbellekler. Aracın preset gruplarında OS ve editör kategorilerinin en sona konması da bunun için; okuyan kişi projeye özel kuralları üstte, atlanabilir gürültüyü altta buluyor.
Sıkça Sorulan Sorular
- Dosyayı zaten commit ettim, ne yapmalıyım?
- Deseni .gitignore'a ekleyin, sonra
git rm --cached dosyaadiçalıştırıp commit edin. Klasör için-rbayrağını ekleyin.--cachedolmadan komut dosyayı diskten de siler, bu yüzden bayrağı atlamayın. Bu işlemden sonra dosya artık takip edilmez ama geçmişteki commit'lerde durmaya devam eder. - .env dosyam GitHub'a gitti, silmek yeterli mi?
- Yeterli değil. Silme işlemi yeni bir commit oluşturur, önceki commit ise geçmişte durur ve içeriği okunabilir. Yapılacak ilk iş içindeki her anahtarı iptal edip yeniden üretmek. Geçmişi temizlemek ikincil:
git filter-repoveya BFG ile mümkün ama tüm hash'leri değiştirdiği için ekibin yeniden clone alması gerekir ve anahtarı çoktan almış birine karşı bir koruma sağlamaz. - .gitignore geriye dönük çalışır mı?
- Hayır. Kural yalnızca takip edilmeyen dosyalara uygulanır. Geçmişteki commit'ler değişmez, indekste duran dosyalar da otomatik çıkmaz. Geriye dönük etki isteyen tek yol indeksten elle çıkarmak, yani
git rm --cached. - Global gitignore mu repo içindeki mi?
- Ayrım şu: dosya sizin araç zincirinizden mi geliyor, projeden mi. Editör ayar klasörleri, işletim sistemi metadata dosyaları ve kişisel geçici dosyalar global dosyaya girer, çünkü ekipteki başka biri bunları hiç üretmiyor olabilir. Derleme çıktısı, bağımlılık klasörü ve ortam dosyaları repo içindeki .gitignore'a girer, çünkü projeyi clone eden herkes onları üretecek.
- Ignore ettiğim dosya hâlâ neden görünüyor?
- Neredeyse her zaman dosyanın zaten takip ediliyor olmasından.
git check-ignore -v yol/dosyakomutu hangi kuralın eşleştiğini satır numarasıyla söyler; hiçbir çıktı vermezse dosya kurala uymuyordur, çıktı verdiği halde dosya görünüyorsa indekstedir vegit rm --cachedgerekir. Üçüncü ihtimal, üst dizinin ignore edilmiş olması nedeniyle içerideki!istisnasının hiç değerlendirilmemesidir.