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
:
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:
Merge made by the 'ort' strategy.
ekspor.txt | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 ekspor.txtBentuk riwayat finalnya:
git log --oneline --graphOutput yang Dihasilkan:
* 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 proyekMembuka Relasi Parent dengan cat-file #
Merge commit 528963c di puncak menyimpan rahasianya di objek mentah:
git cat-file -p mainOutput yang Dihasilkan:
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:
- Parent pertama (
12d7908) — commit tempat kita berdiri saatgit mergedijalankan. Kita berada dimainpada12d7908, jadi parent pertama adalah sisimain. - Parent kedua (
d63e126) — ujung dari branch yang dibawa masuk: posisi terakhirfitur-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:
git cat-file -p main~3Output yang Dihasilkan:
tree a2c50859a47da4894ce25a6365c5de92f284bf86
author Budi Santoso <[email protected]> 1791856800 +0700
committer Budi Santoso <[email protected]> 1791856800 +0700
Tambah catatan awal proyekBaris 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:
git rev-parse main^ main^1 main^2 main~1 main~2Output yang Dihasilkan:
12d7908305806592b76d02fbc33e117b8ee74353
12d7908305806592b76d02fbc33e117b8ee74353
d63e126a5fa521a089f38cdd6b7ae2eaf89d5326
12d7908305806592b76d02fbc33e117b8ee74353
232a88049f7c9f74115f37e7a8353cd1e983d651Tiga 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:
git rev-parse HEAD^^ HEAD~2Output yang Dihasilkan:
232a88049f7c9f74115f37e7a8353cd1e983d651
232a88049f7c9f74115f37e7a8353cd1e983d651Pemetaan lengkapnya untuk repository kita dengan main berada di 528963c:
| Notasi | Arti | Menunjuk |
|---|---|---|
main^, main^1, main~1 | parent pertama | 12d7908 |
main^2 | parent kedua — hanya bermakna pada merge commit | d63e126 |
main~2 | dua langkah mengikuti parent pertama | 232a880 |
main^^ | parent dari parent pertama — setara main~2 | 232a880 |
main~3 | tiga langkah parent pertama sampai root | aadc23b |
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:
git log --oneline main^2Output yang Dihasilkan:
d63e126 Lengkapi pilihan format ekspor
3e694c9 Tambah kerangka ekspor
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyekgit log --oneline main^Output yang Dihasilkan:
12d7908 Tambah catatan rilis 0.1
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyekmain^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:
git log --oneline --first-parentOutput yang Dihasilkan:
528963c Merge branch 'fitur-ekspor'
12d7908 Tambah catatan rilis 0.1
232a880 Tambah daftar tugas proyek
aadc23b Tambah catatan awal proyekCermin 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 .