Ajie Logo Ajie.
Navigation

© 2026 Ajie Kusumadhany.

Back to Articles

Why Your Git Commits Are Probably a Mess Mengapa Git Commit Kamu Kemungkinan Berantakan

Ajie Ajie Kusumadhany
Jun 30, 2026 9 min read
Why Your Git Commits Are Probably a Mess Mengapa Git Commit Kamu Kemungkinan Berantakan

I once inherited a codebase where every single commit message was "updates". Not "Update user authentication", not "Fix login bug". Just "updates". Seven hundred commits. All identical.

If you've ever worked on a team project, you know this pain intimately.

The truth is, most developers treat Git commits like a necessary evil. Something to rush through so they can push their code and move on. But here's what they don't realize: bad commit messages compound over time, turning your version control system from a powerful debugging tool into archaeological guesswork.

The Real Cost of Lazy Commits

Let's say a critical bug surfaces in production. Your first instinct? Run git log and trace back through the history to find when the breaking change was introduced.

With professional commit conventions, this takes minutes. With "fix stuff" and "wip" messages, you're reading through actual code diffs for hours.

Time is money. Bad commits literally waste billable hours.

The Anatomy of a Professional Commit Message

Professional teams follow structured conventions. The most widely adopted is the Conventional Commits specification, but even simpler patterns work wonders if applied consistently.

Here's the basic anatomy:

Component Purpose Example
Type Categorizes the change feat, fix, docs, refactor
Scope What area is affected (auth), (api), (ui)
Subject Brief description add password reset endpoint
Body Detailed explanation Why this change was needed
Footer Metadata Issue references, breaking changes

A complete example looks like this:

feat(auth): add OAuth2 Google login integration

The type prefix immediately tells you what kind of change this is. No guessing. No reading code diffs.

Common Commit Types You Should Know

Different teams use different conventions, but these types are near-universal:

  • feat – A new feature for the user
  • fix – A bug fix
  • docs – Documentation changes only
  • style – Formatting, missing semicolons, whitespace
  • refactor – Code restructuring without changing behavior
  • perf – Performance improvements
  • test – Adding or updating tests
  • chore – Build process, dependencies, tooling
  • ci – CI/CD pipeline changes

Using these consistently transforms your Git log into a scannable changelog.

The 50/72 Rule

This is the golden standard for commit message formatting.

Keep your subject line under 50 characters. Keep body text wrapped at 72 characters per line.

Why? Because Git tools display commit messages in specific UI layouts. Overly long subjects get truncated in git log --oneline. Bodies that exceed 72 characters break terminal readability.

Short subjects force you to be precise. If you can't describe your change in 50 characters, your commit is probably doing too much.

Atomic Commits Change Everything

One commit should do one thing. Not five things. One.

This principle is called atomic commits, and it's non-negotiable for professional workflows.

Bad example: A commit that adds a new feature, fixes two unrelated bugs, and updates documentation.

Good example: Three separate commits, each addressing one logical change.

Why does this matter? Because atomic commits make cherry-picking possible. They make rollbacks surgical instead of catastrophic. They make code reviews focused instead of overwhelming.

When to Commit

Here's a controversial take: commit more often than you think you should.

Many developers batch changes into massive commits because they're worried about "cluttering" the history. But local commits are free. You can always squash them later before pushing.

The real workflow looks like this:

  • Make small, frequent local commits as you work
  • Use git rebase -i to clean up your branch before pushing
  • Push a clean, logical history to the remote

This gives you the safety of frequent saves with the professionalism of clean history.

The Power of Git Hooks

You can enforce commit message standards automatically using Git hooks.

A commit-msg hook validates your message format before allowing the commit. Tools like Husky and Commitlint make this trivial to set up.

Example: Block any commit that doesn't start with a valid type prefix.

This removes the human discipline factor. Your team literally cannot commit without following the convention.

Real World Example: A Week in Professional Commits

Let's compare two developers working on the same feature:

Developer A (Amateur):

  • "stuff"
  • "more changes"
  • "fix"
  • "final version"
  • "actually final"

Developer B (Professional):

  • "feat(api): add user registration endpoint"
  • "test(api): add integration tests for registration"
  • "fix(api): handle duplicate email validation"
  • "docs(api): document registration endpoint in OpenAPI spec"
  • "refactor(api): extract email validation to shared utility"

