Conventional Branch

ข้อกำหนดสำหรับการเพิ่มความหมายที่ทั้งมนุษย์และเครื่องจักรสามารถอ่านได้ให้กับชื่อ Branch

Conventional Branch 1.1.0

บทสรุป

Conventional Branch หมายถึงธรรมเนียมปฏิบัติในการตั้งชื่อ Branch ของ Git ที่มีโครงสร้างและเป็นมาตรฐาน ซึ่งมีจุดมุ่งหมายเพื่อให้ชื่อ Branch อ่านเข้าใจง่ายและสามารถนําไปปฏิบัติงานต่อได้สะดวกขึ้น เราได้แนะนําคํานําหน้า (Prefix) ของ Branch บางส่วนที่คุณอาจต้องการใช้งาน แต่คุณก็สามารถกําหนดรูปแบบการตั้งชื่อของคุณเองได้เช่นกัน รูปแบบการตั้งชื่อที่สม่ําเสมอจะช่วยให้ระบุประเภทของ Branch ได้ง่ายยิ่งขึ้น

ประเด็นสําคัญ

  1. ชื่อ Branch ที่ขับเคลื่อนด้วยวัตถุประสงค์ (Purpose-driven Branch Names): ชื่อ Branch แต่ละชื่อจะระบุวัตถุประสงค์อย่างชัดเจน ทําให้ง่ายต่อนักพัฒนาทุกคนในการทําความเข้าใจว่า Branch นี้มีไว้เพื่ออะไร
  2. การทํางานร่วมกับ CI/CD: การใช้ชื่อ Branch ที่สม่ําเสมอสามารถช่วยให้ระบบอัตโนมัติ (เช่น Continuous Integration/Continuous Deployment pipelines) เรียกใช้การทํางานเฉพาะเจาะจงตามประเภทของ Branch ได้ (เช่น การดีพลอยอัตโนมัติจาก Branch สําหรับการปล่อยเวอร์ชัน หรือ Release)
  3. การทํางานร่วมกันในทีม: ส่งเสริมการทํางานร่วมกันภายในทีมโดยทําให้วัตถุประสงค์ของ Branch มีความชัดเจน ช่วยลดความเข้าใจผิด และทําให้สมาชิกในทีมสามารถสลับไปมาระหว่างงานต่างๆ ได้ง่ายขึ้นโดยไม่เกิดความสับสน

ข้อกําหนด

คำนำหน้าสำหรับการตั้งชื่อ Branch

ข้อกำหนดของ Branch รองรับคำนำหน้า (Prefixes) ดังต่อไปนี้ และควรจัดวางโครงสร้างเป็น:


<type>/<description>

คำนำหน้าตามวัตถุประสงค์ — อธิบายเจตนาของงาน:

  • feature/ (หรือ feat/): สำหรับฟีเจอร์ใหม่ (เช่น feature/add-login-page, feat/add-login-page)
  • bugfix/ (หรือ fix/): สำหรับการแก้ไขข้อบกพร่อง หรือ บั๊ก (เช่น bugfix/fix-header-bug, fix/header-bug)
  • hotfix/: สำหรับการแก้ไขเร่งด่วน (เช่น hotfix/security-patch)
  • release/: สำหรับ Branch ที่กำลังเตรียมการปล่อยเวอร์ชัน หรือ รีลีส (เช่น release/v1.2.0)
  • chore/: สำหรับงานที่ไม่เกี่ยวข้องกับโค้ดโดยตรง เช่น การอัปเดตการพึ่งพา (Dependency) หรือเอกสารอ้างอิง (Docs) (เช่น chore/update-dependencies)

คำนำหน้าแหล่งที่มาของเอเจนต์ AI — ระบุ Branch ที่สร้างโดยเอเจนต์การเขียนโค้ด AI:

คำนำหน้า เอเจนต์ ผู้ให้บริการ ตั้งแต่
ai/ เอเจนต์ AI ใดก็ได้ — v1.1.0
claude/ Claude Code Anthropic v1.1.0
codex/ OpenAI Codex OpenAI v1.1.0
copilot/ GitHub Copilot GitHub v1.1.0
cursor/ Cursor Anysphere v1.1.0

