Chapter sebelumnya ditutup dengan satu tanda: saat eksperimen mulai mengancam versi tayang, pola main-only tidak lagi cukup. Tanda itu kini dibayar tuntas lewat satu fitur nyata dari awal sampai akhir: pencarian artikel pada situs web kecil. Fitur ini khas: melebihi satu hari kerja, menyentuh beberapa berkas, dan harus tetap terbaca sebagai satu unit di riwayat. Kerangka teorinya sudah dibahas di Feature Branch Workflow ; chapter ini menjalankan semuanya sendirian: branch, commit logis, rebase, review mandiri, merge --no-ff, sampai tag.

Siklus Satu Fitur #

Alur lengkapnya satu lingkaran pendek yang ditarikan setiap fitur:

Tiga hal membedakan siklus ini dari sekadar “punya branch”: commit dipecah logis sejak awal, sinkron ke main dilakukan sebelum menyatu, dan merge memakai --no-ff supaya batas fitur terlihat sebagai gelembung di graf.

Sesi: Branch dan Tiga Commit Logis #

Panggungnya situs artikel mini yang sudah berjalan di main:

bash
mkdir situs-artikel && cd situs-artikel
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Majalah Rasa\n\n- [Rendang padang](rendang.md)\n' > beranda.md
printf '# Rendang Padang\n\nResep rendang sapi empuk.\n' > rendang.md
git add .
git commit -m "Buat kerangka situs artikel"

Output yang Dihasilkan (perintah terakhir):

text
[main (root-commit) f3bed7f] Buat kerangka situs artikel
 2 files changed, 6 insertions(+)
 create mode 100644 beranda.md
 create mode 100644 rendang.md

Fitur pencarian lahir di branch sendiri, lalu tumbuh lewat tiga commit yang masing-masing satu satuan logis — kerangka, implementasi, pengujian:

bash
git switch -c fitur/pencarian

Output yang Dihasilkan:

text
Switched to a new branch 'fitur/pencarian'
bash
printf '# Pencarian\n\n<form action="pencarian.md">\n  <input type="text" name="q">\n</form>\n' > pencarian.md
git add pencarian.md
git commit -m "Rangka halaman hasil pencarian"
printf 'function cari(kunci, daftar) {\n  return daftar.filter(function (judul) {\n    return judul.includes(kunci);\n  });\n}\n' > cari.js
printf '\n<script src="cari.js"></script>\n' >> pencarian.md
git add cari.js pencarian.md
git commit -m "Implementasi pencarian judul artikel"
printf '# Uji Pencarian\n\n| kunci | hasil |\n| --- | --- |\n| rendang | 1 artikel |\n| sate | 0 artikel |\n' > uji-pencarian.md
git add uji-pencarian.md
git commit -m "Uji pencarian kata kunci dasar"
git log --oneline main..fitur/pencarian

Output yang Dihasilkan (perintah terakhir):

text
fc70c17 Uji pencarian kata kunci dasar
c143bc2 Implementasi pencarian judul artikel
09a4196 Rangka halaman hasil pencarian

Rentang main..fitur/pencarian menghitung apa yang dimiliki branch dan tidak dimiliki main — tiga commit, tepat tiga satuan kerja. Pemecahan ini bukan estetika: git bisect dan pembaca riwayat kelak berterima kasih karena satu commit menjelaskan satu langkah.

main Bergerak: Sinkron Sebelum Menyatu #

Sementara fitur dikerjakan, kehidupan di main berlanjut — artikel baru masuk lewat jalur singkat:

bash
git switch main
printf '# Majalah Rasa\n\n- [Rendang padang](rendang.md)\n- [Sate ayam](sate.md)\n' > beranda.md
printf '# Sate Ayam\n\nResep sate ayam madura.\n' > sate.md
git add beranda.md sate.md
git commit -m "Tambah artikel sate ayam"

Kembali ke branch fitur, ketinggalannya terukur persis — kebiasaan dari Menjaga Branch Tetap Sinkron :

bash
git switch fitur/pencarian
git log --oneline fitur/pencarian..main
git rebase main

Output yang Dihasilkan (dua perintah pertama):

text
Switched to branch 'fitur/pencarian'
text
1ded381 Tambah artikel sate ayam

Output yang Dihasilkan (git rebase main):

text
Successfully rebased and updated refs/heads/fitur/pencarian.

Satu commit di main belum tergabung ke branch — selisih kecil hari ini, jurang bila dibiarkan seminggu. Rebase memindahkan ketiga commit fitur ke atas 1ded381. Perhatikan efek sampingnya di graf akhir: hash ketiga commit berubah (misalnya fc70c17 menjadi 689cbe4) karena rebase menyalin ulang commit — perilaku yang membuatnya tabu untuk branch bersama yang sudah dipush.

