Chapter Struktur Repository memetakan .git sebagai database; kini kita masuk lebih dalam dan membuka laci-lacinya. Tujuannya bukan sekadar memuaskan rasa ingin tahu: memahami bahwa seluruh riwayat — setiap versi setiap berkas — hidup sebagai objek di objects/, ditunjuk oleh refs/, dengan posisi tercatat di HEAD, mengubah cara kita memandang keamanan dan pencadangan proyek. Setelah chapter ini, frasa “amankan repository” punya arti yang konkret: amankan satu folder.

.git Adalah Database #

Lima penghuni utama .git menjalankan peran masing-masing seperti pada tabel berikut:

PenghuniPeran
objects/Menyimpan seluruh isi riwayat: snapshot berkas, struktur folder, dan commit
refs/Menyimpan penunjuk posisi: branch dan tag
HEADMencatat posisi saat ini — branch mana yang sedang aktif
configMenyimpan pengaturan tingkat repositori
hooks/Menampung skrip yang berjalan otomatis pada peristiwa tertentu

Perhatikan pembagian kerjanya: objects/ memuat data, sementara refs/ dan HEAD memuat penunjuk menuju data itu. Git memisahkan isi dari alamatnya, seperti buku dipisahkan dari daftar isinya. Kita bedah keduanya dari repository latihan yang sama, dengan seluruh suntingan chapter sebelumnya sudah dipulihkan sehingga working tree bersih.

Direktori objects: Isi Riwayat #

Seluruh isi riwayat hidup di objects/ dalam bentuk objek bernama hash:

bash
ls .git/objects

Output yang Dihasilkan:

text
21
46
4c
56
5d
64
info
pack

Enam nama dua karakter di atas adalah folder — dua karakter pertama dari hash objek yang tersimpan di dalamnya, sedangkan info dan pack berisi pengaturan penyimpanan. Kita bisa memeriksa isi salah satu folder:

bash
ls .git/objects/46

Output yang Dihasilkan:

text
2b791829f26390eb7773946830b6fe6e64efa4

Nama berkas tersebut adalah 38 karakter sisanya: digabungkan dengan nama foldernya, terbentuk hash utuh 462b791... — identitas commit “Tambah glosarium istilah” yang sudah kita kenal. Pemecahan dua karakter pertama ke nama folder menjaga folder objects/ tetap rapi meski jumlah objek membengkak ke ratusan ribu. Nama berkas dan folder pada keluaran di atas milik latihan Course ini; hash di mesin pembaca pasti berbeda karena dihitung dari isi masing-masing.

Git menyediakan perintah resmi untuk membaca jenis objek dari hashnya:

bash
git cat-file -t HEAD

Output yang Dihasilkan:

text
commit

Opsi -t pada git cat-file melaporkan type atau jenis objek. Hash yang sama dengan hash pada refs/heads/main ternyata berjenis commit. Ulangi pada hash salah satu blob dari chapter Working Tree , hasilnya blob. Jumlah objek latihan ini bisa dihitung:

bash
git count-objects -v

Output yang Dihasilkan:

text
count: 6
size: 24
in-pack: 0
packs: 0
size-pack: 0
prune-packable: 0
garbage: 0
size-garbage: 0

Enam objek untuk dua commit: dua objek commit (satu per commit), dua objek tree (daftar isi folder pada tiap commit), dan dua objek blob (isi README.md dan glosarium.md). Nilai size: 24 berarti seluruh riwayat itu hanya menempati 24 kilobita. Bedah penuh model objek ini — bagaimana blob, tree, dan commit saling merujuk — dibahas pada section Internals dan Performa .

refs: Penunjuk yang Dapat Dibaca #

Bila objects/ adalah isinya, refs/ adalah daftar alamatnya:

bash
ls .git/refs

Output yang Dihasilkan:

text
heads
tags

Folder heads/ menampung branch dan tags/ menampung tag. Isi branch main kita:

bash
cat .git/refs/heads/main

Output yang Dihasilkan:

text
462b791829f26390eb7773946830b6fe6e64efa4

Sebuah branch di Git ternyata cuma setitik ini: berkas teks berisi satu hash. Tidak ada metadata rumit, tidak ada salinan berkas — branch hanyalah penunjuk yang mudah digeser ke commit lain. Ketika commit baru dibuat, Git menggeser isi berkas ini ke hash yang baru. Konsep sederhana ini menjadi fondasi seluruh materi branch pada section Branch dan Merging .

HEAD, config, dan hooks #

Berkas HEAD melengkapi refs/ dengan satu pertanyaan: penunjuk mana yang sedang aktif? Kita sudah membaca isinya pada chapter sebelumnya — ref: refs/heads/main — yang berarti kita sedang berdiri di branch main. Tanpa HEAD, Git tidak tahu working tree harus disalin dari commit mana dan commit baru harus diletakkan pada branch yang mana.

Berkas config menyimpan pengaturan tingkat repositori. Pada latihan kita isinya:

bash
cat .git/config

Output yang Dihasilkan:

text
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[user]
	name = Budi Santoso
	email = [email protected]

Bagian [core] ditulis Git sendiri saat repository dibuat, sedangkan bagian [user] berasal dari perintah git config user.name dan git config user.email yang kita jalankan lokal di repository ini — nilai lokal menimpa pengaturan global tanpa mengubahnya, sebagaimana dibahas pada section Instalasi dan Konfigurasi . Terakhir, folder hooks/ berisi templat skrip siap pakai — kita memanfaatkannya nanti untuk otomasi pada section Hooks dan Otomasi .

Konsekuensi Praktis: Amankan .git Berarti Amankan Riwayat #

Seluruh temuan di atas bermuara pada satu kesimpulan praktis: semua yang Git ingat tentang proyek kita berada di satu folder. Working tree hanya menyimpan versi terkini dari berkas-berkas; seluruh versi lainnya — ratusan commit, branch, dan tag — hanya hidup di .git. Konsekuensinya: menyalin atau mencadangkan folder .git sama dengan mencadangkan seluruh riwayat; dan menghapus folder .git berarti melepas proyek dari riwayatnya, meski berkas-berkas kerja tetap utuh di tempatnya.

Dengan database, penunjuk, dan konsekuensinya kini jelas, satu kebutuhan tersisa untuk bekerja percaya diri: cara membaca keadaan repository kapan pun — keadaan working tree, staging area, dan posisi branch dalam satu perintah. Lanjut ke git status .