Trunk branches (main, master, develop) ไม่จำเป็นต้องใช้คำนำหน้า


กฎขั้นพื้นฐาน

  1. ใช้อักขระที่เป็นตัวอักษรและตัวเลขพิมพ์เล็ก เครื่องหมายขีดกลาง และจุด (Use Lowercase Alphanumerics, Hyphens, and Dots): ให้ใช้ตัวอักษรพิมพ์เล็ก (a-z), ตัวเลข (0-9) และเครื่องหมายยัติภังค์หรือขีดกลาง (-) เพื่อแยกคําเสมอ หลีกเลี่ยงการใช้อักขระพิเศษ เครื่องหมายขีดล่าง (Underscores) หรือช่องว่าง สามารถใช้จุด (.) ในคำอธิบายของ Branch ทุกประเภทได้ โดยทั่วไปใช้เพื่อแสดงหมายเลขเวอร์ชัน (เช่น release/v1.2.0, chore/upgrade-node-v20.11)
  2. ห้ามใช้เครื่องหมายขีดกลางหรือจุดติดกัน หรือวางไว้ตําแหน่งหน้าสุดหรือหลังสุด (No Consecutive, Leading, or Trailing Hyphens or Dots): ตรวจสอบให้แน่ใจว่าเครื่องหมายขีดกลางและจุดไม่ได้ปรากฏเรียงติดกัน (เช่น feature/new--login, release/v1.-2.0) และไม่ได้อยู่ตรงจุดเริ่มต้นหรือจุดสิ้นสุดของคําอธิบาย (เช่น feature/-new-login, release/v1.2.0.)
  3. รักษาความชัดเจนและกระชับ (Keep It Clear and Concise): ชื่อ Branch ควรอธิบายได้ดีแต่มีความกระชับ โดยระบุจุดประสงค์ของงานได้อย่างชัดเจน
  4. รวมหมายเลขทิกเก็ต (Include Ticket Numbers): หากเป็นไปได้ ให้ใส่หมายเลขทิกเก็ต (Ticket number) จากเครื่องมือบริหารจัดการโปรเจกต์ของคุณเข้าไปด้วยเพื่อให้ติดตามงานได้ง่ายขึ้น ตัวอย่างเช่น สําหรับทิกเก็ตหมายเลข issue-123 ชื่อ Branch อาจเป็น feature/issue-123-new-login

รูปแบบไวยากรณ์

รูปแบบไวยากรณ์ Augmented Backus-Naur Form หรือ ABNF ต่อไปนี้ได้กําหนดโครงสร้างเชิงรูปแบบของชื่อ Branch ที่ถูกต้อง:

branch-name     = trunk-branch / prefixed-branch
trunk-branch    = "main" / "master" / "develop"
prefixed-branch = type "/" description
type            = "feature" / "feat" / "bugfix" / "fix"
                / "hotfix" / "release" / "chore"
                / "ai" / "copilot" / "cursor"
                / "claude" / "codex"
description     = desc-segment *("-" desc-segment)
desc-segment    = 1*(ALPHA / DIGIT) *("." 1*(ALPHA / DIGIT))
ALPHA           = %x61-7A   ; lowercase a-z
DIGIT           = %x30-39   ; 0-9

หมายเหตุ: ไม่อนุญาตให้ใช้เครื่องหมายขีดกลางหรือจุดติดกัน และไม่อนุญาตให้ใช้เครื่องหมายขีดกลางหรือจุดในตําแหน่งเริ่มต้นหรือตําแหน่งสิ้นสุดของคําอธิบาย

ตัวอย่าง

