Riwayat commit dan changelog menjawab dua pertanyaan yang berbeda: git log berbicara kepada pengembang (“apa yang dikerjakan”), changelog berbicara kepada pengguna (“apa yang berubah untuk saya”). Bagian ini menerjemahkan yang pertama menjadi yang kedua — menimbang draft dari log, merapikannya ke format Keep a Changelog, lalu meng-commit-nya. Di tengah jalan kita menabrak satu pelajaran yang jarang diajarkan: tag sudah terlanjur dibuat sebelum changelog ada, dan ada dua jalan keluar yang sama-sama jujur.

Menimbang Draft dari Log #

Bahan mentah changelog memang riwayat — dan karena v1.0.0 adalah rilis pertama, rentangnya adalah seluruh riwayat:

bash
git log --oneline

Output yang Dihasilkan:

text
37b21f8 chore: kunci versi 1.0.0
028e7df fix: perbaiki typo judul film
e908983 Merge branch 'fitur/pencarian'
d203019 feat: tambah pencarian judul
abc7deb Merge branch 'fitur/daftar-film'
36c8667 feat: tambah daftar film awal
1bce001 chore: rintis proyek katalog film

Tujuh baris itu bukan changelog — itu daftar belanja mentah. Setiap baris harus dipilah menurut Changelog : diterjemahkan bila dirasakan pengguna, dibuang bila urusan internal:

Baris logNasib di changelog
feat: tambah daftar film awalmasuk Added sebagai fitur daftar film
feat: tambah pencarian judulmasuk Added sebagai fitur pencarian
fix: perbaiki typo judul filmmasuk Fixed sebagai perbaikan judul
chore: rintis proyek katalog filmmenjadi baris “rilis perdana” — sekali saja
dua Merge branch ...dibuang — kegiatan penggabungan tidak dirasakan pengguna
chore: kunci versi 1.0.0dibuang — langkah internal alur rilis

Prefiks Conventional Commits mempercepat pemilahan ini: feat langsung ke Added, fix ke Fixed, sisanya ditimbang manual. Hasil pemilahan itulah yang ditulis ke CHANGELOG.md:

bash
printf '# Changelog\n\nSemua perubahan penting pada proyek ini didokumentasikan pada berkas ini.\nFormat mengikuti Keep a Changelog, dan penomoran versi mengikuti Semantic Versioning.\n\n## [Belum Dirilis]\n\n## [1.0.0] - 2026-10-13\n\n### Added\n- Rilis perdana aplikasi katalog film.\n- Daftar film favorit beserta tahun rilisnya.\n- Pencarian judul film berdasarkan kata kunci.\n\n### Fixed\n- Typo pada judul film Laskar Pelangi.\n\n[1.0.0]: https://github.com/budi-santoso/katalog-film/releases/tag/v1.0.0\n' > CHANGELOG.md
cat CHANGELOG.md

Output yang Dihasilkan (perintah cat CHANGELOG.md):

text
# Changelog

Semua perubahan penting pada proyek ini didokumentasikan pada berkas ini.
Format mengikuti Keep a Changelog, dan penomoran versi mengikuti Semantic Versioning.

## [Belum Dirilis]

## [1.0.0] - 2026-10-13

### Added
- Rilis perdana aplikasi katalog film.
- Daftar film favorit beserta tahun rilisnya.
- Pencarian judul film berdasarkan kata kunci.

### Fixed
- Typo pada judul film Laskar Pelangi.

[1.0.0]: https://github.com/budi-santoso/katalog-film/releases/tag/v1.0.0

Struktur mengikuti Keep a Changelog: judul section versi memakai kurung siku dan tanggal ISO, perubahan dikelompokkan di bawah label baku Added dan Fixed, dan section [Belum Dirilis] dibiarkan kosong sebagai parkiran perubahan setelah rilis ini. Baris terakhir adalah definisi tautan ke halaman rilis — nama budi-santoso/katalog-film adalah contoh fiktif yang diganti pemilik repository sungguhan. Berkas ini dicatat sebagai satu commit docs, bersama satu baris tambahan di README.md agar struktur proyek ikut akurat:

bash
printf '# Katalog Film\n\nAplikasi teks sederhana untuk mencatat film favorit — latihan\nrilis untuk Course Git Proyek 07.\n\n## Struktur\n\n- `src/app.txt` — isi aplikasi katalog film\n- `VERSION` — penanda versi proyek\n- `CHANGELOG.md` — riwayat perubahan per versi\n\n## Versi\n\nRilis saat ini: v1.0.0 — daftar film dan pencarian judul.\n' > README.md
git add CHANGELOG.md README.md
git commit -m "docs: tambah CHANGELOG untuk 1.0.0"

Output yang Dihasilkan (perintah git commit):

text
[main 4d9fc68] docs: tambah CHANGELOG untuk 1.0.0
 2 files changed, 19 insertions(+)
 create mode 100644 CHANGELOG.md

Tag yang Tertinggal #

