Anatomi commit

Isi objek commit: tree, parent, author, committer, dan message, serta kaitannya dengan basis data objek.

Daftar isi

Sebuah commit bukan sekadar tombol simpan, melainkan objek data dengan struktur yang tetap. Topik ini membedah isi objek commit: tree yang menunjuk snapshot, parent yang merantai commit dengan pendahulunya, author dan committer beserta waktunya, dan pesan yang menjelaskannya. Struktur ini menjadi dasar untuk membaca riwayat, memahami percabangan, dan menafsirkan hasil penulisan ulang riwayat pada topik-topik berikutnya.

Isi objek commit#

Setiap commit menyimpan empat kelompok informasi. Informasi pertama adalah penunjuk ke sebuah tree, yaitu objek yang memuat struktur seluruh berkas proyek pada saat commit dibuat. Informasi kedua adalah penunjuk ke commit induk, kecuali untuk commit pertama yang tidak memiliki induk. Informasi ketiga adalah dua pasang identitas, yaitu author dan committer, masing-masing lengkap dengan waktunya. Informasi keempat adalah pesan commit.

Seluruh isi itu dapat dilihat melalui git show dengan format raw. Siapkan repository latihan berisi dua commit.

bash
# tanggal commit ditetapkan agar keluaran contoh dapat direproduksi secara persis
export GIT_AUTHOR_DATE="2026-11-01T09:00:00+07:00"
export GIT_COMMITTER_DATE="2026-11-01T09:00:00+07:00"
bash
rm -rf /tmp/lab-anatomi
mkdir /tmp/lab-anatomi
cd /tmp/lab-anatomi
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Bab satu.\n" > buku.txt
git add buku.txt
git commit -m "Mulai menulis buku"
printf "Bab satu.\nBab dua.\n" > buku.txt
git commit -am "Tambah bab dua"
text Keluaran
Initialized empty Git repository in /tmp/lab-anatomi/.git/
[main (root-commit) 27ecf4d] Mulai menulis buku
 1 file changed, 1 insertion(+)
 create mode 100644 buku.txt
[main 63abac8] Tambah bab dua
 1 file changed, 1 insertion(+)

Commit terakhir adalah tempat paling nyaman untuk membedah isinya.

bash
git show --no-patch --format=raw HEAD
text Keluaran
commit 63abac804f7307d564975e172c7d988369a4c32d
tree 4619784df2b9c524524b7f294077fa052ea48be8
parent 27ecf4d853d7591c014ef9f49e7496701581e711
author Budi <[email protected]> 1793498400 +0700
committer Budi <[email protected]> 1793498400 +0700

    Tambah bab dua

Baris tree menunjuk snapshot berkas buku.txt pada commit ini. Baris parent menunjuk commit sebelumnya, sehingga dua commit terhubung menjadi rantai. Baris author dan committer menyimpan identitas beserta waktu dalam bentuk angka detik dan pergeseran zona waktu, yaitu +0700 untuk Waktu Indonesia Barat pada contoh ini.

Commit pertama tidak memiliki induk karena tidak ada yang mendahuluinya.

bash
git show --no-patch --format=raw HEAD~1
text Keluaran
commit 27ecf4d853d7591c014ef9f49e7496701581e711
tree 4a6653b01650df13da2a7e9828ece767ee76e7c2
author Budi <[email protected]> 1793498400 +0700
committer Budi <[email protected]> 1793498400 +0700

    Mulai menulis buku

Baris parent memang tidak muncul pada commit pertama. Dua keluaran di atas juga menunjukkan bahwa hash commit berbeda meskipun penulis dan waktunya sama, karena hash dihitung atas seluruh isinya, termasuk tree dan parent yang berbeda.

Rantai parent dan dua induk pada merge#

Rantai parent inilah riwayat yang dilihat git log: setiap commit menunjuk persis satu induk, sehingga penelusuran mundur berjalan lurus. Satu-satunya pengecualian adalah commit merge, yaitu commit yang menggabungkan dua rantai dan karena itu memiliki dua parent sekaligus. Struktur beranak dua ini yang membuat riwayat proyek bersifat pohon, dan mekanikanya dibedah pada modul Penggabungan.

Dua commit yang terhubung melalui penunjuk parentcommit pertama 4f2a9c1tree: 3d6b8c4parent: (tidak ada)pesan: Mulai menulis bukucommit kedua 8d3b5e2tree: 9c41a2eparent: 4f2a9c1pesan: Tambah bab duaparent
Dua commit yang terhubung melalui penunjuk parent

Author, committer, dan waktunya#

Author adalah pembuat perubahan, sedangkan committer adalah pihak yang memasukkan commit ke riwayat. Pada pekerjaan biasa keduanya sama, tetapi keduanya berbeda ketika sebuah commit dipindahkan, misalnya melalui rebase atau cherry-pick: nama author dipertahankan agar kredit perubahan tetap milik pembuatnya, sedangkan committer menjadi orang yang melakukan pemindahan. Dua waktu yang menyertainya mengikuti pembagian yang sama, yaitu waktu pembuatan perubahan dan waktu pemasukan ke riwayat.

Pemisahan ini menjelaskan perilaku yang terlihat aneh bagi pemula: setelah rebase, tanggal author tetap lama padahal commit baru saja dibuat ulang. Keluaran git log secara default menampilkan waktu author, dan opsi --format=fuller menampilkan keduanya sekaligus.

Hash sebagai alamat identitas#

Hash commit dihitung atas seluruh isi objeknya, termasuk tree, parent, identitas, waktu, dan pesan. Akibatnya, mengubah satu karakter pada pesan pun menghasilkan hash yang berbeda, dan dua commit dengan hash yang sama dijamin berisi data yang identik. Hash yang panjang di format=raw dan hash pendek di keluaran log --oneline merujuk objek yang sama, karena Git menerima awalan hash selama belum ambigu pada repository tersebut. Sifat inilah yang membuat commit dapat dirujuk dengan aman dari tempat mana pun, dan yang membuat penulisan ulang riwayat selalu menghasilkan hash baru.

Ringkasan#

  • Objek commit menyimpan penunjuk tree, penunjuk parent, pasangan author dan committer beserta waktunya, serta pesan.
  • Riwayat linear terbentuk dari parent tunggal pada setiap commit, sedangkan commit merge memiliki dua parent.
  • Author dan committer dipisahkan agar kredit tetap milik pembuat perubahan ketika commit dipindahkan.
  • Hash commit dihitung atas seluruh isinya, sehingga hash yang sama menjamin isi yang sama dan setiap perubahan menghasilkan hash baru.

Referensi#