Ders 04 / 15
Çalışma Dizini ve Hazırlık Alanı
Üç bölgeli modelin tanımı, `git add` komutunun nesne veritabanına ve hazırlık alanı dosyasına yaptığı iki ayrı yazma, blob nesnesi ve içerik adresli depolamanın gözle doğrulanması.
İçindekiler
Depo kuruldu ve boş. Bir dosya oluşturulduğunda ne olacağı sorusu açık kaldı: dosya doğrudan
tarihçeye mi girer? Yanıt hayırdır. Çalışma dizini ile tarihçe arasında üçüncü bir bölge
vardır ve bu bölge, git ile çalışmayı diğer birçok sürüm kontrol aracından ayıran temel
tasarım kararıdır.
Bu ders o bölgeyi tanımlar, disk üzerindeki karşılığını gösterir ve bir dosya içeriğinin nesne veritabanında nasıl adlandırıldığını hesap yaparak doğrular.
Üç Bölge
çalışma dizini hazırlık alanı nesne veritabanı
(dosyalar) (.git/index) (.git/objects)
│ │ │
│──── git add ─────────>│ │
│ │──── git commit ─────────>│
Çalışma dizini (working directory), dosyaların düzenlenebilir hâlidir — metin düzenleyicisinin gördüğü şey. Hazırlık alanı (staging area), bir sonraki işlemeye girecek içeriğin toplandığı ara bölgedir. Nesne veritabanı, kalıcı kayıtların tutulduğu yerdir.
Ara bölgenin varlığı bir kolaylık değil, bir yetkidir: işlemenin içeriği, çalışma dizininin o anki hâline mahkûm olmaktan çıkar. Çalışma dizininde beş dosya değişmişse bunlardan ikisi hazırlık alanına alınıp ayrı bir işleme olarak kaydedilebilir. Sonraki derste anlatılacak atomik işleme alışkanlığı bu yetkiye dayanır.
İlk Dosyalar
Örnek depoya iki dosya eklenir. Birincisi projeyi tanıtan README.md:
# Sözlük Bilgisayar bilimi terimlerinin Türkçe karşılıklarını tutan küçük bir liste. ## Biçim `terimler.txt` dosyasında her satır şu biçimdedir: turkce | english
İkincisi terim listesinin kendisi, terimler.txt:
yığıt | stack kuyruk | queue çizge | graph
Depo bu dosyalardan haberdar değildir:
git status
On branch main No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) README.md terimler.txt nothing added to commit but untracked files present (use "git add" to track)
İzlenmeyen (untracked) dosya, hazırlık alanında kaydı bulunmayan dosyadır. Depo onu görür ama izlemez; içeriği değişse bile bildirmez.
git add İki İş Yapar
git add README.md
git status --short
A README.md ?? terimler.txt
Kısa gösterimde her satırın başında iki sütun bulunur. Birinci sütun hazırlık alanı ile son
işleme arasındaki farkı, ikinci sütun çalışma dizini ile hazırlık alanı arasındaki farkı
gösterir. A “eklendi”, M “değiştirildi”, D “silindi”, ?? “izlenmiyor” anlamına gelir.
A birinci sütunda ve ikinci sütun boş olduğuna göre: dosya hazırlık alanına alınmış ve
çalışma dizinindeki hâliyle aynıdır.
Komut iki ayrı yazma yaptı. Birincisi nesne veritabanına:
find .git/objects -type f
.git/objects/49/daf9067744c72d7f5427d163f983c326ff37b5
Dosyanın içeriği, henüz hiçbir işleme yazılmamış olmasına rağmen kalıcı olarak saklandı. Bu nesne bir blob’dur: yalnızca bayt dizisi tutan, dosya adı ve izin bilgisi içermeyen nesne türü. Adı, içeriğinden hesaplanmıştır; dizin adı karma değerinin ilk iki karakteri, dosya adı kalanıdır.
İkinci yazma hazırlık alanınadır:
git ls-files -s
100644 49daf9067744c72d7f5427d163f983c326ff37b5 0 README.md
Bu satır hazırlık alanının bir girdisidir: dosya kipi, blob kimliği, aşama numarası ve yol.
Dosya kipi 100644 sıradan dosyayı, 100755 çalıştırılabilir dosyayı belirtir. Aşama
numarası birleştirme çakışmalarında kullanılır ve olağan durumda sıfırdır.
İkinci dosya da eklenir:
git add terimler.txt git ls-files -s
100644 49daf9067744c72d7f5427d163f983c326ff37b5 0 README.md 100644 9b9ef7052d54292add1ed75823a454c1fe66e3bb 0 terimler.txt
Hazırlığa Alma Biçimleri
Dosyaları tek tek yazmak dışında toplu biçimler de vardır ve kapsamları farklıdır:
| Yazım | Kapsam |
|---|---|
git add <yol> |
Verilen yol |
git add . |
Bulunulan dizin ve altı |
git add -A |
Deponun tamamı, bulunulan dizinden bağımsız |
git add -p |
Değişikliklerin parça parça seçilmesi |
İlk iki biçim arasındaki fark alt dizinlerde belirginleşir. Kök dizinde bir dosya silinmiş,
yeni adlı alt dizinde bir dosya oluşturulmuş olsun. Alt dizinden çalıştırılan komut silmeyi
kapsamaz:
cd yeni git add . git status --short
D ../terimler.txt A a.txt
Silme işareti ikinci sütunda kaldı: hazırlık alanına alınmadı. Kökten çalıştırılan -A biçimi
her ikisini de alır:
git add -A git status --short
D terimler.txt A yeni/a.txt
Dördüncü biçim, tek bir dosyadaki değişikliklerin bir bölümünü hazırlık alanına almayı sağlar: komut, farkın her parçasını sırayla sunar ve her biri için alınıp alınmayacağını sorar. Hazırlık alanının verdiği seçme yetkisi burada dosya düzeyinden satır düzeyine iner; bir dosyada birbirinden bağımsız iki düzeltme yapılmışsa bunlar ayrı işlemelere bölünebilir.
Hazırlık Alanı Bir Dosyadır
Hazırlık alanı soyut bir kavram değil, .git/index adlı ikili bir dosyadır. İngilizce
belgelerde index adıyla anılır. İçinde, izlenen her yol için bir girdi bulunur: yol adı,
kip, blob kimliği ve dosya sisteminden okunan bazı ön bellek alanları.
Bu son alanlar git status komutunun hızını belirler. Çalışma dizinindeki her dosyanın
içeriğini yeniden karma değerinden geçirmek yerine, dosyanın boyutu ve değişiklik zamanı
hazırlık alanındaki kayıtla karşılaştırılır; ikisi de aynıysa dosya değişmemiş sayılır.
Kayıt sayısı arttıkça bu ön belleğin değeri artar.
Hazırlık alanının tuttuğu şeyin düzenlenmiş bir dosya listesi olduğuna dikkat edin: hangi yolun hangi içeriğe bağlı olduğunu söyler. Bu yapı, bir sonraki derste anlatılacak ağaç nesnesinin doğrudan öncülüdür.
Kimlik Nereden Geliyor
Blob kimliği, dosya içeriğinin ham karma değeri değildir. Nesnenin önüne türünü ve uzunluğunu bildiren bir başlık eklenir, karma değeri bu bütün üzerinden hesaplanır. Başlığın biçimi şudur: nesne türü, bir boşluk, bayt cinsinden uzunluk ve bir sıfır baytı.
Bu hesap dışarıdan yapılabilir. Sekiz baytlık bir içerik ele alalım:
printf 'merhaba\n' | git hash-object --stdin
e995d8e1c89654fd0a6453c2da61fb6e9da262e6
Aynı değer, başlık elle eklenerek ve genel amaçlı bir karma aracıyla da elde edilir:
printf 'blob 8\0merhaba\n' | shasum
e995d8e1c89654fd0a6453c2da61fb6e9da262e6 -
İki değer aynıdır. shasum komutu SHA-1 özetini üretir; GNU araç kümesinde aynı iş sha1sum
ile yapılır.
Bu hesabın iki sonucu vardır. Birincisi, aynı içerik iki farklı adla saklansa bile tek bir nesne oluşturur; kimlik dosya adına değil içeriğe bağlıdır. İkincisi, nesnenin bir baytı değişirse kimliği tanınmaz biçimde değişir — Veri Yapıları kursunda tanımlanan çığ etkisi.
Nesnenin türü ve boyutu doğrudan sorulabilir:
git cat-file -t 49daf9067744c72d7f5427d163f983c326ff37b5 git cat-file -s 49daf9067744c72d7f5427d163f983c326ff37b5
blob 187
Bu kimlik README.md dosyasının o andaki içeriğine aittir; kendi deponuzda dosyayı harfi
harfine aynı yazmadığınız sürece farklı bir değer göreceksiniz. Kurs boyunca gösterilen bütün
nesne kimlikleri aynı kuralla üretilmiştir.
Özet
- Çalışma dizini düzenlenen dosyaları, hazırlık alanı bir sonraki işlemeye girecek içeriği, nesne veritabanı kalıcı kayıtları tutar.
git addiki iş yapar: içeriği blob olarak nesne veritabanına yazar ve yolu blob kimliğine bağlayan bir girdiyi hazırlık alanına koyar.- Hazırlık alanı
.git/indexdosyasıdır; yol, kip ve blob kimliğinden oluşan girdileri tutar. - Blob kimliği, tür ve uzunluk başlığı eklenmiş içeriğin karma değeridir; içerik aynıysa kimlik de aynıdır.
- Kısa durum gösteriminde birinci sütun hazırlık alanını, ikinci sütun çalışma dizinini anlatır.
Sonraki Adım
Hazırlık alanında iki girdi var ama tarihçe hâlâ boş; git log çalıştırılsa yanıt
alınamazdı. Sonraki ders hazırlık alanının içeriğini kalıcı bir kayda dönüştürecek, bu
sırada oluşan ağaç ve işleme nesnelerini açıp inceleyecek ve bir işlemenin ne zaman “tek bir
iş” sayıldığını tanımlayacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.