Ders 15 / 15
Yama Tabanlı Katkı
Yama bir metin dosyasıdır ve çizgeyi değil değişikliği kodlar: tarihçeyle itme 15 işlemede 5 soru, posta biçimli seri 12 işlemede 4, düz fark serisi 12 işlemede 3, tek düz fark 1 işlemede 1 soru bırakır ve düz farkta yazarı korunan işleme 0'dır.
İçindekiler
Önceki dersin akışı bir depo platformu varsaydı: ortak bir adres, bir tartışma alanı ve tümleştirme kararını verecek bir yetki. Katkının bunların hiçbiri olmadan gittiği bir biçim daha vardır ve sürüm kontrolünün en eski katkı biçimi budur: değişikliğin dosya olarak gönderilmesi.
Yama, bir depoya değil bir posta kutusuna sığar. Bu dersin sorusu yamanın nasıl üretildiği değil — üretimi iki komuttan ibarettir. Soru şudur: yama karşı tarafa neyi taşır, neyi taşımaz, ve taşımadığı alan altı sorunun neresine düşer?
İki Yama Biçimi
Yama (patch), bir değişikliğin metin olarak kodlanmış hâlidir ve iki ayrı biçimi vardır. Birincisi düz farktır: yalnız değişiklik metnini taşır, üstveri taşımaz.
# öğretilen komutlar — örnek döküm, çalıştırılmamıştır git diff yukari/ana..olcum > olcum.patch git apply --check olcum.patch git apply olcum.patch
--check seçeneği yamayı uygulamadan sınar ve çalışma alanına dokunmaz. Uygulama başarılı
olduğunda değişiklikler çalışma alanına yazılır ve hiçbir işleme oluşmaz: işlemeyi
uygulayan yazar, kendi adıyla ve kendi zamanıyla.
İkincisi posta biçimli yama serisidir: her işleme için bir dosya üretilir ve dosyanın başında bir posta başlığı durur.
# öğretilen komutlar ve dosya başı — örnek döküm, çalıştırılmamıştır git format-patch yukari/ana..olcum -o yamalar/ git am --3way yamalar/0001-olcum-esigini-yapilandirmadan-oku.patch From <işleme kimliği> Mon Sep 17 00:00:00 2001 From: yazan <[email protected]> Date: <yazar tarihi> Subject: [PATCH 1/4] Ölçüm eşiğini yapılandırmadan oku Eşik değeri betiğe gömülüydü; ölçüm noktası değiştiğinde betiği düzenlemek gerekiyordu. --- olcum.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Başlıktaki üç alan doğrudan işlemeye geçer: yazar, yazar tarihi ve mesaj. git am her dosya
için bir işleme yazar ve bu alanları yerelden değil dosyadan okur. --3way seçeneği,
yama doğrudan uymadığında ortak tabana bakarak üç yollu birleştirme dener; çakışma çıkarsa
karar yine elle verilir.
Yamanın Taşıyamadığı
İki biçimin de taşıyamadığı bir alan sınıfı var ve nedeni yapısaldır. Yama bir metin dosyasıdır ve bir değişikliği kodlar; tarihçe ise bir çizgedir ve metin dosyası kenar taşımaz. Bu yüzden yamanın karşı tarafta ürettiği işleme her zaman yeni kimliklidir, öncül bağı uygulandığı yerin ucudur ve dal kaydı hiç geçmez — yamada dal diye bir şey yoktur, yalnız dosya vardır.
Ölçüm bu nedenle tarihçeyi taşınan üstveri kümesinden türetir; biçimleri elle betimlemez.
Ölçümün Varsayımları
- UD25 — Aynı on iki işlemelik gelişim dört ayrı katkı biçimiyle karşı tarafa taşınır; üretilen kod dördünde de aynıdır ve ölçülen tek şey karşı tarafta kalan üstveridir.
- UD26 — Her biçim bir taşınan üstveri kümesiyle tanımlanır; karşı taraftaki tarihçe bu kümeden hesaplanır, elle yazılmaz.
- UD27 — Posta biçimli seri yazarı, yazar zamanını ve mesajı taşır; dal kaydını ve öncül bağını taşımaz.
- UD28 — Düz fark serisi yalnız değişiklik metnini ve mesajı taşır; yazar ve zaman uygulama anında yerelden yazılır ve bu ölçümde “taşımaz” sayılır.
- UD29 — Tek düz fark, on iki işlemenin farkını tek dosyada toplar ve karşı tarafta tek işleme olur; sıkıştırmanın en uç biçimidir.
- UD30 — “Yazarı korunan” sütunu, karşı tarafta yazar alanı özgün katkıcıyı gösteren işlemeleri sayar; birleştirme işlemeleri tümleştirenin adına yazıldığı için sayıma girmez.
Ölçüm
"""Yama tabanlı katkı: taşınan üstveri ve taşınmayanın bedeli. Bölüm 1 - dört katkı biçiminin taşıdığı üstveri alanları. Bölüm 2 - aynı biçimlerin bıraktığı tarihçe ve yanıtladığı soru. """ TOHUM = 20260813 DALLAR = ("olcum", "rapor", "kimlik") DOSYALAR = {"olcum": "olcum.py", "rapor": "rapor.py", "kimlik": "kimlik.py"} KUSURLU = ("rapor", 2) ORTAK_DOSYA = "ayar.py" USTVERI = ("yazar", "yazar zamanı", "konu ve gövde", "dal kaydı", "öncül bağı") TASINAN = {"tarihçeyle itme": set(USTVERI), "posta biçimli seri": {"yazar", "yazar zamanı", "konu ve gövde"}, "düz fark serisi": {"konu ve gövde"}, "tek düz fark": set()} def uretec(tohum): d = tohum % 2147483646 + 1 def r(n): nonlocal d d = (d * 48271) % 2147483647 return d % n return r def gelisim(): """Gerçek gelişim: üç dal, dörder işleme, biri kusuru getiriyor.""" r, kayit, zaman = uretec(TOHUM), [], 0 for adim in range(1, 5): for dal in DALLAR: zaman += 1 + r(3) dosya = ORTAK_DOSYA if adim == 3 and dal in ("olcum", "rapor") else DOSYALAR[dal] kayit.append({"dal": dal, "sira": adim, "dosya": dosya, "kusurlu": (dal, adim) == KUSURLU, "zaman": zaman}) return kayit def uygula(kayit, tur): """Katkının karşı tarafta bıraktığı tarihçe: taşınan üstveriden türer.""" tasinan = TASINAN[tur] if tur == "tarihçeyle itme": t = [] for dal in DALLAR: for k in [x for x in kayit if x["dal"] == dal]: t.append({**k, "dal_kaydi": dal, "zaman_korundu": True, "yazar_korundu": True}) t.append({"dal": dal, "sira": 0, "dosya": None, "kusurlu": False, "zaman": max(x["zaman"] for x in kayit if x["dal"] == dal), "dal_kaydi": dal, "birlesme": True, "zaman_korundu": True, "yazar_korundu": False}) return t if tur == "tek düz fark": return [{"dal": None, "sira": 0, "dosya": sorted({x["dosya"] for x in kayit}), "kusurlu": any(x["kusurlu"] for x in kayit), "zaman": max(x["zaman"] for x in kayit), "dal_kaydi": None, "zaman_korundu": False, "yazar_korundu": False, "sikisik": len(kayit)}] return [{**k, "dal_kaydi": k["dal"] if "dal kaydı" in tasinan else None, "zaman_korundu": "yazar zamanı" in tasinan, "yazar_korundu": "yazar" in tasinan} for dal in DALLAR for k in kayit if k["dal"] == dal] def s1(t): return all(x.get("dal_kaydi") for x in t if not x.get("birlesme")) def s2(t): k = [x for x in t if x["kusurlu"]] return len(k) == 1 and not k[0].get("sikisik") def s3(t): return all(x.get("zaman_korundu") for x in t) def s4(t): return all(isinstance(x["dosya"], str) or x.get("birlesme") for x in t) def s5(t): yerler = {} for i, x in enumerate(t): if x.get("birlesme"): continue yerler.setdefault(x["dal"], []).append(i) return all(y[-1] - y[0] == len(y) - 1 for y in yerler.values()) def s6(t): return any("secilen" in x for x in t) SORULAR = (("özellik gruplaması", s1), ("kusurun yalıtımı", s2), ("gerçek sıra", s3), ("dosya izi", s4), ("dalın bütünlüğü", s5), ("çakışma kararı", s6)) kayit = gelisim() print(f"gerçek gelişim {len(kayit)} işleme, {len(DALLAR)} dal, " f"kusurlu işleme {sum(k['kusurlu'] for k in kayit)}") print() print("üstveri alanı " + "".join(f"{ad:>20s}" for ad in TASINAN)) for alan in USTVERI: print(f" {alan:13s}" + "".join(f"{('taşır' if alan in TASINAN[t] else 'taşımaz'):>20s}" for t in TASINAN)) print() print("katkı biçimi işleme yazarı korunan ayrı okunabilir yanıtlanan kaybolan") for tur in TASINAN: t = uygula(kayit, tur) ayri = sum(1 for x in t if not x.get("birlesme") and not x.get("sikisik")) print(f" {tur:20s} {len(t):6d} {sum(x['yazar_korundu'] for x in t):15d}" f" {ayri:16d} {sum(f(t) for _, f in SORULAR):11d} {len(kayit) - ayri:9d}") print() print("yanıtlanamayan sorular:") for tur in TASINAN: t = uygula(kayit, tur) print(f" {tur:20s} " + ", ".join(ad for ad, f in SORULAR if not f(t)))
gerçek gelişim 12 işleme, 3 dal, kusurlu işleme 1 üstveri alanı tarihçeyle itme posta biçimli seri düz fark serisi tek düz fark yazar taşır taşır taşımaz taşımaz yazar zamanı taşır taşır taşımaz taşımaz konu ve gövde taşır taşır taşır taşımaz dal kaydı taşır taşımaz taşımaz taşımaz öncül bağı taşır taşımaz taşımaz taşımaz katkı biçimi işleme yazarı korunan ayrı okunabilir yanıtlanan kaybolan tarihçeyle itme 15 12 12 5 0 posta biçimli seri 12 12 12 4 0 düz fark serisi 12 0 12 3 0 tek düz fark 1 0 0 1 12 yanıtlanamayan sorular: tarihçeyle itme çakışma kararı posta biçimli seri özellik gruplaması, çakışma kararı düz fark serisi özellik gruplaması, gerçek sıra, çakışma kararı tek düz fark özellik gruplaması, kusurun yalıtımı, gerçek sıra, dosya izi, çakışma kararı
Basamakların Okunması
Alt tablo dört basamak veriyor ve her basamağın bir üstveri karşılığı var.
Tarihçeyle itme on beş işleme ve 5 soru bırakıyor; bu ölçüt satırıdır, bütün alanlar geçmiştir.
Posta biçimli seri on iki işleme bırakıyor ve 4 soru yanıtlıyor. Düşen tek soru özellik gruplaması; nedeni üst tablonun dördüncü satırında yazılı, dal kaydı taşınmıyor. Yazar ve zaman taşındığı için “gerçek sıra” ayakta kalıyor.
Düz fark serisi de on iki işleme bırakıyor ama 3 soru yanıtlıyor. Fark tek bir alandan geliyor: yazar zamanı taşınmadığı için bütün işlemeler uygulama anının zamanını taşıyor ve gerçek sıra okunamıyor. Aynı sayıdaki işleme, tek bir üstveri alanı yüzünden bir soru daha az yanıtlıyor.
Tek düz fark on iki işlemeyi bire indiriyor, 1 soru yanıtlıyor, kaybolan işleme 12. Kursta ölçülen en düşük değer budur; sıkıştırma on iki işlemeyi üçe indirip 2 yanıtlıyordu. Altıncı soru ise dört satırda da yanıtsız — katkının hangi taşıma aracıyla gittiği bunu değiştirmiyor.
Ölçünün Görmediği Alan
Üçüncü satır kursun kendi ölçüsüne dönük bir uyarı taşıyor. Düz fark serisi ile posta biçimli seri arasında yazarı korunan sütunu 12’den 0’a düşüyor: on iki işlemenin hiçbiri artık yazanı göstermiyor, hepsi uygulayan kişinin adına yazılmış. Yanıtlanan soru ise yalnız 1 düşüyor ve düşen soru yazarla ilgili değil.
Nedeni açıktır: altı sorunun hiçbiri yazarı sormaz. Sorular gruplamayı, yalıtımı, sırayı, dosya izini, dal bütünlüğünü ve çakışma kararını sorar; katkının kime ait olduğu kümede yoktur, dolayısıyla ölçü onu göremez. Bu bir ölçü kusuru değil, ölçünün kapsamının bildirimidir. Katkı sahipliği ve imza o pencerenin dışındadır ve düz fark serisi bunları sessizce siler.
Özet
- Yama bir metin dosyasıdır ve değişikliği kodlar; çizgeyi kodlamadığı için işleme kimliği, öncül bağı ve dal kaydı hiçbir yama biçiminde taşınmaz. Posta biçimli seri yazarı, zamanı ve mesajı taşır; düz fark yalnız değişiklik metnini taşır.
- Dört katkı biçimi karşı tarafa 15, 12, 12 ve 1 işleme bırakır ve sırasıyla 5, 4, 3 ve 1 soru yanıtlar.
- Posta biçimli seri ile düz fark serisi aynı sayıda işleme bırakır; aradaki bir soruluk fark yalnız yazar zamanı alanının taşınmamasından gelir.
- Yazarı korunan işleme sayısı 12’den 0’a düştüğünde yanıtlanan soru yalnız bir azalır: altı sorunun hiçbiri yazarı sormaz ve bu, ölçünün kapsam sınırıdır.
Kurs Kapanışı
Kurs tek bir ölçüyle yürüdü: bir tümleştirme biçiminin sayısı, ürettiği kod değil, bıraktığı tarihçenin yanıtlayabildiği soru sayısıdır. On beş ders bu ölçüyü ayrı yerlere uyguladı.
| ders | ölçülen | yanıtlanan soru ya da kayıp |
|---|---|---|
| Dal Kavramı | dallanmanın maliyeti | 0 yeni işleme ve 123 bayt başvuru; kopya modeli aynı işi 12.000 dosya kopyalayarak yapar |
| Dal Oluşturma ve Geçiş | geçişin elde kalan değişikliğe yaptığı | 12 durumun 3’ü taşınır, 5’i engellenir, 4’ü geride kalır; sessiz kayıp 0 |
| Dal Adlandırma | ad düzeninin birinci soruya katkısı | 8 bileşimin 3’ünde grup okunur; kayıt tutmayan biçimde katkı 0 |
| Ayrık HEAD Durumu | erişilemeyen işlemenin tarihçeye maliyeti | 15 kayıt 13’e, yanıt 5’ten 4’e iner; üç sayım sorgusunun 3’ü de eksik yanıtlanır ve tarihçe bunu bildirmez |
| İleri Sarma ve Birleştirme İşlemesi | iki birleşme biçiminin bıraktığı tarihçe | 15 işleme / 5 soru ve 12 işleme / 3 soru; farkı gruplama ile dal bütünlüğü yaratır |
| Çakışma Çözümü | çözümün tarihçeye geçip geçmediği | dört biçimin dördü de altıncı soruyu yanıtlamaz, 0/4; gerekçe mesaja yazılırsa 15 işlemenin 1’i onu taşır |
| Yeniden Temellendirme | doğrusallaştırmanın bıraktığı tarihçe | 12 işleme / 3 soru; ileri sarmayla toplam eşit, kayıp ayrı, fark 1/6 |
| Kiraz Toplama | aynı değişikliğin iki yerde durması | dosya izi evet kalır, dokunan işleme 3’ten 4’e çıkar; kusurlu kopyada yanıt 5’ten 4’e iner |
| Birleştirme Stratejileri | dört biçim yan yana | 15/12/3/12 işleme ve 5/3/2/3 soru; sıkıştırmada kaybolan 12 |
| Dal Stratejileri | dal ömrünün tarihçeye yazdırdığı | 12, 15, 18 ve 24 işleme; üç dal düzeni de 5 soru yanıtlar — altı soru dal düzenlerini ayırmaz |
| Uzak Depo Tanımlama | tanımlamanın tarihçeye eklediği | üç kopya 5/10/15 işleme ve 4/5/5 soru; iki tanımdan sonra yerel 5 işleme / 4 soru |
| Getirme, Çekme ve İtme | üç işlemin değiştirdiği tarihçe | getirme dalı 5’te bırakır, çekme 16’ya ve 5 soruya taşır, itme karşı tarafı 10’dan 16’ya değiştirir |
| Çatallama ve Klonlama | yukarı deponun yanıtlayabildiği | 15/5, 12/3 ve 3/2; sıkıştırmada 3 soru yalnız çatal deposunda kalır |
| Değişiklik İsteği Akışı | akışın seçtiği biçimin bıraktığı | 5/3/2/3 soru; 11 kararın 7’si tarihçeye hiç girmez, sıkıştırmada yazılan 4’ü de okunmaz olur |
| Yama Tabanlı Katkı | yamanın taşıdığı ve taşımadığı üstveri | 15/5, 12/4, 12/3 ve 1/1; düz farkta yazarı korunan 0 ve altı soru bunu hiç sormaz |
Tablodan üç okuma çıkar. Birincisi: okunaklılık ile yanıtlanabilirlik ters yönde hareket eder — en temiz tarihçeler en az soru yanıtlayanlardır ve tarihçeyi temizlemek bilgi siler. İkincisi: altıncı soru hiçbir satırda yanıtlanmaz; çakışmanın nasıl çözüldüğü kaydın tanımı gereği kayıtta yoktur ve tek çare gerekçeyi işleme mesajına yazmaktır. Üçüncüsü: kayıp iki ayrı kaynaktan gelir. Biçim kaybı bilgiyi siler ve geri alınamaz; kapsam kaybı yalnız bir kopyanın eksikliğidir ve getirmeyle kapanır.
Kurs boyunca tarihçe hep okundu: sorular sorulmuş, yanıtlar sayılmış, biçimlerin bıraktığı kayıt olduğu gibi kabul edilmiştir. Sonraki kurs — İleri Git — aynı kaydı yeniden yazma araçlarını ele alır: etkileşimli yeniden temellendirme, toplu tarihçe dönüşümü, zorlayıcı itme disiplini ve kaybolan işlemeleri kurtaran referans günlüğü. Ayrım baştan konmalıdır: tarihçeyi okumak ile yeniden yazmak ayrı işlerdir. Okumak hiçbir şeyi değiştirmez; yeniden yazmak, bu kursta sayılan soruların yanıtlarını kalıcı olarak değiştirebilir. Bu kursun bıraktığı ölçü, oradaki her aracın bedelini hesaplamakta kullanılacak birimdir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.