Takip et

Büyük Depolarda Git Status Yavaşlığına Son: İki Ayar İle Performansı %95 İyileştirme

Modern yazılım geliştirme süreçlerinde Git, projelerin versiyon kontrolü için vazgeçilmez bir araç haline geldi.

Büyük Depolarda Git Status Yavaşlığına Son: İki Ayar İle Performansı %95 İyileştirme

Modern yazılım geliştirme süreçlerinde Git, projelerin versiyon kontrolü için vazgeçilmez bir araç haline geldi. Ancak, özellikle büyük kod tabanlarına sahip monorepolar veya uzun soluklu projelerde, basit bir git status komutunun bile saniyelerce hatta dakikalarca sürmesi, geliştirici verimliliğini ciddi şekilde düşürebilir. Bu durum, günlük iş akışını sekteye uğratmakla kalmaz, aynı zamanda CI/CD (Sürekli Entegrasyon/Sürekli Teslimat) süreçlerinde de darboğazlara yol açabilir. Peki, 17.6 saniye süren bir git status komutunu sadece iki küçük yapılandırma ayarı ile 0.83 saniyeye düşürmek mümkün mü? Cevap kesinlikle evet! Bu makalede, bu sihirli iki ayarın ne olduğunu, neden işe yaradığını ve Git depolarınızda performansı nasıl kökten değiştirebileceğini detaylıca inceleyeceğiz.

Git Status Komutu Neden Önemli ve Büyük Depolarda Neden Yavaşlar?

git status komutu, bir geliştiricinin günlük iş akışının temel taşlarından biridir. Çalışma dizininizdeki (working directory) dosyaların mevcut durumu hakkında size hızlıca bilgi verir: hangi dosyaların değiştirildiğini, hangilerinin dizine (staging area) eklendiğini, hangilerinin takip edilmediğini ve son commit’ten (taahhüt) bu yana ne gibi değişiklikler olduğunu gösterir. Bu bilgiler, bir sonraki adımınızı planlamanız, değişiklikleri organize etmeniz ve projenin genel sağlığını anlamanız için hayati öneme sahiptir. Ancak, depo boyutu arttıkça, özellikle yüz binlerce veya milyonlarca dosya içeren projelerde, bu basit komutun çalışma süresi katlanarak artabilir.

Peki, bu yavaşlamanın arkasındaki temel nedenler nelerdir? Git, git status komutunu çalıştırdığında, çalışma dizininizdeki her bir dosyayı kontrol eder. Bu kontrol süreci temelde üç ana aşamadan oluşur:

  • Dosya Sistemi Taraması ve Değişiklik Tespiti: Git, çalışma dizininizdeki her dosyayı gezerek, o dosyanın diskteki son değiştirilme zamanı (mtime), boyutu ve inode gibi meta verilerini alır. Bu meta verileri, Git’in kendi dizinindeki (index) kayıtlarla karşılaştırır. Eğer bu meta verilerde bir farklılık varsa, dosyanın içeriğinin değişmiş olabileceği varsayılır ve dosyanın SHA-1 (veya daha yeni sürümlerde SHA-256) karması hesaplanır. Bu karma, dosyanın içeriğinin gerçekten değişip değişmediğini kesin olarak belirlemek için kullanılır. Özellikle çok sayıda dosya ve dizin içeren büyük depolarda, bu dosya sistemi taraması başlı başına zaman alıcı bir işlemdir. Her bir dosya için işletim sistemine yapılan stat() veya benzeri sistem çağrıları, binlerce veya milyonlarca kez tekrarlandığında ciddi bir performans maliyeti yaratır.
  • Takip Edilmeyen Dosyaların (Untracked Files) Yönetimi: Git, sadece takip ettiği dosyaları değil, aynı zamanda çalışma dizininde bulunan ancak Git tarafından henüz izlenmeyen (yani .gitignore dosyasında belirtilmemiş veya manuel olarak eklenmemiş) dosyaları da listelemek zorundadır. Bu, Git’in tüm çalışma dizinini tarayarak, kendi dizininde (index) veya HEAD commit’inde bulunmayan dosyaları tespit etmesini gerektirir. Eğer projenizde node_modules, vendor, build gibi çok sayıda geçici veya bağımlılık dosyası içeren dizinler varsa ve bunlar .gitignore dosyasında yeterince iyi yönetilmiyorsa, Git bu devasa dizinleri de taramak zorunda kalır. Bu durum, yavaşlamanın en büyük nedenlerinden biri olabilir.
  • Dizin Boyutu ve Derinliği: Monorepolar, yani birden fazla projenin tek bir Git deposunda yönetildiği yapılar, doğal olarak çok büyük dosya sayılarına ve derin dizin hiyerarşilerine sahiptir. Benzer şekilde, bazı projeler, örneğin büyük bir oyun motoru veya işletim sistemi çekirdeği gibi, milyonlarca kaynak kodu dosyası içerebilir. Bu tür depolarda, Git’in tüm bu dosyaları taraması, dizin yapısını gezmesi ve her bir dosya için gerekli kontrolleri yapması, kaçınılmaz olarak uzun sürelere yol açar. Dosya sisteminin kendisi de bu tür yoğun okuma işlemlerinde belirli bir sınıra sahiptir; özellikle HDD (mekanik disk) kullanılıyorsa, performans düşüşü daha da belirginleşir. SSD (katı hal sürücü) kullanımı bile, dosya sayısı milyonları bulduğunda bir noktadan sonra yetersiz kalabilir.

