Ders 11 / 15
İşlemeyi Değiştirme
Son işlemenin mesajının ya da içeriğinin düzeltilmesi; işlemenin değiştirilemez olması nedeniyle yeni nesne üretilmesi, başvuru günlüğü ve paylaşılmış tarihçenin sınırı.
İçindekiler
Önceki ders henüz işlenmemiş değişiklikleri geri aldı. Bu ders bir adım ileri gider: yazılmış bir işlemede eksik ya da hata varsa ne yapılacağını ele alır. En sık karşılaşılan iki durum, mesajın yanlış yazılması ve bir dosyanın işlemeye alınmayı unutulmasıdır.
Değiştirme Aslında Değiştirmez
İşleme nesnesi değiştirilemez. Kimliği, içeriğinin karma değeridir; içerik değişirse kimlik de değişir ve ortaya başka bir nesne çıkar. Bu nedenle “işlemeyi değiştirme” adı verilen işlem, var olan nesneyi düzenlemez: aynı öncüle bağlanan yeni bir işleme oluşturur ve dalın ucunu o yeni işlemeye taşır. Eski işleme nesne veritabanında kalır ama hiçbir başvurudan erişilemez hâle gelir.
Ayrım pratikte önemlidir: geçmişi düzeltmek, geçmişi yeniden yazmaktır.
Mesajı Düzeltmek
Kullanım bölümü README.md dosyasına eklenir ve işlenir; ancak mesajda iki yazım hatası
vardır:
git commit -m "READMEye kullanm bölümü ekle"
[main c190fa9] READMEye kullanm bölümü ekle 1 file changed, 4 insertions(+)
git commit --amend -m "README'ye kullanım bölümü ekle"
[main d847955] README'ye kullanım bölümü ekle Date: Fri Mar 8 11:30:00 2024 +0300 1 file changed, 4 insertions(+)
Kimlik c190fa9 iken d847955 oldu. İçerikte tek bir bayt bile değişmedi; değişen yalnızca
mesajdı ve mesaj da kimlik hesabına giriyordu.
Çıktıdaki Date: satırı, işlemenin yazar tarihinin korunduğunu bildirmek için yazılır.
Değişen şeyin gerçekten yalnızca mesaj olduğu, ağaç kimlikleri karşılaştırılarak sınanabilir:
git log -1 --format='%h %T' c190fa9 git log -1 --format='%h %T' d847955
c190fa9 4e359f7361da5c8654dce5682f26e5a79e43f5ca d847955 4e359f7361da5c8654dce5682f26e5a79e43f5ca
İki işleme aynı ağacı gösteriyor. Proje içeriği bayt düzeyinde özdeş, işleme kimlikleri farklı: kimliğin içerik dışında üstveriyi de kapsadığının doğrudan kanıtı budur. Nesne veritabanında yeni yazılan tek şey ikinci işleme nesnesidir; blob ve ağaç nesneleri paylaşılmıştır.
Yazar ve İşleyen
İşleme nesnesindeki iki tarih alanının ayrı olmasının nedeni burada görünür:
git log -1 --format='yazar : %an %ad%nişleyen : %cn %cd' --date=iso
yazar : Deniz Kaya 2024-03-08 11:30:00 +0300 işleyen : Deniz Kaya 2024-03-08 11:33:00 +0300
Yazar (author), değişikliği yazan kişi ve o değişikliğin ilk oluşturulma zamanıdır. İşleyen (committer), işlemeyi nesne veritabanına koyan kişi ve o kaydın zamanıdır. Değiştirme işlemi yazar alanını korur, işleyen alanını günceller. İki alanın ayrı tutulması, bir katkının başka biri tarafından tarihçeye yerleştirildiği durumlarda kaynağın kaybolmamasını sağlar.
Unutulan Bir Değişikliği Eklemek
README.md dosyasında çıkış kodunu anlatan satır yazılmadan işlenmişti. Eksik satır eklenir,
hazırlık alanına alınır ve mesaj korunarak işlemeye katılır:
git add README.md git commit --amend --no-edit
[main 18600c5] README'ye kullanım bölümü ekle Date: Fri Mar 8 11:30:00 2024 +0300 1 file changed, 6 insertions(+)
--no-edit, düzenleyiciyi açmadan var olan mesajı kullanır. Satır sayısı dörtten altıya
çıktı: hazırlık alanındaki içerik, yeni işlemenin ağacını oluşturdu.
Tarihçede tek bir işleme görünüyor:
git log --oneline -n 3
18600c5 README'ye kullanım bölümü ekle bfe57d3 Öbek ve dizi terimlerini ekle cb8f7ee Yerel notları izlemeden çıkar
Üç ayrı işleme nesnesi yazıldı — c190fa9, d847955, 18600c5 — ama tarihçede yalnızca
sonuncusu duruyor. İlk ikisi erişilemez hâle geldi.
Değiştirmenin Kapsamı
--amend, yeni işlemenin ağacını hazırlık alanının o anki durumundan üretir. Bu, kolaylık
olduğu kadar bir tuzaktır: hazırlık alanına başka bir iş için alınmış dosyalar varsa, onlar da
değiştirilen işlemeye girer ve tarihçede yanlış yere kaydedilmiş olurlar.
Yalnızca mesajı düzeltmek istendiğinde hazırlık alanının son işlemeyle aynı olması gerekir. Sınama tek komuttur:
git status --short
Çıktının birinci sütununda hiçbir işaret bulunmamalıdır. Bulunuyorsa, o girdiler değiştirme işleminin kapsamına girecektir.
Aynı mekanizma yazar alanı için de geçerlidir. --author seçeneği yeni işlemenin yazarını
belirler; yapılandırmadaki kimlik yanlışken yazılmış bir işlemenin düzeltilmesi bu yolla
yapılır. İşleyen alanı yine yapılandırmadan alınır, dolayısıyla iki alan farklılaşır — bu,
alanların ayrı tutulmasının beklenen sonucudur.
Eski İşlemelere Ne Oldu
Erişilemez olmak yok olmak değildir:
git cat-file -t c190fa9
commit
Nesne yerinde. Ona ulaşmanın yolu başvuru günlüğüdür (reflog): HEAD ve dal uçlarının
geçmişte hangi değerleri aldığını kaydeden yerel bir günlük.
git reflog -n 3
18600c5 HEAD@{0}: commit (amend): README'ye kullanım bölümü ekle
d847955 HEAD@{1}: commit (amend): README'ye kullanım bölümü ekle
c190fa9 HEAD@{2}: commit: READMEye kullanm bölümü ekle
HEAD@{n} gösterimi, HEAD başvurusunun n adım önceki değerini adlandırır. Günlük yereldir
ve paylaşılmaz; deponun bir kopyasında yapılan değiştirme, başka bir kopyanın günlüğünde
görünmez.
Erişilemez nesneler süresiz kalmaz. Depo bakımı sırasında çalışan çöp toplama (garbage collection), hiçbir başvurudan ve başvuru günlüğünden erişilemeyen nesneleri siler. Varsayılan bekleme süresi yeterince uzundur; ancak “erişilemez nesne kalıcıdır” varsayımıyla çalışmak doğru değildir. Kurtarma penceresi sınırlıdır.
Kaybolan İşlemeyi Geri Getirmek
Başvuru günlüğü yalnızca bir kayıt değil, bir kurtarma aracıdır. Yanlışlıkla değiştirilen bir işlemeye yeniden erişilebilir hâle getirmenin yolu, ona bir ad vermektir:
git branch kurtarma HEAD@{2}
git log --oneline -n 2 kurtarma
c190fa9 READMEye kullanm bölümü ekle bfe57d3 Öbek ve dizi terimlerini ekle
Komut sessizce çalışır ve kurtarma adlı bir başvuru oluşturur. Nesne artık bir addan
erişilebilir olduğu için çöp toplamanın kapsamı dışına çıkar; içerik incelenip gerekeni
alındıktan sonra bu ad silinebilir.
Aynı işlem bir kimlikle de yapılabilir: başvuru günlüğündeki c190fa9 doğrudan yazılabilir.
HEAD@{n} gösterimi tercih edilir, çünkü hangi adımın geri alınacağı kimlikten değil
sıradan okunur.
Buradaki genel kural şudur: bir nesneye erişilebilen tek bir ad kalması, onu korumaya yeter. Değiştirme ve sonraki derste görülecek sıfırlama gibi işlemler nesneleri silmez; yalnızca onlara giden adları taşır.
Değiştirmenin Sınırı
Değiştirme, yalnızca son işlemeye uygulanır ve yalnızca paylaşılmamış işlemelerde güvenlidir.
İkinci koşulun nedeni, kimliğin öncül zincirini kapsamasıdır. Bir işleme değiştirildiğinde kimliği değişir; ondan sonraki her işlemenin öncül alanı da değişmek zorunda kalır ve kimlikleri değişir. Tarihçe, değiştirilen noktadan sonra bütünüyle yeni nesnelerden oluşur.
Bu tarihçeyi daha önce almış bir kopya, kendi elindeki eski zinciri tutmaya devam eder. Sonuçta iki kopyada aynı değişiklikleri içeren ama farklı kimlikler taşıyan iki ayrı zincir bulunur; bunlar birleştirilmek istendiğinde her işleme iki kez görünür. İşbirliği içinde çalışan bir depoda bu, kaçınılması gereken bir durumdur.
Kural sadedir: bir işleme paylaşıldıysa değiştirilmez. Onun yerine, etkisini tersine çeviren yeni bir işleme yazılır — sonraki dersin konusu olan devirme.
Değiştirme, yalnızca son işlemeyle sınırlı olduğu için de dar bir araçtır. Daha eski bir işlemeyi düzeltmek gerektiğinde tarihçenin o noktadan itibaren yeniden yazılması gerekir; bu işlemler İleri Git kursunda ele alınacaktır.
Özet
- İşleme nesnesi değiştirilemez; değiştirme işlemi aynı öncüle bağlanan yeni bir işleme oluşturur ve dal ucunu ona taşır.
- Kimlik mesajı da kapsadığı için yalnızca mesajın düzeltilmesi bile yeni bir kimlik üretir.
- Yazar alanı korunur, işleyen alanı güncellenir; iki alanın ayrılması katkının kaynağını korur.
- Eski işlemeler erişilemez hâle gelir ama silinmez; başvuru günlüğü onlara ulaşmayı sağlar. Çöp toplama, erişilemez nesneleri belirli bir süre sonra siler.
- Değiştirme yalnızca son işlemeye ve yalnızca paylaşılmamış tarihçeye uygulanır.
Sonraki Adım
Değiştirme, son işlemeyi hedefliyor ve dal ucunu yeni bir nesneye taşıyordu. Dal ucunu daha geriye taşımak, yani birden çok işlemeyi tarihçeden düşürmek de mümkündür — ve bu işlemin üç farklı kipi vardır. Sonraki ders, bu kiplerin çalışma dizini ile hazırlık alanına ne yaptığını tek tek gösterecek.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.