İçeriğe geç
academia.sh

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 add iki 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/index dosyası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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat