ข้ามไปเนื้อหาหลัก

Category: reference

Conventional Commits — เขียน Git Message อย่างเป็นระบบ

มาตรฐาน Conventional Commits ที่ทำให้ git log อ่านง่าย ทำ changelog อัตโนมัติได้ และเชื่อมกับ semantic versioning

· อ่านประมาณ 2 นาที

สารบัญ

Conventional Commits คืออะไร

Conventional Commits เป็น convention สำหรับเขียน commit message ให้มีโครงสร้างชัดเจน ทำให้:

  • git log อ่านเข้าใจได้ทันที
  • สร้าง changelog อัตโนมัติได้ด้วย tools
  • กำหนด version bump อัตโนมัติ (semantic versioning)

รูปแบบพื้นฐาน

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

ตัวอย่าง:

feat(search): add keyboard shortcut / to focus search
fix(nav): hamburger menu not closing on mobile
docs: update README with deployment instructions
chore(deps): bump astro from 6.3.0 to 6.4.6

Types ที่ใช้บ่อย

Typeใช้เมื่อSemver
featเพิ่มฟีเจอร์ใหม่MINOR
fixแก้ bugPATCH
docsแก้ documentation เท่านั้น
styleformat, whitespace, semicolon (ไม่ใช่ CSS)
refactorเปลี่ยน code โดยไม่เพิ่มฟีเจอร์/ไม่แก้ bug
perfปรับ performancePATCH
testเพิ่ม/แก้ test
choreงาน maintenance: deps, config, build
ciCI/CD pipeline
revertย้อน commit

Breaking Changes

ระบุด้วย ! หลัง type หรือ BREAKING CHANGE: ใน footer:

feat!: remove contact page

BREAKING CHANGE: /contact route no longer exists

หรือแบบ footer:

refactor(api): change response shape

BREAKING CHANGE: `data` field renamed to `payload`

Breaking change บอก tools ว่าต้อง bump MAJOR version

Scope

Scope บอกว่า commit กระทบส่วนไหนของ codebase:

feat(header): add dark mode toggle
fix(card): fix hover state on mobile
style(footer): align links vertically on small screens
chore(deps): update pagefind to 1.5.2

scope เป็น optional แต่ช่วย filter git log ได้ง่ายขึ้น

Multi-line Message

ใช้เมื่อ description บรรทัดเดียวไม่พอ:

fix(search): prevent double init after View Transition

Pagefind UI was re-initializing on every astro:page-load
even when the search element already existed, causing
duplicate search boxes to appear.

Added data-pfInit flag check before instantiation.

หลักการ: subject line ≤72 ตัวอักษร, body อธิบาย WHY ไม่ใช่ WHAT

ตัวอย่างจากโปรเจค Astro จริงๆ

feat(layout): add reading progress bar using CSS custom property

fix(toc): active heading not updating on fast scroll

feat(cards): add transition:name for View Transition shared elements

perf(fonts): add font-display=swap to Google Fonts URL

chore: update astro 6.3 → 6.4.6

feat(pagefind): add data-pagefind-ignore to noise elements

style(dark-mode): add missing dark override for count-badge

Tools ที่ช่วย

Commitlint

ตรวจ commit message อัตโนมัติใน CI:

npm install --save-dev @commitlint/cli @commitlint/config-conventional
echo "module.exports = { extends: ['@commitlint/config-conventional'] }" > commitlint.config.js

Changelogen / conventional-changelog

สร้าง CHANGELOG.md จาก git history:

npx changelogen --output CHANGELOG.md

Commitizen

Interactive prompt สำหรับเขียน commit message:

npm install -g commitizen
git cz  # แทน git commit

Tips

  • ใช้ภาษาเดียวตลอด project (ไทยหรืออังกฤษ) — อย่าปน
  • description ขึ้นต้นด้วย verb ในรูป imperative: “add”, “fix”, “remove” ไม่ใช่ “added”, “fixes”
  • ถ้า commit ทำหลายอย่างมากเกินไป ให้ split เป็นหลาย commit
  • ไม่ต้องใส่จุดท้าย description