ชื่อ Branch สถานะ หมายเหตุ
main ✅ Trunk branch
master ✅ Trunk branch
develop ✅ Trunk branch
feature/add-login-page ✅ ฟีเจอร์ใหม่
feat/add-login-page ✅ ชื่อเรียกย่อสําหรับฟีเจอร์
bugfix/fix-header-bug ✅ การแก้ไขบั๊ก
fix/header-bug ✅ ชื่อเรียกย่อของการแก้ไขบั๊ก
hotfix/security-patch ✅ การแก้ไขเร่งด่วน
release/v1.2.0 ✅ รีลีสพร้อมระบุเวอร์ชัน
chore/upgrade-node-v20.11 ✅ จุดใน Branch ที่ไม่ใช่รีลีส
chore/update-dependencies ✅ งานที่ไม่เกี่ยวกับโค้ด
feature/issue-123-new-login ✅ ฟีเจอร์พร้อมหมายเลขทิกเก็ต
Feature/Add-Login ❌ ไม่อนุญาตให้ใช้ตัวอักษรพิมพ์ใหญ่
feature/new--login ❌ ไม่อนุญาตให้ใช้เครื่องหมายขีดกลางติดกัน
feature/-new-login ❌ มีเครื่องหมายขีดกลางนําหน้าคําอธิบาย
feature/new-login- ❌ มีเครื่องหมายขีดกลางต่อท้ายคําอธิบาย
release/v1.-2.0 ❌ มีเครื่องหมายขีดกลางอยู่ติดกับจุด
fix/header bug ❌ ไม่อนุญาตให้เว้นวรรค (มีช่องว่าง)
fix/header_bug ❌ ไม่อนุญาตให้ใช้เครื่องหมายขีดล่าง (Underscores)
ai/refactor-auth-flow ✅ คำนำหน้าทั่วไปสำหรับเอเจนต์ AI
copilot/add-login-page ✅ GitHub Copilot
cursor/fix-header-bug ✅ Cursor
claude/security-patch ✅ Claude Code โดย Anthropic
codex/optimize-query ✅ OpenAI Codex
unknown/some-task ❌ ไม่รู้จักประเภทของคำนำหน้า

สรุปท้าย

  • การสื่อสารที่ชัดเจน: เพียงแค่เห็นชื่อ Branch ก็ช่วยให้เข้าใจถึงจุดประสงค์ของการเปลี่ยนแปลงโค้ดนั้นๆ ได้อย่างชัดเจน
  • รองรับระบบอัตโนมัติ: เชื่อมต่อกับกระบวนการอัตโนมัติได้ง่าย (เช่น เวิร์กโฟลว์ (Workflows) ที่แตกต่างกันสําหรับ feature, release และอื่นๆ)
  • การขยายขนาด: ทํางานได้ดีในทีมขนาดใหญ่ที่มีนักพัฒนาหลายคนกําลังปฏิบัติงานหลายส่วนที่แตกต่างกันไปพร้อมๆ กัน

โดยสรุปแล้ว Conventional Branch ถูกออกแบบมาเพื่อปรับปรุงการจัดระเบียบโปรเจกต์ การสื่อสาร และการทํางานแบบอัตโนมัติภายในเวิร์กโฟลว์ของ Git (Git workflows) ให้ดียิ่งขึ้น

เครื่องมือ

ใช้เครื่องมือเหล่านี้เพื่อปรับใช้และบังคับใช้ Conventional Branch ในโปรเจกต์ของคุณ:

  • commit-check: ตรวจสอบชื่อ branch, ข้อความ commit และ metadata ที่เกี่ยวข้องของ Git ในเครื่อง
  • commit-check-action: ตรวจสอบชื่อ branch โดยอัตโนมัติใน GitHub Actions
  • Conventional Branch Skill: สอนผู้ช่วยเขียนโค้ด AI ให้สร้างชื่อ branch แบบ Conventional Branch ที่ถูกต้อง

ติดตั้ง skill ด้วยคำสั่ง:

npx skills add conventional-branch/conventional-branch --skill conventional-branch

คำถามที่พบบ่อย

ชื่อ Branch คืออะไร?

ชื่อ Branch คือป้ายชื่อที่ Git ใช้เรียกสายการพัฒนาหนึ่งสาย เช่น main หรือ feature/add-login-page โดย Git เก็บชื่อนี้ไว้เป็น ref ภายใต้ refs/heads/ Git ยอมรับชื่อได้หลากหลายมาก ชื่อ Branch เพียงอย่างเดียวจึงไม่ได้บอกอะไรที่เชื่อถือได้เกี่ยวกับงานใน Branch นั้น Conventional Branch กำหนดโครงสร้างให้เป็น <type>/<description> คือประเภทที่บอกว่างานนี้มีไว้เพื่ออะไร ตามด้วยคำอธิบายสั้นๆ ที่เป็นตัวพิมพ์เล็ก โดยคั่นคำด้วยเครื่องหมายขีดกลาง ตัวอย่างเช่น:

  • feature/add-login-page
  • bugfix/fix-header-bug
  • release/v1.2.0