Six months later, when a registration bug appears, which history would you rather investigate?

Breaking Changes Deserve Special Attention

If your commit introduces a breaking change, that must be communicated explicitly.

The convention is to add BREAKING CHANGE: in the commit footer, or append an exclamation mark to the type:

feat(api)!: remove deprecated v1 endpoints

Automated changelog generators parse this to create clear upgrade guides. Without it, your breaking change is invisible until someone's code explodes.

Commit Messages as Documentation

Your commit body is where you explain the "why", not the "what".

The code shows what changed. The commit message explains why it was necessary, what alternatives were considered, and what impact it has.

Bad body: "Changed the caching strategy"

Good body: "Switched from memory cache to Redis to support horizontal scaling. Memory cache was causing inconsistent state across multiple server instances."

This context is gold when someone (often future you) needs to understand a decision made months ago.

Squashing vs. Preserving History

There's an ongoing debate: should you squash feature branches or preserve all commits?

The answer depends on your team's workflow:

Squash when: You want a clean linear history where each commit represents a complete, deployable feature.

Preserve when: You want full transparency into the development process, including intermediate steps and problem-solving iterations.

Neither is wrong. Just be consistent across your team.

Tools That Make This Easier

You don't have to memorize everything. Use tools:

  • Commitizen – Interactive CLI that prompts you for proper commit format
  • Commitlint – Validates commit messages against rules
  • Husky – Manages Git hooks easily
  • Conventional Changelog – Auto-generates changelogs from commits
  • Semantic Release – Automates versioning based on commit types

These tools transform commit conventions from a chore into an automated workflow.

Pro Tips for Mastering Git Commits

Use imperative mood: Write "add feature" not "added feature". This matches Git's own generated messages like "Merge branch".

Reference issues: Link commits to issue trackers with "Closes #123" or "Fixes #456". Many platforms auto-close issues when commits are merged.

Avoid generic messages: Ban words like "update", "change", "fix" without specific details.

Review before pushing: Run git log and read your commits as if you're seeing them for the first time. If they don't make sense, rewrite them.

Teach your team: Good commit conventions only work if everyone follows them. Make it part of your onboarding and code review process.

Key Takeaways

Your Git history is a form of technical documentation. It's a debugging tool. It's a communication channel across time.

Professional commit messages aren't about being pedantic. They're about respecting your future self and your teammates.

Start small. Pick a convention. Enforce it with tools. Watch your productivity compound as your codebase history becomes actually useful instead of archaeological noise.

The difference between a junior developer and a senior one often shows up in the Git log before it shows up in the code.

Saya pernah mewarisi sebuah codebase di mana setiap commit message adalah "updates". Bukan "Update user authentication", bukan "Fix login bug". Hanya "updates". Tujuh ratus commit. Semuanya identik.

Jika Anda pernah bekerja dalam proyek tim, Anda pasti merasakan sakit ini dengan intim.

Kenyataannya adalah, kebanyakan developer memperlakukan Git commit seperti sesuatu yang wajib tapi tidak penting. Sesuatu yang harus diselesaikan dengan cepat agar mereka bisa push kode dan melanjutkan pekerjaan. Tapi inilah yang tidak mereka sadari: commit message yang buruk menumpuk seiring waktu, mengubah sistem version control Anda dari alat debugging yang powerful menjadi tebak-tebakan arkeologi.

Biaya Sebenarnya dari Commit yang Asal-asalan

Katakanlah sebuah bug kritis muncul di production. Instink pertama Anda? Jalankan git log dan telusuri kembali riwayat untuk menemukan kapan perubahan yang merusak diperkenalkan.

Dengan konvensi commit profesional, ini memakan waktu beberapa menit. Dengan pesan "fix stuff" dan "wip", Anda akan membaca code diff yang sebenarnya selama berjam-jam.

Waktu adalah uang. Commit yang buruk secara harfiah membuang jam kerja yang bisa ditagih.

Anatomi Commit Message Profesional

Tim profesional mengikuti konvensi terstruktur. Yang paling banyak diadopsi adalah spesifikasi Conventional Commits, tetapi bahkan pola yang lebih sederhana bekerja dengan baik jika diterapkan secara konsisten.

