Chapter Anatomi Commit memperlihatkan baris parent di dalam objek commit, dan chapter Commit Hash dan References memberi kita nama-nama untuk menyebut commit. Kini saatnya membedah relasi itu sendiri: bagaimana commit-commit saling menaut menjadi rantai, di mana rantai itu berawal, dan bagaimana sebuah commit merge menyimpan dua tautan sekaligus. Pemahaman relasi parent adalah bekal membaca notasi ~ dan ^ dengan yakin — bukan menghafal — sekaligus kunci mengerti mengapa urutan parent pada merge commit penting.

Repository Latihan: Satu Merge, Dua Sisi #

Repository latihan menumbuhkan branch fitur-ekspor berisi dua commit dari Siti, lalu menggabungkannya ke main yang juga sudah maju satu langkah — persis bentuk yang dipetakan chapter Graph History :

bash
mkdir latihan-parent && cd latihan-parent
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'Catatan proyek: pembagian tugas awal.\n' > catatan.txt
git add catatan.txt
git commit -m "Tambah catatan awal proyek"
printf 'Tugas:\n1. rancang ekspor\n2. uji tampilan\n' > tugas.txt
git add tugas.txt
git commit -m "Tambah daftar tugas proyek"
git switch -c fitur-ekspor
printf 'Ekspor hasil:\n- ke berkas teks\n' > ekspor.txt
git add ekspor.txt
git -c user.name="Siti Rahma" -c user.email="[email protected]" \
  commit -m "Tambah kerangka ekspor"
printf 'Ekspor hasil:\n- ke berkas teks\n- ke format csv\n' > ekspor.txt
git add ekspor.txt
git -c user.name="Siti Rahma" -c user.email="[email protected]" \
  commit -m "Lengkapi pilihan format ekspor"
git switch main
printf 'Rilis 0.1: fitur dasar selesai.\n' > rilis.txt
git add rilis.txt
git commit -m "Tambah catatan rilis 0.1"
git merge fitur-ekspor -m "Merge branch 'fitur-ekspor'"

Output yang Dihasilkan:

text
Merge made by the 'ort' strategy.
 ekspor.txt | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 ekspor.txt

Bentuk riwayat finalnya:

bash
git log --oneline --graph

Output yang Dihasilkan:

text
*   528963c Merge branch 'fitur-ekspor'
|\  
| * d63e126 Lengkapi pilihan format ekspor
| * 3e694c9 Tambah kerangka ekspor
* | 12d7908 Tambah catatan rilis 0.1
|/  
* 232a880 Tambah daftar tugas proyek
* aadc23b Tambah catatan awal proyek

Membuka Relasi Parent dengan cat-file #

Merge commit 528963c di puncak menyimpan rahasianya di objek mentah:

bash
git cat-file -p main

Output yang Dihasilkan:

text
tree e72e2256e544c93dbfb8fe6a76fd01c8c2088f19
parent 12d7908305806592b76d02fbc33e117b8ee74353
parent d63e126a5fa521a089f38cdd6b7ae2eaf89d5326
author Budi Santoso <[email protected]> 1791859200 +0700
committer Budi Santoso <[email protected]> 1791859200 +0700

Merge branch 'fitur-ekspor'

Dua baris parent — itulah seluruh definisi merge commit: commit biasa dengan satu tautan tambahan. Urutannya bukan kebetulan dan tidak bisa ditukar:

  1. Parent pertama (12d7908) — commit tempat kita berdiri saat git merge dijalankan. Kita berada di main pada 12d7908, jadi parent pertama adalah sisi main.
  2. Parent kedua (d63e126) — ujung dari branch yang dibawa masuk: posisi terakhir fitur-ekspor.

Urutan ini penting karena notasi ^ memilih parent berdasarkan nomornya: main^1 selalu menunjuk sisi main, main^2 selalu menunjuk sisi branch yang digabungkan. Kebalikan urutan akan membalik makna kedua notasi itu. Mekanisme lengkap perintah merge — fast-forward, strategi ort, konflik — dibahas di chapter git merge .

Root Commit: Parent yang Tidak Ada #

Rantai parent harus berawal di suatu tempat. Kita turuni sisi main tiga langkah — melewati 12d7908 dan 232a880 — sampai ke commit paling tua:

bash
git cat-file -p main~3

Output yang Dihasilkan:

text
tree a2c50859a47da4894ce25a6365c5de92f284bf86
author Budi Santoso <[email protected]> 1791856800 +0700
committer Budi Santoso <[email protected]> 1791856800 +0700