Trunk branches (main, master, develop) ไม่ต้องใช้คำนำหน้า

ฉันควรตั้งชื่อ Feature Branch อย่างไร?

ขึ้นต้นด้วย feature/ หรือชื่อเรียกย่อ feat/ แล้วอธิบายฟีเจอร์นั้นหลังเครื่องหมายทับ หากงานนั้นมีทิกเก็ตในเครื่องมือบริหารจัดการโปรเจกต์ของคุณ ให้ใส่หมายเลขทิกเก็ตด้วย ตัวอย่างเช่น:

  • feature/add-login-page
  • feat/add-login-page
  • feature/issue-123-new-login

Chore Branch คืออะไร?

Branch chore/ มีไว้สำหรับงานที่ไม่เกี่ยวข้องกับโค้ดโดยตรง เช่น การอัปเดต Dependency หรือเอกสาร ประเภทของ Branch ถูกตั้งใจให้มีน้อยกว่าประเภทของ Conventional Commits (ดูด้านล่าง) งานบำรุงรักษาลักษณะนี้จึงจัดอยู่ใน chore/ ตัวอย่างเช่น:

  • chore/update-dependencies
  • chore/upgrade-node-v20.11
  • chore/update-generated-files

บอตจัดการ Dependency บางตัว เช่น Renovate ก็สามารถตั้งค่าให้ใช้คำนำหน้านี้ได้เช่นกัน ดูบอตและระบบอัตโนมัติ

ฉันควรตั้งชื่อ Release Branch อย่างไร?

ใช้ release/ ตามด้วยสิ่งที่ Branch นั้นกำลังเตรียม ซึ่งโดยทั่วไปคือหมายเลขเวอร์ชัน ใช้จุดได้ แต่ห้ามอยู่ที่จุดเริ่มต้นหรือจุดสิ้นสุดของคำอธิบาย และห้ามอยู่ติดกับเครื่องหมายขีดกลาง:

  • release/v1.2.0 — ถูกต้อง
  • release/v1.2.0. — ไม่ถูกต้อง: มีจุดต่อท้าย
  • release/v1.-2.0 — ไม่ถูกต้อง: มีเครื่องหมายขีดกลางอยู่ติดกับจุด

