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:
git log --onelineOutput yang Dihasilkan:
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 filmTujuh baris itu bukan changelog — itu daftar belanja mentah. Setiap baris harus dipilah menurut Changelog : diterjemahkan bila dirasakan pengguna, dibuang bila urusan internal:
| Baris log | Nasib di changelog |
|---|---|
feat: tambah daftar film awal | masuk Added sebagai fitur daftar film |
feat: tambah pencarian judul | masuk Added sebagai fitur pencarian |
fix: perbaiki typo judul film | masuk Fixed sebagai perbaikan judul |
chore: rintis proyek katalog film | menjadi baris “rilis perdana” — sekali saja |
dua Merge branch ... | dibuang — kegiatan penggabungan tidak dirasakan pengguna |
chore: kunci versi 1.0.0 | dibuang — 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:
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.mdOutput yang Dihasilkan (perintah cat CHANGELOG.md):
# 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.0Struktur 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:
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):
[main 4d9fc68] docs: tambah CHANGELOG untuk 1.0.0
2 files changed, 19 insertions(+)
create mode 100644 CHANGELOG.mdTag 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
:
git show v1.0.0:CHANGELOG.mdOutput yang Dihasilkan:
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:
git diff v1.0.0 main --statOutput yang Dihasilkan:
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:
| Jalan | Caranya | Kapan pantas |
|---|---|---|
| (a) pindahkan tag | git tag -f -a v1.0.0 di commit changelog, lalu perbarui remote | tag belum dikonsumsi siapa pun |
| (b) simpan untuk berikutnya | v1.0.0 dibiarkan; changelog terbit bersama v1.0.1 | tag 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:
git tag -f -a v1.0.0 -m "Katalog Film 1.0.0" -m "Fitur: daftar film, pencarian. Perbaikan: judul."Output yang Dihasilkan:
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:
git rev-parse v1.0.0^{commit}
git rev-parse HEADOutput yang Dihasilkan (perintah git rev-parse v1.0.0^{commit}):
4d9fc687a8e5f21807bfd3d06ee6b01aba8ebfaeOutput yang Dihasilkan (perintah git rev-parse HEAD):
4d9fc687a8e5f21807bfd3d06ee6b01aba8ebfaeHash kini jatuh pada commit changelog — tag dan main sejajar lagi. Kartu identitas tag berubah:
git show v1.0.0 --statOutput yang Dihasilkan:
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:
git push -f origin v1.0.0Output yang Dihasilkan:
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 .