Bir vaka analizi olarak, uluslararası bir yazılım firmasının büyük bir JavaScript monoreposunu ele alalım. Bu depoda, yüzlerce mikroservis ve ön uç uygulaması bir arada bulunuyordu. Her bir uygulamanın kendi node_modules klasörü ve derlenmiş çıktıları vardı. Proje büyüdükçe, git status komutu 20-30 saniyeye kadar uzayabiliyordu. Bu durum, geliştiricilerin her değişiklikten sonra durumu kontrol etmek için uzun süreler beklemek zorunda kalması anlamına geliyordu. Gün içinde defalarca tekrarlanan bu bekleme süreleri, toplamda saatlere varan bir verimlilik kaybına yol açıyordu. CI/CD pipeline’larında da benzer bir sorun yaşanıyor, her aşamada git status veya benzeri dosya sistemi tarama komutları yüzünden build süreleri uzuyordu. Bu durum, sadece geliştiricilerin motivasyonunu düşürmekle kalmıyor, aynı zamanda şirketin genel geliştirme hızını da yavaşlatıyordu.

Git’in Performans Engelini Anlamak: Dosya Sistemi Etkileşimi

Git’in temel çalışma prensibi, dosyaların içeriğini ve meta verilerini sürekli olarak izlemeye dayanır. Herhangi bir değişiklik olduğunda, Git bu değişikliği tespit etmek ve depoda uygun şekilde saklamak zorundadır. Bu izleme süreci, yoğun dosya sistemi etkileşimleri gerektirir. Git, çalışma dizinindeki dosyaları tararken, her bir dosya için işletim sisteminden bilgi ister. Bu bilgiler arasında dosyanın değiştirilme zamanı, boyutu ve dosya sistemindeki konumu gibi detaylar yer alır. Bu süreç, özellikle büyük depolarda, yüz binlerce veya milyonlarca dosya için tekrarlandığında, dosya sistemi üzerindeki yükü artırır ve git status gibi komutların yavaşlamasına neden olur.

Git, değişiklikleri tespit etmek için genellikle iki ana yöntem kullanır: birincisi dosya meta verilerini (mtime, ctime, boyut) karşılaştırmak, ikincisi ise dosya içeriğinin karmasını (hash) hesaplamaktır. Eğer dosya meta verileri değişmişse, Git dosyanın içeriğinin de değişmiş olabileceğini varsayar ve doğrulamak için içeriğin karmasını hesaplar. Bu karma hesaplama işlemi, dosyanın boyutuna bağlı olarak zaman alabilir. Küçük bir depo için bu işlemler neredeyse anında gerçekleşirken, büyük depolarda bu süreçler birikerek ciddi gecikmelere yol açar. Örneğin, bir Java projesinde derlenmiş .class dosyaları, veya bir C++ projesinde .o dosyaları, hatta bir Python projesinde __pycache__ dizinleri, Git’in taraması gereken binlerce ek dosya anlamına gelebilir. Bu dosyalar genellikle .gitignore ile göz ardı edilse de, Git’in yine de bu dosyaların varlığını kontrol etmesi ve .gitignore kurallarıyla eşleştirmesi gerekir ki bu da bir miktar maliyet yaratır.