Tambah catatan awal proyek

Baris parent tidak ada — inilah root commit, satu-satunya commit tanpa induk, yang sudah kita temui di chapter Anatomi Commit . Objek ini sekaligus membuktikan kedua sisi merge bertemu: jalur parent pertama dari main melalui 12d7908 dan jalur parent kedua melalui d63e126 lalu 3e694c9 sama-sama turun ke 232a880 sebelum berakhir di root aadc23b.

Tilde dan Caret: Dua Cara Melangkah Mundur #

Notasi ~ dan ^ sama-sama melangkah mundur dari sebuah commit, dengan aturan yang berbeda: ~ mengikuti rantai parent pertama sebanyak langkah yang ditulis, sedangkan ^ memilih parent ke-n dari commit tepat di belakangnya. Lima penunjuk berikut dievaluasi sekaligus:

bash
git rev-parse main^ main^1 main^2 main~1 main~2

Output yang Dihasilkan:

text
12d7908305806592b76d02fbc33e117b8ee74353
12d7908305806592b76d02fbc33e117b8ee74353
d63e126a5fa521a089f38cdd6b7ae2eaf89d5326
12d7908305806592b76d02fbc33e117b8ee74353
232a88049f7c9f74115f37e7a8353cd1e983d651

Tiga baris bernilai 12d7908 — main^, main^1, dan main~1 memang sinonim untuk parent pertama. Baris main^2 memberi d63e126 dari sisi fitur, dan main~2 melompat dua langkah di sisi main hingga 232a880. Tanda caret dan tilde juga bisa dirangkai; dua bentuk berikut setara:

bash
git rev-parse HEAD^^ HEAD~2

Output yang Dihasilkan:

text
232a88049f7c9f74115f37e7a8353cd1e983d651
232a88049f7c9f74115f37e7a8353cd1e983d651

Pemetaan lengkapnya untuk repository kita dengan main berada di 528963c:

NotasiArtiMenunjuk
main^, main^1, main~1parent pertama12d7908
main^2parent kedua — hanya bermakna pada merge commitd63e126
main~2dua langkah mengikuti parent pertama232a880
main^^parent dari parent pertama — setara main~2232a880
main~3tiga langkah parent pertama sampai rootaadc23b

Perbedaan ~ dan ^ baru terasa nyata pada merge commit. Pada commit biasa, satu-satunya parent adalah parent pertama, sehingga HEAD~1 dan HEAD^ identik. Pada merge commit, ^ membuka pintu ke sisi kedua yang tak bisa dijangkau ~ berapa pun langkahnya. Dampak praktisnya terlihat langsung pada riwayat yang ditampilkan masing-masing penunjuk:

bash
git log --oneline main^2

Output yang Dihasilkan:

text
d63e126 Lengkapi pilihan format ekspor
3e694c9 Tambah kerangka ekspor
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyek
bash
git log --oneline main^

Output yang Dihasilkan:

text
12d7908 Tambah catatan rilis 0.1
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyek

main^2 menampilkan seluruh sejarah sisi fitur, main^ menampilkan sejarah sisi main. Satu kegunaan turunan yang sering dipakai tim: git log --oneline --first-parent hanya menelusuri rantai parent pertama — tampilan “garis utama” riwayat tanpa percabangan:

bash
git log --oneline --first-parent

Output yang Dihasilkan:

text
528963c Merge branch 'fitur-ekspor'
12d7908 Tambah catatan rilis 0.1
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyek

Cermin Struktur dalam Diagram #

Relasi parent pada repository kita tergambar utuh berikut — setiap panah mengalir dari commit ke induknya:

Diagram ini memindahkan graf terminal ke bentuk yang bisa ditempel di dokumentasi: merge commit 528963c memancarkan dua panah berlabel — panah parent 1 ke 12d7908 di garis utama, panah parent 2 ke d63e126 di sisi fitur — dan kedua jalur bertemu kembali di 232a880 sebelum berakhir di root aadc23b. Kosakata notasi lengkap untuk berjalan pada graf ini terdokumentasi di gitrevisions .

Struktur parent menjelaskan bentuk riwayat; kualitas isinya — commit atomik, pesan yang jelas, ukuran yang pas — menentukan apakah struktur itu enak ditelusuri. Bagian penutup section ini merangkum kebiasaan menjaga kualitas itu: Menjaga Riwayat Commit .