Ders 11 / 12
Depo Öznitelikleri
Öznitelik dosyası hangi işlemin hangi dosyada nasıl davranacağını belirler: ayarsız bin işlemelik tarihçe 5888 nesne yazar, satır sonu 162 gereksiz nesne üretir ve elli birleştirmenin 43'ü üretilen dosyada çakışarak 86 nesne daha ekler.
İçindekiler
Önceki dersin ölçümü bir varsayımı dışarıda bıraktı: çalışma alanına çıkarılan dosyaların iki düzende de aynı olduğu varsayımını. Bu, dosyanın nasıl yazıldığının bir tercih olmadığını söylüyordu.
Öyle değildir. Nesne deposundaki damla ile çalışma alanındaki dosya birbirinin aynısı olmak zorunda değildir; arada bir dönüşüm katmanı vardır ve o katman yapılandırılabilir. Katman ayarsız bırakıldığında sessizce çalışır ve yaptığı iş tarihçeye yazılır. Bu dersin sorusu şudur: hangi öznitelik hangi işlemi hangi dosyada değiştirir, ve ayarsız durumda içeriği değişmediği hâlde kaç nesne yazılır?
Öznitelik Dosyası Neyi Belirler
Depo öznitelikleri (repository attributes), dosya desenlerine davranış bağlayan
kurallardır ve .gitattributes dosyasında dururlar. Dosya işlenen bir dosyadır: tarihçeye
girer, dallar arasında farklılaşabilir ve klonlayan herkese aynı kuralı taşır. Yapılandırma
dosyasından ayıran yer burasıdır — yapılandırma kişiseldir ve kopyaya özeldir, öznitelik
depoya aittir.
# öznitelik dosyası — örnek döküm, çalıştırılmamıştır # .gitattributes * text=auto *.py text eol=lf *.md text eol=lf ayar.py text merge=ours sunum.bin -text -diff belge.md diff=metin
Her satır bir desen ve ona bağlı niteliklerdir. text dosyanın metin sayılacağını ve satır
sonu dönüşümüne girebileceğini bildirir; text=auto kararı içeriğe bakarak aracın vermesini
ister. eol=lf çalışma alanına yazılırken hangi satır sonu (line ending) düzeninin
kullanılacağını sabitler. Başındaki eksi işareti niteliği kaldırır: -text dosyanın hiçbir
dönüşüme girmeyeceğini, -diff ise karşılaştırmanın metin olarak denenmeyeceğini bildirir.
merge=ours ve diff=metin ise bir birleştirme sürücüsüne (merge driver) ya da bir
karşılaştırma tanımına ad verir.
Dört İşlem, Dört Ayrı An
Öznitelikler dört ayrı anda devreye girer ve hangisinin ne zaman çalıştığı karışırsa ölçüm de karışır.
Çıkarma anı: damla çalışma alanına yazılırken satır sonu dönüşümü uygulanır. İşleme anı: çalışma alanındaki dosya damlaya çevrilirken ters dönüşüm uygulanır — depoya yazılan biçim tektir. Birleştirme anı: iki yanın değişikliği harmanlanırken hangi sürücünün kullanılacağı belirlenir. Karşılaştırma anı: iki damla arasındaki fark üretilirken metin sayılıp sayılmayacağı belirlenir.
Beşinci bir an daha vardır ve tarihçeyi hiç ilgilendirmez: deponun bir sürümü arşiv olarak paketlenirken hangi yolların dışarıda bırakılacağı da bir öznitelikle bildirilir. Kural paketlemeye bakar, işlemeye değil; dosya tarihçede kalır, yalnız arşive girmez. Bu ders onu ölçmüyor çünkü nesne birimiyle karşılığı yoktur.
İlk ikisi tarihçeye nesne yazar; son ikisinden yalnız birleştirme yazar. Karşılaştırma
okunabilirliği etkiler, tarihçeyi etkilemez — bu yüzden ölçümde -diff satırı sıfır verir ve
bu bir eksiklik değil, doğru sonuçtur.
Satır sonu dönüşümü ayarsızken ne olur? Depoya, yazanın ortamında ne varsa o girer. İki ayrı satır sonu düzeni kullanan iki ortam aynı dosyaya sırayla dokunduğunda, içerik hiç değişmese bile damla baştan yazılır: bayt dizisi farklıdır, dolayısıyla nesne farklıdır.
Ölçümün Varsayımları
- BD20 — Ölçüm ortak kurgunun dört ölçeğini kullanır. Her işlemeye ayrı bir üreteçten iki alan eklenir: yazanın satır sonu düzeni ve içeriğin gerçekten değişip değişmediği.
- BD21 — İşlemelerin üçte biri ayrı bir satır sonu düzeni kullanan bir ortamdan gelir; beşte biri içeriği gerçekten değiştirmez, yalnız dosyaya dokunur.
- BD22 — Satır sonu ayarı yokken, içeriği değişmemiş bir işleme ancak dosyanın son kaydedilen düzeni farklıysa yeni damla yazar; her böyle yazım 2 nesnedir. Ayar varsayıldığında bu işlemeler 0 nesne yazar.
- BD23 — Her 20 işlemede bir birleştirme yapılır; pencerenin iki yarısı da üretilen dosyaya dokunduysa birleştirme çakışması doğar. Elle çözüm bir işleme yazar, 2 nesne.
- BD24 —
merge=ourstanımlandığında çakışma doğmaz ve çözüm işlemesi yazılmaz; sürücü üretilen dosyada karşı yanın sürümünü almaz. - BD25 —
-textve-diffikili varlığa hiçbir nesne eklemez ve hiçbirini çıkarmaz; etkileri çıkarma ve karşılaştırma anındadır, tarihçede değil. - BD26 — Bedel dokunulan nesne birimiyle sayılır. “Ayarsız” sütunu taban, “tam ayarlı” sütunu ortak kurgunun klon bedelidir; aradaki fark özniteliğin yazılmasını engellediği nesnedir.
Ölçüm
"""Depo oznitelikleri: ayarsiz durumda dogan gereksiz nesne. Bolum 1 - hangi oznitelik hangi dosyada hangi islemi degistiriyor (1000 isleme). Bolum 2 - dort olcekte ayarsiz, satir sonu ayarli ve tam ayarli nesne. """ TOHUM = 20260814 DOSYALAR = ("olcum.py", "rapor.py", "kimlik.py", "ayar.py", "belge.md") IKILI_VARLIK = "sunum.bin" URETILEN = "ayar.py" # uretilen dosya: birlestirme surucusu buna baglanir OLCEKLER = (50, 200, 1000, 4000) BIRLESME_ARALIGI = 20 # her 20 islemede bir birlestirme def uretec(tohum): d = tohum % 2147483646 + 1 def r(n): nonlocal d d = (d * 48271) % 2147483647 return d % n return r def tarihce(n, tohum=TOHUM): """n islemelik dogrusal tarihce; her isleme bir dosyaya dokunuyor.""" r, liste = uretec(tohum), [] for i in range(n): dosya = DOSYALAR[r(5)] ikili = r(11) == 0 liste.append({"no": i + 1, "dosya": dosya, "ikili": ikili, "nesne": 2 + (40 if ikili else 0)}) return liste def klon_bedeli(t, ikili_dahil=True): return sum(x["nesne"] for x in t if ikili_dahil or not x["ikili"]) def ortamli(t, tohum): """Her islemeye yazanin satir sonu duzeni ve icerigin gercekten degisip degismedigi eklenir.""" r, k = uretec(tohum), [] for x in t: k.append({**x, "crlf": r(3) == 0, "gercek": r(5) != 0}) return k def satir_sonu_nesnesi(k, dosya=None): """Ayarsizken: icerik ayni oldugu halde satir sonu duzeni degistigi icin yeniden yazilan damla. Dosya basina son duzen izlenir.""" son, gereksiz = {}, 0 for x in k: if x["dosya"] == dosya or dosya is None: if not x["gercek"] and son.get(x["dosya"]) not in (None, x["crlf"]): gereksiz += 2 son[x["dosya"]] = x["crlf"] return gereksiz def cakisan_birlesmeler(k): """Her aralikta bir birlestirme; iki yan da uretilen dosyaya dokunduysa cakisma dogar ve elle cozum bir isleme yazar.""" sayi = 0 for bas in range(0, len(k) - BIRLESME_ARALIGI + 1, BIRLESME_ARALIGI): pencere = k[bas:bas + BIRLESME_ARALIGI] yarim = BIRLESME_ARALIGI // 2 sol = any(x["dosya"] == URETILEN for x in pencere[:yarim]) sag = any(x["dosya"] == URETILEN for x in pencere[yarim:]) sayi += sol and sag return sayi def surucu_nesnesi(k): return 2 * cakisan_birlesmeler(k) K = ortamli(tarihce(1000), TOHUM + 7) print("dosya oznitelik degistirdigi islem satir sonu nesnesi" " surucu nesnesi") OZNITELIK = (("olcum.py", "text eol=lf", "cikarma ve isleme"), ("rapor.py", "text eol=lf", "cikarma ve isleme"), ("kimlik.py", "text eol=lf", "cikarma ve isleme"), ("ayar.py", "text merge=ours", "cikarma, isleme, birlestirme"), ("belge.md", "text eol=lf", "cikarma ve isleme"), (IKILI_VARLIK, "-text -diff", "cikarma ve karsilastirma")) for dosya, oz, islem in OZNITELIK: s = 0 if dosya == IKILI_VARLIK else satir_sonu_nesnesi(K, dosya) d = surucu_nesnesi(K) if dosya == URETILEN else 0 print(f" {dosya:10s} {oz:16s} {islem:26s} {s:16d} {d:15d}") print() print("isleme ayarsiz nesne satir sonu ayarli tam ayarli gereksiz nesne oran") for n in OLCEKLER: k = ortamli(tarihce(n), TOHUM + 7) tam, s, d = klon_bedeli(k), satir_sonu_nesnesi(k), surucu_nesnesi(k) print(f"{n:6d} {tam + s + d:14d} {tam + d:18d} {tam:11d} {s + d:15d} " f"{(s + d) / (tam + s + d):6.4f}") print() n = 1000 k = ortamli(tarihce(n), TOHUM + 7) print(f"tarihce {n} isleme; satir sonu yuzunden yeniden yazilan damla " f"{satir_sonu_nesnesi(k) // 2}, yazdigi nesne {satir_sonu_nesnesi(k)}") print(f"birlestirme {n // BIRLESME_ARALIGI}, uretilen dosyada cakisan " f"{cakisan_birlesmeler(k)}, elle cozumun yazdigi nesne {surucu_nesnesi(k)}")
dosya oznitelik degistirdigi islem satir sonu nesnesi surucu nesnesi
olcum.py text eol=lf cikarma ve isleme 38 0
rapor.py text eol=lf cikarma ve isleme 34 0
kimlik.py text eol=lf cikarma ve isleme 22 0
ayar.py text merge=ours cikarma, isleme, birlestirme 36 86
belge.md text eol=lf cikarma ve isleme 32 0
sunum.bin -text -diff cikarma ve karsilastirma 0 0
isleme ayarsiz nesne satir sonu ayarli tam ayarli gereksiz nesne oran
50 390 384 380 10 0.0256
200 972 938 920 52 0.0535
1000 5888 5726 5640 248 0.0421
4000 23578 22912 22600 978 0.0415
tarihce 1000 isleme; satir sonu yuzunden yeniden yazilan damla 81, yazdigi nesne 162
birlestirme 50, uretilen dosyada cakisan 43, elle cozumun yazdigi nesne 86
Hangi Öznitelik Hangi Dosyada
Üst tablo dersin birinci sorusunu yanıtlıyor ve dikkat çeken şey sütunların birbirinden bağımsız olmasıdır.
Satır sonu sütunu beş metin dosyasına dağılıyor: 38, 34, 22, 36 ve 32 — toplam 162 nesne. Dağılım eşit değil ama nedeni özniteliğin kendisi değil, kurgunun dosya dağılımı. Öznitelik açısından beş satır aynı kuralı taşıyor; ödenen bedel dosyanın ne sıklıkta dokunulduğuna göre değişiyor.
Sürücü sütunu tek bir satırda toplanıyor: 86 nesne, yalnız ayar.py satırında. Bu, kurgu
gereği üretilen dosyadır — elle yazılmayan, bir araç tarafından üretilip depoya konan bir
dosya. Öbür dört dosyada sürücü sütunu 0’dır çünkü onlarda çakışma elle çözülmelidir ve
çözüm bir karardır, ayarla değiştirilecek bir şey değildir.
İkili varlık satırı iki sütunda da 0 veriyor. -text ve -diff nitelikleri gerçek işler
yapar — dönüşümü engeller, okunmaz karşılaştırmayı önler — ama tarihçeye tek nesne
eklemez ve çıkarmaz. Ölçünün birimi nesne olduğu için o etkiler burada görünmez. Bu satır,
ölçünün kapsam sınırının bildirimidir.
Ayarsızlığın Ödettiği
Alt tablonun birimi dokunulan nesnedir ve üç sütun aynı tarihçenin üç ayarlama düzeyini veriyor. Bin işlemelik tarihçe ayarsız 5888 nesne yazıyor; satır sonu ayarlandığında 5726’ya, birleştirme sürücüsü de tanımlandığında 5640’a — yani ortak kurgunun klon bedeline — iniyor. Gereksiz nesne 248, oran 0,0421.
Oran küçüktür ve bu, ölçümün dürüst sonucudur: satır sonu düzensizliği bir depoyu şişirmez. İki gözlem yine de kayda değer. Birincisi, gereksiz nesne oranı dört ölçekte 0,0256, 0,0535, 0,0421 ve 0,0415 çıkıyor; büyük iki ölçekte 0,042 dolayında oturuyor ve ölçek büyüdükçe azalmıyor. Bu, tarihçenin ömrü boyunca ödenmeye devam eden bir bedeldir. İkincisi, elli işlemelik satırdaki 10 nesne, o ölçekteki 1/50 çözünürlüğün yanında beş işlemeye karşılık gelir; küçük depoda bu bedelden bir sonuç çıkarılamaz.
Asıl sayı üçüncü satırda duruyor: 50 birleştirmenin 43’ü üretilen dosyada çakışıyor. Bu, birleştirmelerin beşte dördünden fazlasıdır ve her biri bir kişinin oturup çakışma işaretlerini elle temizlemesi demektir. Tarihçeye yazdığı 86 nesne bu işin en küçük parçasıdır; ölçülmeyen kısmı, kırk üç kez verilen ve hiçbirinin bir bilgi taşımadığı karardır. Dallanma ve İşbirliği kursu çakışma çözümünün tarihçeye yazılmadığını göstermişti — burada görülen şey, o yazılmayan kararların kırk üç tanesinin baştan gereksiz olduğudur.
Hangi Satır Kazanır
Ölçüm her dosyaya tek bir kural düştüğünü varsaydı. Gerçek bir öznitelik dosyasında bir yola birden çok desen uyar ve hangisinin kazandığı bilinmeden hiçbir ayarın etkisi öngörülemez.
Kural sırası üç katmanlıdır. Aynı dosya içinde son eşleşen satır kazanır — yukarıdan aşağı okunur ve alttaki üsttekini ezer; bu yüzden genel desenler başa, özel desenler sona yazılır. Alt dizindeki öznitelik dosyası üsttekini ezer, çünkü daha yakındır. Ve deponun içinde, tarihçeye girmeyen yerel bir öznitelik dosyası daha vardır; o hepsini ezer ve yalnız o kopyada geçerlidir.
Üçüncü katman iki yönlü keskindir. Bir kopyanın davranışını depoyu değiştirmeden ayarlamayı sağlar; aynı nedenle, bir kopyada beklenmedik bir dönüşüm görüldüğünde bakılacak ilk yer orasıdır. Öznitelikler depoya aittir demiştik — bu, o yerel katman dışında doğrudur ve farkın nerede olduğu bilinmezse bir dosyanın neden başka türlü çıktığı hiç anlaşılmaz.
Bir nitelik üç değer alabilir: verilmiş (text), kaldırılmış (-text) ve belirtilmemiş.
Üçüncüsü ikinciyle aynı şey değildir: kaldırılmış bir nitelik kararı kesinleştirir,
belirtilmemiş bir nitelik kararı bir alt katmana ya da aracın kendi öntanımına bırakır.
text=auto tam olarak bu üçüncü durumu yönetir — kararı içeriğe bakarak verir ve ikili
sandığı dosyaya dönüşüm uygulamaz.
Ayarın Sınırı ve Kurtarma
Öznitelik dosyası ileriye dönük çalışır. Bugün yazılan bir text=auto satırı, dün yazılmış
damlaları düzeltmez; tarihçedeki 162 nesne yerinde kalır. Ayarın etkisi ilk çıkarmadan
sonra başlar ve depo çalışanların ellerinde zaten çıkarılmış durumdaysa, dosyaların bir kez
yeniden normalize edilmesi gerekir — bu, tarihçede yeni bir işleme olarak görünür ve
tarihçeyi yeniden yazmaz.
Yeniden yazan yol da vardır ve konunun ikinci dersindeki kuralla aynı sınıra girer: geçmişteki bütün damlaları normalize etmek tarihçeyi yeniden yazmaktır, kimlikleri değiştirir, geri alınamaz ve her kopyanın yeniden klonlanmasını gerektirir. Kazancı ölçümde okunuyor — 162 nesne. Bin işlemelik bir depoda bu, klon bedelinin otuz beşte biri kadardır ve o kazanç için tarihçeyi yeniden yazmak neredeyse hiçbir durumda haklı çıkmaz.
Ucuz ve geri alınabilir yol şudur: öznitelik dosyası deponun ilk gününde yazılır; sonradan yazıldıysa tek bir normalizasyon işlemesiyle ileriye dönük düzeltilir; geçmiş olduğu gibi bırakılır. Yanlış bir öznitelik satırının kendisi ise zararsızdır — dosya işlenen bir dosya olduğu için satır geri alınabilir, ve dönüşüm bir sonraki çıkarmada eski hâline döner.
Özet
- Depo öznitelikleri işlenen bir dosyada durur ve depoya aittir; yapılandırmadan farkı budur. Dört ayrı anda devreye girerler: çıkarma, işleme, birleştirme ve karşılaştırma.
- Karşılaştırma anı tarihçeye nesne yazmaz; ikili varlık satırı ölçümde iki sütunda da 0 verir ve bu, ölçünün kapsam sınırının bildirimidir.
- Satır sonu ayarsızken içeriği değişmemiş 81 işleme yeni damla yazar ve 162 nesne üretir; beş metin dosyasına 38 / 34 / 22 / 36 / 32 olarak dağılır.
- Üretilen dosyada birleştirme sürücüsü tanımsızken 50 birleştirmenin 43’ü çakışır ve
elle çözüm 86 nesne yazar;
merge=oursbu çakışmaların tümünü ortadan kaldırır. - Bin işlemede ayarsız tarihçe 5888, tam ayarlı tarihçe 5640 nesnedir; gereksiz 248 nesnenin oranı 0,0421’dir ve ölçek büyüdükçe azalmaz.
Sonraki Adım
Bu konunun dört dersi aynı depoya dört ayrı müdahale yaptı: bağımlı depoyu gömdü, ikili gövdeyi dışarı taşıdı, çalışma ağacını çoğalttı ve dönüşüm katmanını ayarladı. Dördü de tek bir soruyu varsaydı — deponun sınırının nerede olduğunu. Sonraki ders o varsayımı ölçer: aynı iş tek bir depoda ve dört ayrı depoda yapılırsa, klon bedeli ile arama adımı nasıl değişir, ve bileşenler arasında sorulan sorulardan kaçı ikinci düzende yanıtsız kalır?
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.