Ayrıca, Git’in dizin (index) dosyası, projenin anlık durumunun bir anlık görüntüsünü (snapshot) içerir. git status komutu, çalışma dizinini bu dizin dosyasıyla karşılaştırarak değişiklikleri belirler. Eğer dizin dosyası çok büyükse (milyonlarca giriş içeriyorsa), bu karşılaştırma işlemi de zaman alıcı hale gelebilir. Git’in bu karşılaştırmaları etkili bir şekilde yapabilmesi için, dosya sistemiyle olan etkileşimlerini optimize etmesi gerekir. İşte tam da bu noktada core.untrackedCache ve core.fsmonitor gibi yapılandırma ayarları devreye girer. Bu ayarlar, Git’in dosya sistemiyle olan etkileşimini akıllıca yöneterek, gereksiz taramaları ve hesaplamaları en aza indirmeyi hedefler. Böylece, Git’in sadece gerçekten değişen veya potansiyel olarak değişmiş olabilecek dosyalar üzerinde yoğunlaşmasını sağlayarak performansı artırır.

Çözümün Anahtarı: core.untrackedCache ve core.fsmonitor Nedir?

Git’in büyük depolardaki performans sorunlarına yönelik en etkili çözümlerden ikisi, core.untrackedCache ve core.fsmonitor yapılandırma ayarlarıdır. Bu iki ayar, Git’in dosya sistemiyle etkileşimini optimize ederek, git status gibi komutların çalışma süresini önemli ölçüde azaltır. Şimdi bu ayarları detaylıca inceleyelim:

core.untrackedCache: Takip Edilmeyen Dosyaların Akıllı Önbelleklemesi

core.untrackedCache ayarı, Git’in takip edilmeyen (untracked) dosyaları yönetme biçimini değiştirir. Varsayılan olarak, git status her çalıştığında, çalışma dizinindeki tüm dosyaları tarar ve bunların takip edilip edilmediğini kontrol eder. Eğer projenizde node_modules, vendor, build veya benzeri, binlerce hatta yüz binlerce dosya içeren dizinler varsa ve bunlar .gitignore tarafından zaten göz ardı ediliyorsa bile, Git yine de bu dizinleri gezmek ve her bir dosyanın durumunu kontrol etmek zorunda kalır. Bu, büyük bir performans yükü oluşturur.

core.untrackedCache ayarı true yapıldığında, Git takip edilmeyen dosyalar hakkında bilgi içeren bir önbellek oluşturur ve bu önbelleği güncel tutar. Bu önbellek, .git/index dosyasının içinde veya yanında saklanır. Bir sonraki git status çağrısında, Git tüm çalışma dizinini tekrar taramak yerine, bu önbelleği kullanarak takip edilmeyen dosyaların durumunu çok daha hızlı bir şekilde belirleyebilir. Bu, özellikle .gitignore tarafından göz ardı edilen ancak fiziksel olarak diskte var olan devasa dizinlerin olduğu durumlarda muazzam bir hız artışı sağlar. Git, bu önbelleği akıllıca günceller; sadece gerekli olduğunda (örneğin, bir git clean işlemi yapıldığında veya önbellekteki bir dosyanın zaman damgası değiştiğinde) yeniden tarama yapar. Bu sayede, gereksiz dosya sistemi okumaları ve CPU döngüleri büyük ölçüde azalır.

Bu özelliğin temel faydası, Git’in dosya sistemiyle yaptığı gereksiz stat() çağrılarının sayısını azaltmasıdır. Bir dosyanın takip edilip edilmediğini anlamak için, Git’in o dosyanın meta verilerine erişmesi gerekir. untrackedCache, bu bilgiyi bir kez okuduktan sonra önbelleğe alarak, sonraki sorgulamalarda disk erişimini atlamasını sağlar. Bu da özellikle yavaş disklerde veya ağ üzerindeki dosya sistemlerinde çalışanlar için hayati bir iyileşme demektir.

core.fsmonitor: Dosya Sistemi İzleyicisi ile Anında Bildirimler

core.fsmonitor ayarı, Git’in dosya sistemi değişikliklerini izlemek için işletim sistemi seviyesindeki bildirim mekanizmalarını kullanmasını sağlar. Git’in geleneksel yaklaşımında, çalışma dizinindeki değişiklikleri tespit etmek için sürekli olarak dosyaların meta verilerini (mtime gibi) kontrol etmesi gerekir. Bu, her git status çağrısında potansiyel olarak binlerce dosyanın tek tek kontrol edilmesi anlamına gelir.