Sekarang momen jujur proyek ini. Commit changelog barusan menggeser main — dan tag v1.0.0 dibuat sebelum commit itu ada. Ujilah dugaannya dengan membaca isi tag, pola git show <titik>:<berkas> dari Memulihkan File :

bash
git show v1.0.0:CHANGELOG.md

Output yang Dihasilkan:

text
fatal: path 'CHANGELOG.md' exists on disk, but not in 'v1.0.0'

Git menolak — berkas itu ada di working tree kita, tetapi tidak ada di pohon yang dibekukan tag. Rentangnya terbaca dari diff:

bash
git diff v1.0.0 main --stat

Output yang Dihasilkan:

text
 CHANGELOG.md | 18 ++++++++++++++++++
 README.md    |  1 +
 2 files changed, 19 insertions(+)

main unggul satu commit dari tag: changelog dan baris README.md belum masuk ke dalam v1.0.0. Rilis bernama v1.0.0 yang sudah terdorong ke pusat ternyata tidak membawa dokumentasinya sendiri.

Dua Jalan Keluar dan Tag Ulang #

Ada dua jalan yang sama-sama sah, dan keduanya perlu dipahami sebelum memilih:

JalanCaranyaKapan pantas
(a) pindahkan taggit tag -f -a v1.0.0 di commit changelog, lalu perbarui remotetag belum dikonsumsi siapa pun
(b) simpan untuk berikutnyav1.0.0 dibiarkan; changelog terbit bersama v1.0.1tag sudah ditarik rekan tim, CI, atau pengguna

Jalan (b) adalah aturan emas: tag yang sudah menjadi milik publik tidak digeser, sebab setiap salinan di luar sana akan berbeda dengan milik kita — pengguna yang sudah mengunduh v1.0.0 tidak boleh mendapat v1.0.0 yang isinya berganti diam-diam. Jalan (a) hanya sah selama tag masih privat. Keadaan kita saat ini: tag sudah terdorong ke katalog-film-pusat.git, tetapi pusat itu baru kita buat sendiri di Bagian 2 dan belum satu orang pun menariknya — belum ada clone selain milik kita, belum ada CI yang menariknya. Selama itu benar, memindahkan tag masih aman:

bash
git tag -f -a v1.0.0 -m "Katalog Film 1.0.0" -m "Fitur: daftar film, pencarian. Perbaikan: judul."

Output yang Dihasilkan:

text
Updated tag 'v1.0.0' (was 44b157a)

Git melaporkan tag diperbarui dan mencetak hash tag lama sebagai bukti — angka (was 44b157a) adalah objek tag sebelumnya yang barusan digantikan. Verifikasi keduanya seperti di Bagian 2:

bash
git rev-parse v1.0.0^{commit}
git rev-parse HEAD

Output yang Dihasilkan (perintah git rev-parse v1.0.0^{commit}):

text
4d9fc687a8e5f21807bfd3d06ee6b01aba8ebfae

Output yang Dihasilkan (perintah git rev-parse HEAD):

text
4d9fc687a8e5f21807bfd3d06ee6b01aba8ebfae

Hash kini jatuh pada commit changelog — tag dan main sejajar lagi. Kartu identitas tag berubah:

bash
git show v1.0.0 --stat

Output yang Dihasilkan:

text
tag v1.0.0
Tagger: Budi Santoso <[email protected]>
Date:   Tue Oct 13 10:25:00 2026 +0700

Katalog Film 1.0.0

Fitur: daftar film, pencarian. Perbaikan: judul.

commit 4d9fc687a8e5f21807bfd3d06ee6b01aba8ebfae
Author: Budi Santoso <[email protected]>
Date:   Tue Oct 13 10:20:00 2026 +0700

    docs: tambah CHANGELOG untuk 1.0.0

 CHANGELOG.md | 18 ++++++++++++++++++
 README.md    |  1 +
 2 files changed, 19 insertions(+)

Diffstat di bawah tag kini memuat CHANGELOG.md — rilis bernama v1.0.0 membawa changelog-nya sendiri. Titik terakhir dari jalan (a): remote masih memegang tag lama, jadi perbarui dengan paksaan yang jujur dinyatakan:

bash
git push -f origin v1.0.0

Output yang Dihasilkan:

text
To ../katalog-film-pusat.git
 + 44b157a...8c4b52a v1.0.0 -> v1.0.0 (forced update)

Pelajaran sebenarnya dari detik-detik ini bukan soal -f, melainkan soal urutan. Alur delapan langkah di Release Workflow meletakkan changelog di langkah 3 — sebelum tag di langkah 5. Kita mengerjakannya terbalik: tag dulu (Bagian 2), changelog kemudian, sehingga harus membayar satu putaran tag ulang plus push paksa. Changelog dulu, baru tag — begitulah urutan ideal, dan hari ini kita membuktikan mengapa.

Tag kini menunjuk commit yang benar dan pusat sudah mengikuti. Saatnya menuntaskan rilis secara penuh — mendorong segalanya, membungkus artefak, dan membuktikan hasilnya dari luar: Bagian 4: Menerbitkan Release .