Git'in Push'umu Reddettiği Gün
Bir gün git, çalışmamı kaydetmeme öylece izin vermez oldu. Push’um daha önce hiç görmediğim bir sunucu hatasıyla başarısız oldu — bir merge çakışması değil, bir izin sorunu değil, sadece diğer uçtan gelen düz bir ret. Haftalardır mutlu mesut commit’liyordum ve şimdi günümün en sıradan komutu tamamlanmıyordu.
Sebep git’teki bir hata değildi. O haftaları sessizce, depomu orada işi olmayan binlerce şeyle tıka basa doldurarak geçirmiş olmamdı ve depo nihayet kaldırılamayacak kadar ağırlaşmıştı.
Bir türlü gitmeyen push
İlk başta bunun bir tesadüf olduğunu varsaydım — bir ağ tıkanması, kötü bir an yaşayan bir sunucu. Ama olmaya devam etti, güvenilir bir şekilde, her seferinde. Depoda birikmiş hacim sebep gibi görünüyordu: push her seferinde aynı şekilde başarısız olmaya devam ediyordu ve geçici değil yapısal olan bir sorunu hiçbir tekrar denemesi düzeltemeyecekti.
Deponun gerçekte ne içerdiğine nihayet baktığımda, cevap utanç vericiydi. Kod — bir deponun var olma amacı — onun küçük bir azınlığıydı. Ezici çoğunluk veriydi: binlerce üretilmiş dosya, önbellek ve derlenmiş artefakt; her biri sadakatle izleniyor, sürümleniyor ve her işlemde sürükleniyordu.
Bir depo sessizce nasıl bir depoya dönüşür
Kimse gigabaytlarca veriyi sürüm kontrolüne koymaya karar vermez. Bu, her seferinde makul görünen bir adımla olur. Birkaç dosya üretirsiniz ve onlar proje klasörünüze düşer. Belki biraz dikkatsizce bir add komutu çalıştırırsınız ve onlar da gelir. İşe yarar. Hiçbir şey şikâyet etmez. Böylece bunu tekrar tekrar yaparsınız ve depo, bir çekmecenin pisliği biriktirdiği gibi veri biriktirir — görünmez bir şekilde, ta ki kapanmadığı güne kadar.
Git push’umu reddettiğinde, binlerce veri dosyasını izliyordum. Onları sürüm kontrolüne koymak gibi bilinçli bir seçim hiç yapmamıştım. Sadece onları dışarıda tutma seçimini hiç yapmamıştım.
Veri ve kod zıt şeyler ister
Bunları karıştırmanın can yakmasının sebebi, tamamen farklı nedenlerle sürümlenmeleridir. Kod küçüktür, anlamlıdır ve satır satır görmek isteyeceğiniz şekillerde değişir — git tam olarak bunun için inşa edilmiştir. Veri büyüktür, opaktır ve toptan değişme eğilimindedir; onun satır satır bir diff’i size neredeyse hiçbir şey söylemez ve onun her geçmiş sürümünü sonsuza dek saklamak çoğunlukla israftır. Git ilk işte muhteşemdir; standart geçmişi ise ikincisi için, en azından veri büyüdüğünde veya sürekli değiştiğinde, çoğu zaman kötü bir uyumdur.
Bunları bir araya koyun ve her ikisinin de en kötüsünü elde edersiniz. Geçmişiniz, asla anlamlı bir şekilde okuyamayacağınız devasa değişikliklerle şişer, her clone ve push hepsini etrafta sürükler ve o küçük, değerli şey — gerçek kaynak — çoğunlukla balasttan ibaret bir depoda gömülü kalır.
Çözüm: atladığınız sınırı çizin
Onarım kavramsal olarak basit ve biraz da sıkıcıydı: git’e, açıkça, neyi izlememesi gerektiğini söyleyin. Üretilmiş dosyalar, önbellekler, derlenmiş artefaktlar — hepsi dışlandı ve depo her zaman olması gereken şeye geri döndü: kasıtlı olarak yazdığım şeylerin — kod, yapılandırma, dokümanlar, testler — bir yuvası; toplu üretilmiş çıktının değil. Veri ise büyük, yeniden üretilebilir şeylerin ait olduğu yere taşındı — talep üzerine üretilen ya da büyük dosyalar için inşa edilmiş bir yerde saklanan, ama bir daha asla sanki kaynakmış gibi satır satır sürümlenmeyen bir yere.
Push ilk denemede geçti. Çözüm zekice değildi. Sadece ilk günden çizmem gereken ve hiç çizmediğim bir sınırdı.
Altta yatan alışkanlık: kaynak mı, türev mi
Kalıcı ders aslında git ile ilgili değil. Bir projenin ürettiği her dosya hakkında artık sorduğum bir soru: bunu ben mi yazdım, yoksa kodum mu üretti? Bu kaynak mı — bir insanın yazdığı, yeri doldurulamaz şey — yoksa türev mi, kaynağı tekrar çalıştırarak yeniden oluşturulabilecek bir çıktı mı?
Kaynak genellikle sürüm kontrolüne aittir. Büyük veya hantal türev dosyalar ise genellikle ait değildir — yalnızca yeniden üretilebilirlik ya da iş akışı gerçekten gerektirdiğinde commit’lenmeli ve ideal olarak her an kaynaktan yeniden üretilebilir kalmalıdırlar. Yönetilemez bir karmaşaya çürüyen depoların çoğu bunu, bu ayrımın izini kaybederek yapar — türev olan bir şeye sanki değerliymiş gibi davranarak ve her zaman yeniden üretilebilecek şeylerin, asla yerine konulamayacak şeylerin yanında yığılmasına izin vererek.
Git o gün bozulmadı. Sadece nihayet, kaynak ile çıktıyı ayrı yerlerinde tutmayı bıraktığımı ve bir araçtan asla inşa edilmediği bir işi yapmasını istediğimi fark etmemi sağladı.
— Sinyal yok, getiri yok, yatırım tavsiyesi değildir.