core.fsmonitor true yapıldığında, Git bir dosya sistemi izleyicisi (file system monitor) yardımcı süreci (helper process) kullanır. Bu yardımcı süreç, işletim sisteminin yerel dosya sistemi izleme API’larını kullanarak (örneğin Linux’ta inotify, macOS’ta FSEvents, Windows’ta ReadDirectoryChangesW), çalışma dizininde gerçekleşen dosya değişikliklerini anında takip eder. Bir dosya oluşturulduğunda, değiştirildiğinde veya silindiğinde, dosya sistemi izleyicisi bu olayı tespit eder ve Git’e bildirir. Bu sayede, Git, git status komutu çalıştırıldığında tüm çalışma dizinini baştan sona taramak yerine, yalnızca dosya sistemi izleyicisi tarafından bildirilen değişmiş dosyaları kontrol eder. Bu, özellikle çok büyük depolarda ve aktif geliştirme yapılan ortamlarda inanılmaz bir hız artışı sağlar.

fsmonitor‘un çalışma prensibi oldukça basittir: İşletim sistemi, bir dizindeki değişiklikleri dinleyebilir ve bu değişiklikler hakkında uygulamalara bilgi verebilir. Git, bu yeteneği kullanarak, hangi dosyaların değiştiğini veya yeni eklendiğini pasif bir şekilde öğrenir. Böylece, git status çağrıldığında, Git’in yapması gereken iş miktarı, sadece birkaç değişmiş dosyayı kontrol etmekle sınırlı kalır, milyonlarca dosyayı taramak zorunda kalmaz. Bu, özellikle dosya sayısı çok fazla olan ve sık sık değişiklik yapılan monorepolar için oyun değiştirici bir özelliktir. Bu özellik, core.untrackedCache ile birleştiğinde, Git’in performansını adeta fırlatır; untrackedCache takip edilmeyen dosyaları hızlıca ele alırken, fsmonitor takip edilen dosyaların değişikliklerini anında tespit eder.

Bu iki ayarın birleşimi, Git’in dosya sistemiyle olan etkileşimini radikal bir şekilde optimize eder. untrackedCache, göz ardı edilen dosyaların yükünü hafifletirken, fsmonitor, takip edilen dosyaların değişiklik tespitini neredeyse anlık hale getirir. Sonuç olarak, git status komutu, devasa depolarda bile saniyeler içinde tamamlanarak geliştirici verimliliğini maksimum seviyeye çıkarır.

Adım Adım Uygulama: Git Performansınızı Nasıl Hızlandırırsınız?

Git depolarınızda git status komutunun yavaşlığından şikayetçiyseniz, yukarıda bahsettiğimiz iki yapılandırma ayarını uygulamak oldukça basittir ve genellikle çok kısa sürede gözle görülür bir fark yaratır. İşte adım adım bu ayarları nasıl uygulayacağınız ve sonuçları nasıl gözlemleyeceğiniz:

Mevcut Durumu Kontrol Etme: Başlangıç Performansını Ölçme

Herhangi bir optimizasyona başlamadan önce, mevcut performansınızı ölçmek önemlidir. Bu, yapılan değişikliklerin ne kadar etkili olduğunu somut verilerle görmenizi sağlar. Terminalinizde, yavaş olduğunu düşündüğünüz büyük Git deposunun kök dizinindeyken aşağıdaki komutu çalıştırın:

time git status

Bu komut, git status komutunun çalışması için geçen gerçek (real), kullanıcı (user) ve sistem (sys) sürelerini size gösterecektir. Genellikle “real” süresi, komutun tamamlanması için geçen toplam süreyi ifade eder. Bu değeri bir yere not alın. Örneğin, başlangıçta 17.6 saniye gibi bir süre görebilirsiniz. Bu, bizim referans noktamız olacak.

Yapılandırma Ayarlarını Uygulama

Şimdi sıra, Git’in performansını artıracak sihirli iki ayarı uygulamaya geldi. Bu ayarları genel (global) olarak tüm Git depolarınız için veya sadece belirli bir depo için yerel (local) olarak yapabilirsiniz. Genel olarak uygulamak, bu optimizasyondan tüm projelerinizde faydalanmanızı sağlar ve genellikle tercih edilen yöntemdir.

Aşağıdaki komutları terminalinizde çalıştırın:

git config --global core.untrackedCache true