Inilah anatomi dasarnya:

Komponen Tujuan Contoh
Type Mengkategorikan perubahan feat, fix, docs, refactor
Scope Area yang terpengaruh (auth), (api), (ui)
Subject Deskripsi singkat add password reset endpoint
Body Penjelasan detail Mengapa perubahan ini diperlukan
Footer Metadata Referensi issue, breaking changes

Contoh lengkap terlihat seperti ini:

feat(auth): add OAuth2 Google login integration

Prefiks type langsung memberi tahu Anda jenis perubahan apa ini. Tidak ada tebakan. Tidak perlu membaca code diff.

Tipe Commit Umum yang Harus Anda Ketahui

Tim yang berbeda menggunakan konvensi yang berbeda, tetapi tipe-tipe ini hampir universal:

  • feat – Fitur baru untuk pengguna
  • fix – Perbaikan bug
  • docs – Perubahan dokumentasi saja
  • style – Formatting, semicolon yang hilang, whitespace
  • refactor – Restrukturisasi kode tanpa mengubah perilaku
  • perf – Peningkatan performa
  • test – Menambah atau memperbarui test
  • chore – Proses build, dependensi, tooling
  • ci – Perubahan pipeline CI/CD

Menggunakan ini secara konsisten mengubah Git log Anda menjadi changelog yang bisa di-scan dengan mudah.

Aturan 50/72

Ini adalah standar emas untuk format commit message.

Jaga subject line Anda di bawah 50 karakter. Jaga teks body dibungkus pada 72 karakter per baris.

Mengapa? Karena alat Git menampilkan commit message dalam layout UI tertentu. Subject yang terlalu panjang akan terpotong di git log --oneline. Body yang melebihi 72 karakter merusak keterbacaan terminal.

Subject yang pendek memaksa Anda untuk presisi. Jika Anda tidak bisa menggambarkan perubahan Anda dalam 50 karakter, commit Anda mungkin melakukan terlalu banyak hal.

Atomic Commits Mengubah Segalanya

Satu commit harus melakukan satu hal. Bukan lima hal. Satu.

Prinsip ini disebut atomic commits, dan ini tidak dapat dinegosiasikan untuk workflow profesional.

Contoh buruk: Commit yang menambahkan fitur baru, memperbaiki dua bug yang tidak terkait, dan memperbarui dokumentasi.

Contoh baik: Tiga commit terpisah, masing-masing menangani satu perubahan logis.

Mengapa ini penting? Karena atomic commits membuat cherry-picking mungkin. Mereka membuat rollback menjadi bedah, bukan bencana. Mereka membuat code review menjadi fokus, bukan membingungkan.

Kapan Harus Commit

Inilah pendapat kontroversial: commit lebih sering daripada yang Anda pikirkan.

Banyak developer menggabungkan perubahan menjadi commit besar-besaran karena khawatir tentang "mengacaukan" history. Tetapi commit lokal itu gratis. Anda selalu bisa squash mereka nanti sebelum push.

Workflow sebenarnya terlihat seperti ini:

  • Buat commit lokal kecil dan sering saat Anda bekerja
  • Gunakan git rebase -i untuk membersihkan branch Anda sebelum push
  • Push history yang bersih dan logis ke remote

Ini memberi Anda keamanan save yang sering dengan profesionalisme history yang bersih.

Kekuatan Git Hooks

Anda bisa menegakkan standar commit message secara otomatis menggunakan Git hooks.

Hook commit-msg memvalidasi format pesan Anda sebelum mengizinkan commit. Tool seperti Husky dan Commitlint membuat ini sangat mudah untuk diatur.

Contoh: Blokir commit apa pun yang tidak dimulai dengan prefiks type yang valid.

Ini menghilangkan faktor disiplin manusia. Tim Anda secara harfiah tidak dapat commit tanpa mengikuti konvensi.

Contoh Dunia Nyata: Seminggu dalam Commit Profesional

Mari kita bandingkan dua developer yang bekerja pada fitur yang sama:

Developer A (Amatir):

  • "stuff"
  • "more changes"
  • "fix"
  • "final version"
  • "actually final"