Review Mandiri, Merge, dan Tag #

Sebelum menyatu, satu ritual yang sering dilewati: menimbang sendiri seluruh diff:

bash
git diff --stat main...fitur/pencarian

Output yang Dihasilkan:

text
 cari.js          | 5 +++++
 pencarian.md     | 7 +++++++
 uji-pencarian.md | 6 ++++++
 3 files changed, 18 insertions(+)

Tiga berkas, 18 baris — ukuran sehat untuk satu fitur. Diff tiga-titik (main...fitur) membandingkan branch terhadap titik percabangan, bukan main terkini, sehingga perubahan lain tidak ikut terhitung. Penyatuan memakai --no-ff dengan pesan yang menyebut fitur secara eksplisit:

bash
git switch main
git merge --no-ff fitur/pencarian -m "Gabungkan fitur pencarian artikel"
git branch -d fitur/pencarian
git tag -a v1.1.0 -m "Rilis pencarian artikel"

Output yang Dihasilkan (git merge):

text
Merge made by the 'ort' strategy.
 cari.js          | 5 +++++
 pencarian.md     | 7 +++++++
 uji-pencarian.md | 6 ++++++
 3 files changed, 18 insertions(+)
 create mode 100644 cari.js
 create mode 100644 pencarian.md
 create mode 100644 uji-pencarian.md

Output yang Dihasilkan (git branch -d):

text
Deleted branch fitur/pencarian (was 689cbe4).

Riwayat akhir memperlihatkan fitur sebagai satu gelembung utuh — mengapa --no-ff lebih informatif daripada maju cepat dibedah di Fast-Forward Merge :

bash
git log --oneline --graph --decorate

Output yang Dihasilkan:

text
*   43d5271 (HEAD -> main, tag: v1.1.0) Gabungkan fitur pencarian artikel
|\  
| * 689cbe4 Uji pencarian kata kunci dasar
| * 2b87464 Implementasi pencarian judul artikel
| * dff7795 Rangka halaman hasil pencarian
|/  
* 1ded381 Tambah artikel sate ayam
* f3bed7f Buat kerangka situs artikel

Hash di mesin pembaca berbeda, komposisinya tidak: tiga commit fitur terkurung gelembung merge, v1.1.0 menandai puncaknya, dan tag minor menaikkan angka kedua karena fitur baru yang mundur-kompatibel — penalaran SemVer dari Semantic Versioning . Jalur pada keluaran menyesuaikan lokasi direktori.

Pola Pesan Commit untuk Sebuah Fitur #

Tiga pesan di atas mengikuti satu pola yang bisa diulang untuk fitur apa pun:

TahapContoh pesanSatuan logisnya
KerangkaRangka halaman hasil pencarianstruktur berkas kosong, belum ada perilaku
ImplementasiImplementasi pencarian judul artikelperilaku inti bekerja
PengujianUji pencarian kata kunci dasarbukti perilaku sesuai harapan

Kata kerja perintah, subjek jelas. Nama fitur tidak perlu diulang tiap pesan — branch dan pesan merge sudah menjadi konteksnya. Opsi merge yang dipakai di sepanjang siklus terdokumentasi di dokumentasi git merge .

Ringkasan Langkah, Perintah, Alasan #

LangkahPerintahAlasan
1. Branch dari maingit switch -c fitur/pencarianisolasi tanpa merusak jalur tayang
2. Commit logisgit add …, git commit -m "…"riwayat terbaca per langkah fitur
3. Ukur ketinggalangit log fitur/pencarian..maintahu kapan waktunya sinkron
4. Sinkrongit rebase mainkonflik kecil dipecahkan di branch, bukan saat merge
5. Review mandirigit diff --stat main...fitur/pencarianmenimbang total perubahan sebelum menyatu
6. Mergegit merge --no-ff fitur/pencarian -m "…"batas fitur terlihat di graf
7. Rapikangit branch -d fitur/pencarianbranch berumur pendek by design
8. Tandaigit tag -a v1.1.0 -m "…"fitur jadi milestone bernomor

Siklus ini tenang karena memang diniatkan begitu: dikerjakan sendirian, tanpa review orang lain, tanpa kejaran waktu — dan tanpa darurat di peta. Produksi jarang berjanji demikian: bug bisa muncul tepat setelah rilis, dan menunggu siklus fitur normal justru salah. Workflow hotfix, chapter berikutnya, adalah jalur darurat yang tetap tertib.