Bu komut, core.untrackedCache özelliğini etkinleştirir. --global bayrağı, bu ayarın kullanıcı seviyesinde (yani sizin kullanıcı hesabınız için) tüm Git depolarına uygulanmasını sağlar. Bu ayar, Git’in takip edilmeyen dosyalar için bir önbellek tutmasına olanak tanır, böylece her git status çağrısında bu dosyaları yeniden taramak zorunda kalmaz. Özellikle node_modules gibi büyük ve sık değişmeyen dizinlerin olduğu projelerde büyük fayda sağlar.

git config --global core.fsmonitor true

Bu komut ise core.fsmonitor özelliğini etkinleştirir. Yine --global bayrağı ile tüm depolarınıza uygulanır. fsmonitor, işletim sisteminin dosya sistemi izleme yeteneklerini kullanarak, Git’in sadece değişen dosyaları kontrol etmesini sağlar. Bu, Git’in tüm çalışma dizinini taramak yerine, sadece işletim sistemi tarafından bildirilen değişiklikler üzerinde yoğunlaşmasına olanak tanır. Bu özellik, özellikle aktif olarak geliştirme yapılan ve dosyalarda sık sık değişiklikler olan depolarda inanılmaz bir hız artışı sağlar.

Bu iki komutu çalıştırdıktan sonra, ayarlarınız Git yapılandırmanıza kaydedilmiş olacaktır. Bu ayarların etkin olup olmadığını kontrol etmek için aşağıdaki komutu kullanabilirsiniz:

git config --global --list | grep "core.untrackedCache\|core.fsmonitor"

Bu komut, yapılandırma dosyanızdaki ilgili girdileri listeleyecektir. Eğer true olarak görünüyorsa, ayarlar başarıyla uygulanmıştır.

Sonuçları Gözlemleme: Performans Kazancını Doğrulama

Ayarları uyguladıktan sonra, şimdi performans kazancını doğrulamak için tekrar git status komutunu ölçme zamanı. Büyük Git deponuzun kök dizininde tekrar aşağıdaki komutu çalıştırın:

time git status

Şimdi elde ettiğiniz “real” süresini ilk not aldığınız değerle karşılaştırın. Çoğu durumda, başlangıçta 17.6 saniye süren bir komutun 0.83 saniyeye düştüğünü veya benzer şekilde %90’dan fazla bir iyileşme gördüğünüzü fark edeceksiniz. Bu, geliştirme deneyiminizi kökten değiştirecek önemli bir kazançtır.

Vaka Çalışması: Bir Geliştiricinin Deneyimi

Bir web geliştiricisi olan Ayşe, büyük bir Vue.js projesi üzerinde çalışıyordu. Proje, birçok bileşen kütüphanesi ve bağımlılık içerdiği için node_modules klasörü yüz binlerce dosyadan oluşuyordu. Ayşe, her git pull veya npm install işleminden sonra git status komutunun 15-20 saniye sürmesinden muzdaripti. Bu durum, özellikle küçük değişiklikler yapıp hızlıca durumunu kontrol etmek istediğinde onu yavaşlatıyordu. Makalede bahsedilen core.untrackedCache ve core.fsmonitor ayarlarını uyguladıktan sonra, Ayşe’nin git status süresi 1.5 saniyenin altına düştü. Bu, Ayşe’nin günlük iş akışında devrim niteliğinde bir değişiklik yarattı. Artık çok daha hızlı geri bildirim alabiliyor, değişikliklerini daha verimli yönetebiliyor ve genel olarak geliştirme sürecinden daha fazla keyif alıyordu. Bu vaka, bu iki basit ayarın bile ne kadar büyük bir etki yaratabileceğinin somut bir örneğidir.

Derinlemesine Bakış: Bu Ayarlar Git’in İç İşleyişini Nasıl Değiştiriyor?

Bu ayarların Git’in iç işleyişini nasıl etkilediğini anlamak, neden bu kadar etkili olduklarını daha iyi kavramamızı sağlar. Git, temel olarak bir içerik adreslenebilir dosya sistemi (content-addressable filesystem) olarak çalışır. Yani, her dosyanın içeriği bir karma (hash) ile temsil edilir ve bu karma, dosyanın benzersiz kimliğidir. git status komutu, bu karma değerlerini ve dosya meta verilerini karşılaştırarak değişiklikleri tespit eder.

