สรุปสั้น ๆ
สำหรับมือใหม่หลายคนคงเคยสงสัยว่า เราจะตั้งชื่อ Commit อย่างไรดี ? บางคนก็บอกว่าต้องใส่ “อีโมจิ” ลงไป บางคนก็บอกแบบนั้น แบบนี้ เอาจริง ๆ แล้ว โลกเรามีสิ่งที่เรียกว่า “Conventional Commits” หรือ ข้อกำหนด กติการ่วมกันในการเขียน Commit ไว้อยู่
ซึ่งเจ้าสิ่งนี้จะทำให้คนในทีม หรือ ใครที่จะหยิบโปรเจกต์ของเราไปใช้เข้าใจใน Commit ของเรา และ ถ้าเราเขียนตามนี้คอมพิวเตอร์ (เครื่องจักร) สามารถเข้าใจได้ด้วยเหมือนกัน ซึ่งหมายความว่า เราสามารถใช้เครื่องมือ Automation กับ Project เราได้อย่างมีประสิทธิภาพมากขึ้นด้วย
โดยในบทความนี้ เราก็ได้รวม Conventional Commit ที่น่าสนใจ ตามเว็บไซต์ conventionalcommits.org โดยจะเป็น Conventional Commits 1.0.0 ที่เราจะพูดถึงกัน
เขียนโดย
Kittikorn Prasertsak (Prame)
Founder @ borntoDev
บทความนี้ปรับปรุงเมื่อ 1 มกราคม 2567
เริ่มจากการเข้าใจโครงสร้างก่อน
สำหรับใครสักคนที่มือใหม่จริง ๆ เรามาดูองค์ประกอบของ Commit Message กันก่อน โดยจะมีโครงสร้างตามนี้
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
ต่อมารู้จักกับ Type หลัก ๆ ใน Commit กัน
- build: ใช้สำหรับการเปลี่ยนแปลงที่ส่งผลกับระบบ build หรือ dependency ภายนอก เช่น npm, gulp, broccoli เป็นต้น
- feat: ใช้สำหรับการเพิ่มฟีเจอร์ใหม่ลงมาใน Codebase ของเรา
- fix: ใช้สำหรับการแก้ไข Bug ต่าง ๆ ใน Codebase
- docs: ประเภทนี้ใช้สำหรับการที่เราเปลี่ยนแปลงแค่เฉพาะ Document
- style: การเปลี่ยนแปลงแค่สไตล์ โดยแน่นอนว่าจะไม่กระทบกับการทำงานหลักของ Code ที่เราเขียน เช่น white-space, formatting หรือ จนถึงการลืมใส่ semi-colins
- refactor: สำหรับการทำความสะอาดโค้ดให้อ่านง่าย เข้าใจมากยิ่งขึ้น ปรับปรุงโครงสร้างภายใน โดยไม่ได้ทำการแก้ Bug หรือ เพิ่มฟีเจอร์ต่าง ๆ ลงไป
- perf: คำนี้มาจาก Performance หรือ การปรับปรุงประสิทธิภาพการทำงานนั่นเอง
- test: การเปลี่ยนแปลงในส่วนของ Test ที่เราสร้างไว้ เช่น เพิ่ม Test-case
- ci: ปรับปรุง เปลี่ยนแปลง CI Config ของไฟล์ หรือ สคริปต์ เช่น Travis, Circle, BrowserStack
แต่เดี๋ยวก่อน จะบอกว่า Type ไม่ได้มีแค่นี้นะ แต่แค่เท่านี้ก็ถือว่าครอบคลุมสำหรับงานเกือบทั้งวันของเราแล้วนั่นเอง หากใครอยากดูเพิ่มเติม แนะนำลงหาจาก Convention ต่าง ๆ เช่น ใน Angular convention อ่านเพิ่มเติมได้เลย
แล้ว Scope หละ ต้องใส่อะไรบ้าง ?
อย่างที่เห็นจากตัวอย่างบนสุด ส่วนของ Scope เป็นรูปแบบ Optional คือจะใส่ หรือ ไม่ใส่ก็ได้ แต่จะอยู่ด้านหลัง Type เสมอ และ ใน Conventional Commit เขาได้มีบอกไว้ด้วยนะ ว่าการใส่ Scope นั้นจะต้องเป็นในรูปแบบของ “Noun” หรือ “คำนาม” และ เขียนในรูปแบบอยู่ในวงเล็บเท่านั้น โดยตัวอย่างของ Scope หากเราต้องการจะใส่ก็สามารถใส่ได้ตั้งแต่ข้อมูลที่เป็น
- module-name: ระบุชื่อโมดูล หรือ Component ของ Codebase เราลงไป
- library: ระบุชื่อ Library ของ Codebase
- frontend: กรณีที่ส่วนของ front-end ที่เกิดการเปลี่ยนแปลง
- backend: กรณีที่ส่วน back-end เกิดการเปลี่ยนแปลง
- database: เมื่อการเปลี่ยนแปลงเกิดขึ้นในชั้น database หรือ data storage
และ อื่น ๆ อีกเพียบ โดยตรงนี้เป็นแค่เพียงตัวอย่างกว้าง ๆ เท่านั้น เราสามารถใส่ Scope ตรงนี้เป็น api กรณี change เกิดกับ API หรือ lang กรณีเราอัพเดตการแปลภาษาต่าง ๆ ก็ได้เช่นกัน แต่ขออย่างเดียวคือจะต้องระบุให้ถูกที่เท่านั้น
มาดูในส่วน Description กับ Body ไปด้วยกัน
หนึ่งสิ่งที่ต้องรู้คือ แม้ว่าในโครงสร้างจะเขียนว่าเป็น description แต่การทำงานของเขาเหมือนกับ Subject หรือ ชื่อหัวข้อการ / การสรุปสั้น ๆ ของเปลี่ยนแปลงนั่นเอง และ ในส่วนของ body ที่แม้ว่าจะเป็น optional ที่จะใส่ หรือ ไม่ใส่ก็ได้ แต่มีประโยชน์สำหรับเราไม่น้อย ซึ่งความแตกต่างของทั้งสองสิ่งมีดังนี้
- Description (Subject) หากเขียนจะอยู่หลังเครื่องหมาย Semicolon และ เว้น Space ไว้ด้านหน้า 1 ครั้ง โดยส่วน Description นี้จะเป็นเหมือนสรุปสั้น ๆ เกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้น เช่น fix: array parsing issue when multiple spaces were contained in string.
- Body (Long Description) มีไว้ในกรณีที่เราต้องการลงรายละเอียดของการเปลี่ยนแปลง เช่น เราแก้ไข Bug ตัวนี้ได้ยังไง, ปัญหาที่เราพบ, ขั้นตอนการทำงานของอะไรบางอย่าง โดยใน Convention Commit ได้ระบุไว้ว่า การเขียน Body นี้จะเป็นในรูปแบบ free-form
โดยในปัจจุบันการเขียนข้อมูลในส่วน Description นั้นมักจะเขียนในรูปแบบของ Imperative Mood หรือ การเขียนในรูปแบบประโยคคำสั่ง / ร้องขอ เช่น “Fix bug …” หรือ “Add feature …”
ก็ดูเหมือนครบแล้วนี่ .. แล้ว Footer มันคืออะไร ?
แน่นอนว่า Footer นี่คือ Optional อีกตัว แต่เราสามารถใช้ประโยชน์จากเขาได้ในการใส่เพื่อให้ข้อมูลเพิ่มเติม โดยในส่วน Footer นี้อาจจะมีข้อมูลหลากหลายตัวก็ได้ วิธีการเขียน Footer คือ “ให้เรานำบรรทัดว่างคั่นกลางระหว่าง Body กับ Footer ที่จะเขียน” นั่นเอง
โดยตัวอย่าง Keyword ที่มักจะพบกันบ่อย ๆ ใน Footer คือ “BREAKING CHANGE” (หรือจริง ๆ จะใส่เครื่องหมาย ! ไว้หลัง type/scope ก็ได้) ที่มีหน้าที่เป็นตัวบอกว่า “การเปลี่ยนแปลงนี้ใน Commit จะ break การทำงานหลักของ Codebase” เช่น
chore!: drop support for Node 6
BREAKING CHANGE: use JavaScript features not available in Node 6.
จากที่เห็นในตัวอย่างจะพบได้ว่า เราสามารถข้าม Body ได้ ถ้าไม่มี และ กระโดดมาใส่ Footer ในส่วน BREAKING CHANGE ได้เลย
ใช้หมดนี่แล้วเกิดอะไรขึ้น ? แค่อ่านง่ายแค่นั้นไหม ?
อย่างที่บอกไปตอนต้น เอาจริง ๆ แค่ในทีมอ่านง่ายก็เพียงพอแล้ว สำหรับใครที่ยังไม่เคยเริ่มใช้ อาจจะรู้สึกไม่เข้ามือในช่วงแรก แต่พอใช้นาน ๆ จะกลายเป็นมาตรฐานที่สามารถส่งต่อให้เพื่อนร่วมทีมคนใหม่ ๆ เข้าใจงานเราได้ง่ายขึ้นนั่นเอง และ นอกจากนี้ยังมีข้อดีอื่น ๆ อีกเพียบ ไม่ว่าจะเป็น
- การทำ CHANGELOG แบบอัตโนมัติ
- การมี Trigger เพื่อสั่งให้ Build / Publish ฟีเจอร์ต่าง ๆ ได้ด้วยตัวระบบเอง
- การจับความหมายของ version อัตโนมัติ ตามประเภทของ Commit
ซึ่งจะเห็นได้ว่านอกจากคนอย่างเรา ๆ จะอ่านแล้วพอเข้าใจได้แล้ว เรายังทำ Automation กับการเขียนในลักษณะนี้ได้ด้วย
เรื่องอื่น ๆ และ ตัวอย่างที่น่าสนใจ
สำหรับเรื่องอื่น ๆ เช่น การพิมพ์ในส่วน Type นั้น ขึ้นต้นต้องพิมพ์เล็ก หรือ ตัวพิมพ์ใหญ่นั้น จะขึ้นอยู่กับการใช้งาน แต่ถ้าเราใช้แบบไหน ก็ควรมีความสอดคล้องกันไปทั้งโปรเจกต์
หรือ ตัวอย่างการ Commit ที่มี Description และ Breaking Change ใน Footer แบบครบ ๆ
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
หรือ การ Commit แบบง่าย ๆ ที่ไม่มี body
docs: correct spelling of CHANGELOG
จนถึงการใส่ Scope ก็ไม่จำเป็นต้องเป็นอะไรที่เกี่ยวกับไฟล์อย่างเดียว อาจจะเกี่ยวกับหมวดการแก้ไขเรื่องภาษา การแสดงผลข้อความในลักษณะนี้ก็ได้เช่นกัน
feat(lang): add Thai language
และ สุดท้ายหากใครอยากจะอ่านแบบเต็ม ๆ ซึ่งเอาจริง ๆ แล้ว Spec ของ Conventional Commits นี้มีไม่เยอะ แค่เพียง 16 ข้อเท่านั้น (หลายข้อค่อนข้างตรงไปตรงมา Common sense อยู่แล้ว) สามารถเข้าไปดูได้ที่เว็บไซต์ conventionalcommits.org ของเขาได้เลยคร้าบ
หากใครคิดว่าเป็นประโยชน์ หรือ ในทีมกำลังเขียน Commit แบบเละเทะกันอยู่ ก็ฝากแชร์ให้นำไปใช้โดยทั่วกันได้เลย
ระบบฝึกทักษะ การเขียนโปรแกรม
ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง
- โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
- รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
- ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!