คำนำหน้าที่สม่ำเสมอยังช่วยให้ Pipeline ทำงานกับ release/* ได้ เช่น ดีพลอยอัตโนมัติจาก Release Branch

ฉันควรตั้งชื่อ Hotfix Branch อย่างไร?

ใช้ hotfix/ สำหรับการแก้ไขเร่งด่วน และใช้ bugfix/ (หรือ fix/) สำหรับการแก้ไขที่ไม่เร่งด่วน อธิบายสิ่งที่กำลังแก้ไข และใส่หมายเลขทิกเก็ตด้วยหากมี ตัวอย่างเช่น:

  • hotfix/security-patch
  • hotfix/issue-123-security-patch
  • bugfix/fix-header-bug สำหรับการแก้ไขที่ไม่เร่งด่วน

Conventional Branch มีความเกี่ยวข้องกับ Conventional Commits อย่างไร?

Conventional Branch ได้รับแรงบันดาลใจมาจาก Conventional Commits และปฏิบัติตามปรัชญาที่คล้ายคลึงกัน นั่นคือ การนำโครงสร้างที่ทั้งมนุษย์และเครื่องจักรสามารถอ่านได้มาใช้กับข้อมูลเมตา (Metadata) ของ Git ในขณะที่ Conventional Commits เป็นการสร้างมาตรฐานให้กับข้อความการคอมมิต (Commit messages) ตัว Conventional Branch จะเป็นการสร้างมาตรฐานให้กับชื่อ Branch ซึ่งข้อกำหนดทั้งสองนี้ต่างช่วยเสริมซึ่งกันและกันได้อย่างลงตัว

Conventional Branch เป็นผู้คิดค้นคำนำหน้าเหล่านี้หรือไม่?

ไม่ใช่ คำนำหน้าอย่าง feature/, hotfix/ และ release/ แพร่หลายราวปี 2010 ผ่านเครื่องมือ git-flow และเป็นค่าเริ่มต้นในเครื่องมืออย่าง Branching model ของ Bitbucket Conventional Branch ต่อยอดจากแนวปฏิบัตินี้แทนที่จะเข้ามาแทนที่ สิ่งที่เพิ่มเข้ามาคือคำนิยามที่แม่นยำซึ่งทั้งคนและเครื่องมือใช้ร่วมกันได้ ได้แก่ ชุดประเภทที่กำหนดตายตัว ไวยากรณ์อย่างเป็นทางการ Regex สำหรับตรวจสอบที่เผยแพร่ใน spec.json และกรณีทดสอบความสอดคล้อง เพื่อให้เครื่องมือตรวจสอบทุกตัวยอมรับชื่อชุดเดียวกันทุกประการ

ทำไมประเภทของ Branch ถึงไม่ละเอียดเท่า Conventional Commits (เช่น build, ci, docs, style, refactor)?

Branch มีความแตกต่างจากการคอมมิต (Commits) — Branch เป็นเพียงสิ่งชั่วคราวและส่วนใหญ่จะถูกใช้งานจนกว่าจะถูกนำไปรวม (Merged) เท่านั้น การแนะนำประเภทของ Branch ให้มีมากเกินไปนั้นถือเป็นสิ่งไม่จำเป็น และจะทำให้ยากต่อการจัดการและการจดจำ

ฉันสามารถกำหนดประเภทของ Branch ด้วยตัวเองนอกเหนือจากรายการที่ระบุไว้ได้หรือไม่?

ได้ ในฐานะส่วนขยายระดับทีม ประเภทที่อยู่ในไวยากรณ์คือประเภทที่เครื่องมือที่สอดคล้องกับข้อกำหนดทุกตัวยอมรับ ดังนั้น Branch อย่าง unknown/some-task จึงไม่ถูกต้องตามข้อกำหนดนี้เอง ทีมที่ต้องการประเภทเพิ่มเติม (เช่น experiment/) ควรระบุประเภทเหล่านั้นในเครื่องมือตรวจสอบอย่างชัดเจน (เช่น ใน allow_branch_types ของ commit-check) และจัดทำเอกสารไว้ เพื่อให้สมาชิกในทีมและเครื่องมืออัตโนมัติเข้าใจตรงกัน ตัวอย่างเช่น Repository ของข้อกำหนดนี้เองได้เพิ่ม dependabot/ ไว้ในการตั้งค่า commit-check สำหรับ Branch ที่ Dependabot สร้างขึ้น

ทำไมชื่อ Branch ต้องเป็นตัวพิมพ์เล็ก?

มีเหตุผลสองข้อ ข้อแรก Git มักเก็บการอ้างอิง Branch เป็นไฟล์ใน .git/refs/heads/ และระบบไฟล์เริ่มต้นของ macOS และ Windows ไม่แยกตัวพิมพ์เล็กและใหญ่ Feature/login กับ feature/login จึงชี้ไปยังพาธเดียวกันบนเครื่องเหล่านั้น แต่บน Linux จะเป็นสอง Branch ที่ต่างกัน Repository ที่ยอมรับทั้งสองแบบจึงอาจทำงานต่างกันในแต่ละ Clone ข้อที่สอง การเขียนแบบเดียวทำให้พิมพ์ ค้นหา และจับคู่ได้ง่ายกว่า เครื่องมือที่ทำงานตาม release/* ไม่ต้องรองรับ Release/* เพิ่มอีก

ความแตกต่างหลักระหว่าง v1.1.0 และ v1.0.0 คืออะไร?

v1.1.0 เพิ่ม คำนำหน้าแหล่งที่มาของเอเจนต์ AI เป็นฟีเจอร์ใหม่หลัก (ดูคำถามถัดไปสำหรับสาเหตุที่นำมาใช้) นอกจากนี้ยังมาพร้อมกับเว็บไซต์แบบหลายเวอร์ชันพร้อมตัวสลับเวอร์ชัน เพื่อให้ผู้ใช้สามารถเรียกดูข้อกำหนดทั้งเวอร์ชัน v1.0.0 และ v1.1.0 ได้ ชื่อ Branch ที่มีอยู่แล้วทั้งหมดใน v1.0.0 ยังคงใช้ได้อย่างสมบูรณ์ — ไม่มีการเปลี่ยนแปลงที่ทำให้เสียความเข้ากันได้

ทำไมต้องเพิ่มคำนำหน้าแหล่งที่มาของเอเจนต์ AI?

เอเจนต์การเขียนโค้ด AI (GitHub Copilot, Cursor, Claude Code, OpenAI Codex ฯลฯ) ถูกใช้มากขึ้นในการสร้างโค้ดและสร้าง Pull Request แต่ละเอเจนต์ใช้คำนำหน้า Branch ของตัวเอง (เช่น copilot/, cursor/) การทำให้คำนำหน้าเหล่านี้เป็นมาตรฐานในข้อกำหนด Conventional Branch ช่วยให้:

  1. ระบุได้รวดเร็ว — ผู้ตรวจสอบและเครื่องมือสามารถจดจำ PR ที่สร้างโดย AI ได้ทันที
  2. การตรวจสอบด้วยเครื่องมือ — เครื่องมืออย่าง commit-check สามารถตรวจสอบ Branch ของเอเจนต์ AI ตามข้อกำหนดได้
  3. มาตรฐานการลงทะเบียน — เอเจนต์ AI ใหม่สามารถใช้คำนำหน้าที่ได้จัดทำเป็นเอกสารไว้แล้ว แทนการสร้างรูปแบบขึ้นมาเฉพาะกิจ

คำนำหน้าทั่วไป ai/ พร้อมใช้งานสำหรับเอเจนต์ AI ที่ไม่มีคำนำหน้าเฉพาะ หรือสำหรับทีมที่ต้องการตัวระบุที่ไม่ขึ้นกับผู้จำหน่าย นี่คือฟีเจอร์หลักที่ปล่อยใน v1.1.0 — สำหรับสรุปการเปลี่ยนแปลงทั้งหมดระหว่างเวอร์ชัน โปรดดูคำถามที่พบบ่อยด้านบน

ฉันควรจัดการกับ Branch ที่มีอายุยาวนานอย่าง develop หรือ staging อย่างไร?

Branch สำหรับการรวมโค้ดหรือสำหรับสภาพแวดล้อม (Environment branches) ที่มีอายุการใช้งานยาวนาน ซึ่งเป็นส่วนหนึ่งของข้อกำหนดหลัก (อ้างอิงถึงกฎ trunk-branch ในไวยากรณ์) เช่น main, master หรือ develop จะถูกจัดให้เป็น Branch หลัก (Trunk branches) และไม่จำเป็นต้องมีคำนำหน้า (Prefix) นอกจากนี้ แต่ละทีมยังอาจเลือกที่จะกำหนด Branch ที่มีอายุการใช้งานยาวนานอื่นๆ (ตัวอย่างเช่น staging หรือ production) ให้เป็น Branch ที่มีสถานะเสมือน Branch หลัก (“Trunk-like” branches) ตามธรรมเนียมปฏิบัติได้ แต่สิ่งเหล่านี้ถือเป็นส่วนขยายที่ขึ้นอยู่กับแต่ละทีมซึ่งอยู่นอกเหนือจากข้อกำหนดของรูปแบบไวยากรณ์ อย่างไรก็ตาม ในทุกกรณี Branch เหล่านี้ควรได้รับการตั้งชื่ออย่างสม่ำเสมอในทุกภาคส่วนของโปรเจกต์ของคุณ

มีเครื่องมือใดบ้างที่สามารถใช้ตรวจสอบได้โดยอัตโนมัติหากสมาชิกในทีมไม่ได้ทำตามข้อกำหนดนี้?

คุณสามารถใช้ commit-check เพื่อตรวจสอบข้อกำหนดของ Branch หรือใช้ commit-check-action หากโค้ดของคุณถูกฝากไว้บน GitHub