core.untrackedCache etkinleştirildiğinde, Git, .git/index dosyasının içinde veya yanında “untracked cache” adı verilen özel bir bölüm oluşturur. Bu önbellek, takip edilmeyen dosyaların listesini ve onların meta verilerini (mtime, boyut gibi) tutar. Normalde, Git takip edilmeyen dosyaları bulmak için tüm çalışma dizinini gezmek zorundadır. Ancak bu önbellek sayesinde, Git sadece önbelleği okuyarak, hangi dosyaların takip edilmediğini ve bu dosyaların önbelleğe alındığından bu yana değişip değişmediğini hızlıca belirleyebilir. Eğer bir dosya önbellekte yoksa veya meta verileri değişmişse, Git o dosyayı tekrar kontrol eder. Bu, özellikle .gitignore‘da belirtilen ancak yine de diskte yer kaplayan büyük dizinler için (örneğin node_modules) kritik öneme sahiptir. Git, bu dizinleri her seferinde baştan sona taramak yerine, önbellekteki bilgiyi kullanarak çok daha hızlı karar verir.

core.fsmonitor ise, Git’in dosya sistemi değişikliklerini proaktif olarak izlemesini sağlar. Bu özellik etkinleştirildiğinde, Git, işletim sisteminin yerel dosya sistemi izleme API’ları (Linux’ta inotify, macOS’ta FSEvents, Windows’ta ReadDirectoryChangesW) ile iletişim kuran bir yardımcı süreç (helper process) başlatır. Bu yardımcı süreç, çalışma dizininde gerçekleşen dosya oluşturma, değiştirme veya silme gibi olayları anında yakalar. Bu olaylar, Git’e “değişen dosyaların bir listesi” olarak iletilir. Böylece, git status komutu çalıştırıldığında, Git tüm depoyu taramak zorunda kalmaz; yalnızca dosya sistemi izleyicisi tarafından bildirilen dosyaları ve onların ilgili meta verilerini kontrol eder. Bu, özellikle büyük depolarda ve sık sık dosya değişikliği yapılan ortamlarda, dosya sistemi üzerindeki yükü ve CPU kullanımını radikal bir şekilde azaltır. Bu yardımcı süreç, genellikle .git/info/fsmonitor--daemon gibi bir dosyada veya benzer bir mekanizma ile çalıştırılır ve arka planda sessizce izleme yapar.

Bu iki mekanizmanın birleşimi, Git’in dosya sistemiyle olan etkileşimini “tembel” (lazy) ve “olay tabanlı” (event-driven) hale getirir. Git artık her şeyi sürekli olarak sorgulamak yerine, sadece ihtiyaç duyduğunda veya bir olay tetiklendiğinde harekete geçer. Bu da, performans kazancının temelini oluşturur. Bu ayarlar, Git’in dahili dizin (index) yapısını daha verimli kullanmasını sağlayarak, büyük ölçekli depolarda bile hızlı ve duyarlı bir deneyim sunar.

Performans Optimizasyonu İçin Diğer İpuçları ve İleri Düzey Teknikler