Developer B (Profesional):

  • "feat(api): add user registration endpoint"
  • "test(api): add integration tests for registration"
  • "fix(api): handle duplicate email validation"
  • "docs(api): document registration endpoint in OpenAPI spec"
  • "refactor(api): extract email validation to shared utility"

Enam bulan kemudian, ketika bug registrasi muncul, history mana yang lebih Anda sukai untuk diselidiki?

Breaking Changes Membutuhkan Perhatian Khusus

Jika commit Anda memperkenalkan breaking change, itu harus dikomunikasikan secara eksplisit.

Konvensinya adalah menambahkan BREAKING CHANGE: di footer commit, atau menambahkan tanda seru ke type:

feat(api)!: remove deprecated v1 endpoints

Generator changelog otomatis mem-parse ini untuk membuat panduan upgrade yang jelas. Tanpanya, breaking change Anda tidak terlihat sampai kode seseorang meledak.

Commit Message sebagai Dokumentasi

Body commit Anda adalah tempat Anda menjelaskan "mengapa", bukan "apa".

Kode menunjukkan apa yang berubah. Commit message menjelaskan mengapa itu diperlukan, alternatif apa yang dipertimbangkan, dan dampak apa yang dimilikinya.

Body buruk: "Changed the caching strategy"

Body baik: "Switched from memory cache to Redis to support horizontal scaling. Memory cache was causing inconsistent state across multiple server instances."

Konteks ini sangat berharga ketika seseorang (sering kali diri Anda di masa depan) perlu memahami keputusan yang dibuat beberapa bulan yang lalu.

Squashing vs. Melestarikan History

Ada perdebatan yang sedang berlangsung: haruskah Anda squash feature branch atau melestarikan semua commit?

Jawabannya tergantung pada workflow tim Anda:

Squash ketika: Anda menginginkan history linear yang bersih di mana setiap commit mewakili fitur lengkap yang dapat di-deploy.

Preserve ketika: Anda menginginkan transparansi penuh ke dalam proses pengembangan, termasuk langkah-langkah perantara dan iterasi pemecahan masalah.

Tidak ada yang salah. Pastikan saja konsisten di seluruh tim Anda.

Tool yang Membuat Ini Lebih Mudah

Anda tidak perlu menghafal semuanya. Gunakan tool:

  • Commitizen – CLI interaktif yang meminta format commit yang benar
  • Commitlint – Memvalidasi commit message terhadap aturan
  • Husky – Mengelola Git hooks dengan mudah
  • Conventional Changelog – Menghasilkan changelog otomatis dari commit
  • Semantic Release – Mengotomatiskan versioning berdasarkan tipe commit

Tool-tool ini mengubah konvensi commit dari tugas menjadi workflow otomatis.

Tips Praktis untuk Menguasai Git Commits

Gunakan imperative mood: Tulis "add feature" bukan "added feature". Ini cocok dengan pesan yang dihasilkan Git sendiri seperti "Merge branch".

Referensikan issue: Hubungkan commit ke issue tracker dengan "Closes #123" atau "Fixes #456". Banyak platform menutup issue secara otomatis ketika commit di-merge.

Hindari pesan generik: Larang kata-kata seperti "update", "change", "fix" tanpa detail spesifik.

Review sebelum push: Jalankan git log dan baca commit Anda seolah-olah Anda melihatnya untuk pertama kali. Jika tidak masuk akal, tulis ulang.

Ajari tim Anda: Konvensi commit yang baik hanya berfungsi jika semua orang mengikutinya. Jadikan bagian dari proses onboarding dan code review Anda.

Kesimpulan Utama

History Git Anda adalah bentuk dokumentasi teknis. Ini adalah alat debugging. Ini adalah saluran komunikasi melintasi waktu.

Commit message profesional bukan tentang menjadi pedant. Ini tentang menghormati diri Anda di masa depan dan rekan tim Anda.

Mulai dari yang kecil. Pilih konvensi. Tegakkan dengan tool. Perhatikan produktivitas Anda bertambah saat history codebase Anda menjadi benar-benar berguna daripada noise arkeologi.

Perbedaan antara developer junior dan senior sering muncul di Git log sebelum muncul di kode.

#Git #Programming #Workflow