Git Object Model & DAG — Git

Di balik perintah Git yang sehari-hari kamu pakai, ada model data yang elegan. Memahami ini membuat perintah Git masuk akal. Struktur folder .git/: .git/ HEAD ←

Di balik perintah Git yang sehari-hari kamu pakai, ada model data yang elegan. Memahami ini membuat perintah Git masuk akal.

Struktur folder .git/:

.git/
  HEAD             ← pointer ke branch aktif
  objects/         ← semua object tersimpan di sini
  refs/
    heads/         ← pointer branch lokal (main, fitur-x)
    remotes/       ← pointer branch remote (origin/main)
    tags/          ← pointer tag
  config           ← konfigurasi repo
  index            ← staging area

4 jenis object Git:

Object Isi Analogi
blob konten file (tanpa nama) isi buku
tree daftar nama file + permission + hash blob/tree daftar isi folder
commit pointer ke tree + parent + author + pesan snapshot berlabel
tag pointer ke commit + metadata (annotated tag) bookmark resmi

Setiap object diidentifikasi dengan SHA-1 hash 40 karakter dari isinya. Sama isi → sama hash → tidak ada duplikasi.

Commit bukanlah "diff" — commit adalah snapshot:

commit abc123
├── tree def456        (snapshot seluruh folder)
│   ├── blob 111 index.html
│   ├── blob 222 style.css
│   └── tree ghi789 src/
│       └── blob 333 app.js
├── parent xyz987      (commit sebelumnya)
└── pesan: "tambah fitur login"

Ref: branch adalah pointer, bukan "benda":

$ cat .git/refs/heads/main
abc123...              ← hanya 40 karakter SHA, itu saja!

Ketika kamu commit, Git membuat object commit baru dan memindahkan pointer refs/heads/main ke hash baru. Itu sebabnya branching di Git sangat murah.

HEAD:

$ cat .git/HEAD
ref: refs/heads/main   ← HEAD menunjuk ke branch

Saat git checkout abc123 (detached HEAD), isinya jadi SHA langsung, bukan ref.

Commit DAG (Directed Acyclic Graph):

Commit menunjuk ke parent-nya (bukan child). Merge commit punya 2+ parent. Tidak ada siklus — maka "Acyclic".

<style> .c { fill: #f59e0b; stroke: #92400e; stroke-width: 2; } .m { fill: #10b981; stroke: #064e3b; stroke-width: 2; } .sha { font: 700 10px ui-monospace, monospace; fill: #111827; text-anchor: middle; } .ref { font: 700 12px ui-sans-serif, system-ui; fill: #2563eb; text-anchor: middle; } .head { font: 700 12px ui-monospace, monospace; fill: #dc2626; text-anchor: middle; } .arr { stroke: #6b7280; stroke-width: 1.5; fill: none; marker-end: url(#ah); } </style> a1b2 c3d4 e5f6 g7h8 i9j0 k1l2 M main HEAD

Eksperimen: jalankan git cat-file -p <hash> untuk melihat isi object, dan git rev-parse HEAD untuk hash commit terakhir.

Yang akan kamu pelajari