core.untrackedCache ve core.fsmonitor ayarları Git performansını önemli ölçüde artırsa da, daha da ileri gitmek ve Git deneyiminizi daha da optimize etmek için başka teknikler ve ipuçları da bulunmaktadır. Bu ileri düzey stratejiler, özellikle çok büyük veya karmaşık depolarda çalışan geliştiriciler için faydalı olabilir.

  • .gitignore Dosyasını Etkin Kullanmak: Bu, Git performansını artırmak için en temel ama en etkili yöntemlerden biridir. Projenizde derlenmiş dosyalar (.class, .o), bağımlılık dizinleri (node_modules, vendor), log dosyaları, geçici dosyalar, editör ayarları veya hassas bilgiler (API anahtarları) gibi Git tarafından takip edilmemesi gereken her şeyi .gitignore dosyasına ekleyin. Ne kadar çok gereksiz dosyayı göz ardı ederseniz, Git’in taraması gereken dosya sayısı o kadar azalır ve bu da git status gibi komutların daha hızlı çalışmasını sağlar. Büyük bir node_modules dizinini .gitignore‘a eklemek, tek başına bile büyük bir hız artışı sağlayabilir.
  • Sparse Checkout (Seyrek Checkout): Eğer çok büyük bir monorepo üzerinde çalışıyor ancak sadece belirli alt dizinlerdeki dosyalarla ilgileniyorsanız, sparse checkout kullanabilirsiniz. Bu özellik, Git’in çalışma dizininize sadece belirli dizinleri veya dosyaları çekmesini sağlar. Böylece, tüm depoyu diskinize klonlamak zorunda kalmazsınız ve Git’in üzerinde çalışması gereken dosya sayısı önemli ölçüde azalır. Bu, özellikle çok büyük kaynak kodlu projelerde veya bağımsız modüllerin bir arada bulunduğu monorepolarda geliştirici deneyimini hızlandırır.
    git config core.sparseCheckout true
    git sparse-checkout init --cone
    echo "path/to/my/module/" >> .git/info/sparse-checkout
    git sparse-checkout reapply

    Bu komutlar, path/to/my/module/ dizini dışındaki tüm dosyaların göz ardı edilmesini sağlar.

  • Shallow Clone (Sığ Klonlama): Yeni bir depoyu klonlarken, tüm commit geçmişini indirmek yerine sadece belirli bir derinlikteki commit’leri (örneğin son 1 commit) indirmek, klonlama süresini ve depo boyutunu büyük ölçüde azaltır. Bu, özellikle CI/CD ortamlarında veya hızlıca bir depoyu test etmek istediğinizde faydalıdır. Ancak, tam bir geçmişe ihtiyacınız olduğunda bu yöntem uygun değildir.
    git clone --depth 1 <repo_url>
  • Git GC (Garbage Collection – Çöp Toplama): Git, zaman zaman otomatik olarak çöp toplama (garbage collection) işlemleri yapar. Bu işlem, gereksiz nesneleri siler, gevşek nesneleri paket dosyalarına sıkıştırır ve depo boyutunu optimize eder. Eğer deponuzda çok sayıda eski veya erişilemez nesne varsa, manuel olarak git gc komutunu çalıştırmak performansı artırabilir.
    git gc --prune=now
  • Donanım Faktörleri: Git’in performansı, kullandığınız donanım tarafından da doğrudan etkilenir. SSD (Katı Hal Sürücü) kullanımı, HDD’lere (Mekanik Disk) göre dosya okuma ve yazma hızlarını katlayarak Git komutlarının daha hızlı çalışmasını sağlar. Yeterli miktarda RAM ve hızlı bir işlemci de genel sistem performansını ve dolayısıyla Git işlemlerinin hızını olumlu etkiler. Özellikle sanal makinelerde veya ağ paylaşımlarında çalışan Git depolarında performans sorunları daha sık görülebilir; bu durumlarda yerel bir SSD’de çalışmak büyük fark yaratır.
  • Git Versiyonunu Güncel Tutmak: Git sürekli olarak geliştirilmekte ve yeni performans iyileştirmeleri eklenmektedir. Kullandığınız Git sürümünü güncel tutmak, en son optimizasyonlardan ve hata düzeltmelerinden faydalanmanızı sağlar. Yeni Git sürümleri, dosya sistemi etkileşimlerini, indeksleme algoritmalarını ve genel performansı iyileştiren önemli değişiklikler içerebilir.

Bu ipuçlarını ve teknikleri bir araya getirerek, Git depolarınızdaki performansı sadece git status için değil, genel olarak tüm Git operasyonları için optimize edebilirsiniz. Unutmayın ki her depo ve proje farklıdır, bu nedenle hangi optimizasyonların sizin için en uygun olduğunu bulmak için deneme yapmak gerekebilir.

Sıkça Sorulan Sorular

Git performans optimizasyonu konusunda akla gelebilecek bazı yaygın sorular ve yanıtları:

Bu ayarlar (core.untrackedCache ve core.fsmonitor) her zaman güvenli midir?

Evet, bu ayarlar genel olarak güvenlidir ve Git’in resmi olarak desteklediği özelliklerdir. Bunlar, Git’in dosya sistemiyle etkileşimini optimize etmek için tasarlanmıştır ve temel Git operasyonlarının doğruluğunu veya bütünlüğünü bozmazlar. Nadir durumlarda, özellikle çok eski veya özel dosya sistemlerinde fsmonitor ile uyumluluk sorunları yaşanabilir, ancak modern işletim sistemleri ve dosya sistemlerinde sorunsuz çalışması beklenir. Herhangi bir şüpheniz varsa, önce küçük veya test depolarınızda deneyebilirsiniz.

Performans kazancı her depoda aynı mı olur?

Hayır, performans kazancı deponun boyutuna, dosya sayısına, dizin derinliğine, .gitignore dosyasının etkinliğine ve dosya sistemi aktivitesine göre değişiklik gösterir. Özellikle çok sayıda takip edilmeyen dosya (node_modules gibi) ve sık dosya değişiklikleri olan büyük depolarda en büyük kazançlar elde edilir. Küçük depolarda veya çok az dosya değişikliği olan depolarda, bu ayarların etkisi daha az fark edilebilir olacaktır çünkü zaten performans sorunu yaşanmıyordur.

Bu ayarları geri nasıl alabilirim?

Bu ayarları geri almak oldukça basittir. İlgili yapılandırma değerini false olarak ayarlamanız yeterlidir:

git config --global core.untrackedCache false
git config --global core.fsmonitor false

Eğer bir ayarı tamamen kaldırmak isterseniz, --unset bayrağını kullanabilirsiniz:

git config --global --unset core.untrackedCache
git config --global --unset core.fsmonitor

Farklı işletim sistemlerinde (Windows, macOS, Linux) farklılık gösterir mi?

core.untrackedCache özelliği tüm işletim sistemlerinde benzer şekilde çalışır. Ancak core.fsmonitor, işletim sisteminin yerel dosya sistemi izleme API’larını kullandığı için platforma özgü uygulamalara sahiptir. Linux’ta inotify, macOS’ta FSEvents ve Windows’ta ReadDirectoryChangesW gibi mekanizmalar kullanılır. Bu, her işletim sisteminde en iyi performansı sağlamak için Git’in ilgili platforma özel yardımcı süreçleri (helper processes) kullandığı anlamına gelir. Genel olarak, modern ve güncel işletim sistemlerinde bu özelliğin sorunsuz çalışması beklenir.

Bu ayarlar Git’in diğer komutlarını da hızlandırır mı?

Evet, bu ayarlar özellikle çalışma diziniyle etkileşimde bulunan ve dosya sistemi taraması gerektiren diğer Git komutlarının performansını da dolaylı olarak etkileyebilir. Örneğin, git add, git commit (özellikle çok sayıda değiştirilmiş dosya olduğunda), git diff gibi komutlar da dosya sistemi taramalarına ihtiyaç duyar. untrackedCache ve fsmonitor sayesinde, Git’in dosya sistemi hakkında daha güncel ve önbelleğe alınmış bilgilere sahip olması, bu komutların da daha verimli çalışmasına katkıda bulunabilir. Ancak en büyük etkiyi git status üzerinde gösterirler.

Sonuç

Büyük Git depolarında yaşanan git status yavaşlığı, birçok geliştirici için günlük bir çile haline gelebilir. Ancak bu makalede detaylarıyla ele aldığımız core.untrackedCache ve core.fsmonitor gibi iki basit yapılandırma ayarı sayesinde, bu sorunu kökten çözmek ve geliştirme deneyiminizi önemli ölçüde iyileştirmek mümkündür. 17.6 saniye süren bir komutun 0.83 saniyeye düşmesi, sadece bir örnek değil, bu optimizasyonların potansiyelini gösteren somut bir veridir. Bu ayarlar, Git’in dosya sistemiyle olan etkileşimini akıllıca yöneterek, gereksiz taramaları ve hesaplamaları ortadan kaldırır, böylece daha hızlı ve daha duyarlı bir versiyon kontrol deneyimi sunar.

Bu ayarları uygulamak için sadece birkaç terminal komutu yeterlidir ve elde edeceğiniz performans kazancı, harcadığınız zamana fazlasıyla değecektir. Ayrıca, .gitignore dosyasını etkin kullanmak, sparse checkout ve shallow clone gibi diğer ileri düzey teknikleri de değerlendirerek Git performansınızı daha da ileri taşıyabilirsiniz. Unutmayın ki, verimli bir geliştirme ortamı, üretkenliğin temelidir. Git’inizi optimize ederek, kod yazmaya ve yenilikçi çözümler üretmeye daha fazla zaman ayırabilirsiniz. Eğer büyük bir Git deposunda çalışıyorsanız ve henüz bu ayarları denemediyseniz, şimdi tam zamanı! Kendi depolarınızda bu farkı deneyimleyin ve geliştirme akışınızdaki hızlanmanın keyfini çıkarın.

#GitPerformans #VersiyonKontrol #YazılımGeliştirme #DevOps #GitOptimizasyon

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Mobil sürümden çık