ในโลกของ Software Development จะมีสิ่งหนึ่งที่เรียกว่า Source Code ซึ่ง Source Code นี้จะถูกเขียนและร่วมกันพัฒนาขึ้นโดย Software Engineer อยู่ในรูปแบบที่มนุษย์สามารถอ่านและทำความเข้าใจได้ และการนำเอาภาษาเหล่านี้มาคอมไพล์จนเป็นโปรแกรมที่สามารถใช้งานได้บนเว็บเบราว์เซอร์หรือเครื่องของเรา หลายท่านอาจจะเคยเห็นชื่อของภาษาเหล่านี้ผ่านตามาบ้าง เช่น JavaScript, Java, C++, Python, Ruby
พอจะเห็นภาพกันแล้วว่า Source Code คืออะไร เรามาดูกันต่อในส่วนของการเก็บและดูแลรักษา Source Code ที่ถูกเขียนขึ้นนั้นจะมีสิ่งที่เรียกว่า Version Control System หรือ VCS คอยช่วยติดตามการเปลี่ยนแปลงที่เกิดขึ้น ตัวอย่างเช่น
commit 722f8ca8eaba5691e5597f2726535ed0319a1838
Author: Ayuth Mangmesap
Date: Sat Jul 30 12:47:42 2022 +0700
style: change default font weight variable and add more weights
diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx
index ecbb14a..92dcc49 100644
--- a/components/Header/Header.tsx
+++ b/components/Header/Header.tsx
@@ -48,13 +48,14 @@ const Wrapper = styled.div`
`
const NavLink = styled.a`
+ font-weight: var(--font-weight-regular);
text-decoration: none;
cursor: pointer;
color: inherit;
`
const HomeLink = styled(NavLink)`
- font-weight: var(--font-weight-bold);
+ font-weight: var(--font-weight-extra-bold);
text-transform: uppercase;
`
...
จากโค้ดด้านบนจะเห็นได้ว่า บรรทัดสีแดงคือบรรทัดที่ถูกลบไป ส่วนบรรทัดสีเขียวคือส่วนที่ถูกเพิ่มเข้ามาแทนที่ แทนที่โดยใคร วัน เวลา วันที่เท่าไร จึงทำให้เราสามารถติดตามการเปลี่ยนแปลงได้อย่างชัดเจนและการเปลี่ยนแปลงเหล่านี้จะถูกเก็บเป็นประวัติที่สามารถย้อนกลับมาหาได้ทุกเมื่อเช่นกัน นี่จึงเป็นสิ่งที่ทำให้ VCS อย่างเช่น Git ได้รับความนิยมมาก อย่างไรก็ตามบล็อกนี้จะไม่ใช่การอธิบายเกี่ยวกับ Git หรือ VCS (Version Control System)เจ้าไหน มีบล็อกที่อธิบายได้ดีอยู่แล้วครับ
อธิบายสำหรับท่านที่ไม่ใช่สาย Dev การ commit เปรียบเสมือนการเลือกเอาพัสดุใส่ลงไปในกล่องจากนั้น “ปิดผนึกกล่อง” และ “แปะข้อความ” ลงไปว่าในกล่องนั้นเก็บอะไรอยู่บ้าง
- 📦 การปิดผนึกกล่อง เปรียบเสมือน commit
- 📝 การแปะข้อความลงบนกล่องที่ผนึก เปรียบเสมือน commit message
ทำไมต้องเขียน Commit ให้ดีและมีความหมาย?
Commit Message ถือได้ว่าเป็นอีกหนึ่งทางที่นักพัฒนาใช้สื่อสารกันด้วยการอ่าน นอกเหนือจากการสื่อสารด้วยการพูดคุยกัน การศึกษาทางประวัติศาสตร์ทำให้เราเข้าใจว่าสิ่งรอบตัวเราในปัจจุบันนั้นมีประวัติความเป็นมาอย่างไร เปลี่ยนแปลงไปเมื่อไร ใครเป็นคนเปลี่ยน เช่นเดียวกับ Commit Message ถ้าใครเคยอ่าน Handbook ของ GitLab มีประโยคหนึ่งที่น่าสนใจเขียนไว้ว่า
Reading is much faster than listening.
เอาละมาดูข้ออดีแต่ละข้อกันดีกว่า
- Commit Message ที่ดีจะทำให้ทำความเข้าใจโค้ดและแก้ปัญหาได้เร็วขึ้น → เช่น โค้ดบรรทัดนี้เกิดมาได้อย่างไร เกิดเพราะอะไร เกิดขึ้นเมื่อไร ใครเป็นคนเขียน
- เพิ่มประสิทธิภาพในการสื่อสารในทีม → เพราะเราไม่ได้ทำงานคนเดียว
- ลดระยะเวลาในการค้นหาประวัติ Commit เก่า ๆ → ในกรณีที่เกิดปัญหาขึ้นไม่ว่าจะเป็น bug ใน production การค้นหา commit ที่เขียนได้มีความหมายจะช่วยลดระยะเวลาในการย้อนกลับมาและแก้ปัญหาได้ทันท่วงที
- สามารถสร้าง Automation tools เพื่อทำให้ commit ที่ push ขึ้นไปสั่งไปทำงานบางอย่างได้ เช่น build, rebuild หรือ publish ก็ตาม
ลองมาดูตัวอย่างระหว่างใน คุณหมา() กับ คุณแมว() กันบ้างด้วยตัวอย่างที่ง่ายที่สุด
หมา(): Update README.md file
แมว(): docs: update README.md file
สังเกตเห็นไหมครับว่าระหว่างนาย A กับนาย B มี message ที่เหมือนกัน เพียงแต่นาย B มีคำว่า “docs” อยู่ด้านหน้า ถ้าอ่านโดยผ่านตาเราจะทราบว่าทำอะไรสักอย่างเกี่ยวกับ README.md ในหัวข้อถัดไปว่านอกเหนือจากคำว่า “docs” แล้วมีอะไรอีกบ้าง ตัวอย่างต่อไป
หมา(): add the register feature
แมว(): feat(api)!: add the register feature
*หมายเหตุ เครื่องหมาย “!” แสดงถึงการที่มี breaking changes อยู่ใน commit นั้น
หมา(): update README.md
แมว(): docs: update README.md
ตัวอย่างสุดท้าย
หมา(): change the button color
แมว(): style(homepage): change the button color (#7832)
ถ้าเราสังเกตให้ดี จะเห็นว่าแค่ส่วนของ style ที่เป็น prefix ข้างหน้าเราก็พอรู้แล้วว่าสิ่งที่ commit มานั้นเกี่ยวกับอะไร แทบจะไม่ต้องดูลงลึกไปในรายละเอียดด้วยซ้ำ ช่วยให้ประหยัดเวลาได้เยอะทีเดียว
ลองจินตนาการว่าถ้าเราไม่ได้มีแค่โปรเจคเดียว แต่มีเป็น 10 หรือลามไป 100 โปรเจค และท่านต้องค้นหาว่าบัคนี้ถูกเอาขึ้นมาตอนไหนแล้วละก็ น้ำตาท่านอาจจะคลอเบ้าได้ (เคสจริงไม่อิงนิยาย 🫣)
รูปในการเขียน Conventional Commits
เกริ่นกันถึงข้อดีและทำไมเราถึงต้องเขียน Commit Message ให้ดีและมีความหมายมาแล้ว ทีนี้มาดูโครงสร้างของ Commit กันบ้าง โครงสร้างของ commit จะประกอบด้วย 3 ส่วน คือ type, scope, description, bodyและ footer
[optional scope]:
[optional body]
[optional footer(s)]
type
สำหรับ type จะเป็นได้ดังนี้
- fix → การแก้บัค
- feat → การเพิ่ม feature ใหม่
- docs → สำหรับการเปลี่ยนแปลงแค่ documentation (ไม่กระทบกับโค้ดหลัก)
- style → สำหรับการเปลี่ยนแปลงที่ไม่ได้เปลี่ยนแปลงความหมายของโค้ด เช่น ลบ white-space, การแก้ format, หรือเติม semi-colon ที่หายไป
- refactor → สำหรับการแก้ไขที่ไม่ใช่การแก้บัค(fix) หรือ เพิ่มความสามารถใหม่(feature)
- chore → การเปลี่ยนแปลงที่ไม่ใช่การแก้บัค(fix)หรือการเพิ่มความสามารถใหม่(feature) เช่น การอัพเดท dependencies
- test → เพิ่มส่วนของ test แก้ไขเทสเคสเดิมให้สมบูรณ์ยิ่งขึ้น
- อื่น ๆ → build , ci , pref , revert
scope (optional)
scope → จะต้องเป็นขอบเขตที่กำหนดไว้ ถ้าในโปรเจคของเราจะมีส่วนของ docs หรือ core package หลัก อันนี้แล้วแต่ทีมท่านตกลงกันว่าจะมีอะไรบ้าง ผมลองเอาตัวอย่าง scope จาก Angular โปรเจคจะมีดังนี้เผื่อจะเป็นไอเดียให้เราได้
The following is the list of supported scopes:
- animations
- common
- compiler
- compiler-cli
- core
- elements
- forms
- http
- language-service
- platform-browser
- platform-browser-dynamic
- platform-server
- platform-webworker
- platform-webworker-dynamic
- router
- service-worker
- upgrade
description หรือ subject
ส่วนนี้จะเป็นข้อความที่สั้น กระชับ ที่บ่งบอกการเปลี่ยนแปลงของ commit นั้น
- ต้องเป็นประโยคหรือข้อความที่แสดงถึงความเป็นปัจจุบัน (present tense)
- ไม่ต้องขึ้นต้นด้วยตัวใหญ่
- และไม่ต้องมีเครื่องหมายจุด (.) ต่อท้าย
body (optional)
ส่วนที่ขยายต่อมาจากส่วน subject ส่วนนี้จะ
ในส่วนของ body นั้นจะต้องบ่งบอกหรือแสดงถึงแรงจูงในที่ทำให้เกิด commit นี้หรือสิ่งที่ขัดแย้งจากสิ่งเดิมหรือพฤติกรรมเดิมที่มีอยู่แล้ว
คือส่วนที่
footer (optional)
ในส่วนนี้สามารถลิงค์ไปที่หมายเลข Issue ในโปรเจคหรือ Jira ที่ commit นี้ได้แก้ปัญหาหรือปิดไปได้เช่นกัน
สำหรับใครอยากอ่านต่อ เว็บ Conventional Commits มีภาษาไทยด้วย! สามารถไปอ่านกันได้ครับ
ตัวอย่างจริง Angular Repository บน GitHub
ปกติผมเป็นคนที่ชอบ explore ใน GitHub อยู่แล้ว พวกเครื่องมือที่ Developers ใช้จะ Open Source อยู่แล้ว ผมจะชอบไปขุดคุ้ยดูว่าโปรเจคใหญ่ ๆ ที่มีคนใช้งานรวมถึงดาวน์โหลดมากกว่าล้านครั้งเขามีการบริหารจัดการอย่างไร หรือแนวทางปฏิบัติที่ส่วนไหนที่เราสามารถทำมาใช้กับโปรเจคของเราได้บ้างไหม แน่นอนว่าได้เรียนรู้อะไรเยอะแยะเลยครับ
ถ้าเราเปิดดู Angular โปรเจคใน GitHub จะเห็นส่วนหนึ่งที่อยู่ใน Contribution Guideline นั่นคือ Commit Message Format โดยในส่วนของคู่มือนี้จะเขียนแนวทางในการเขียน commit message อย่างชัดเจนว่าเขาจะแบ่ง commit message ออกเป็น 3 ส่วนคือ header, body และ footer ซึ่งในที่นี้เราจะมาดูส่วนที่เกี่ยวข้องในบทความนี้คือส่วนของ header ครับ
เขาจะเล่าว่ามี type ไหนบ้างที่อนุญาตให้ใช้และ scope ไหนให้ใช้งานและข้อความด้านหลังสุดควรจะเป็น short summary หรือสรุปสั้น ๆ นั่นเอง
():
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|router|service-worker|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
│ devtools
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
ที่น่าสนใจกว่านั้นคือทางทีมที่ดูแลโปรเจค Angular ได้นำพวกแนวทางที่เขียนไว้มาทำเป็นเครื่องมือเพื่อเช็คในว่าในแต่ละครั้งที่เรามีการ commit นั้น ในส่วนของ commit message ได้ตรงตามที่โปรเจคระบุไว้หรือเปล่า
เขาจะเล่าว่ามี type ไหนและ scope ไหนที่อนุญาตให้ใช้งานบ้าง
สรุป
การเขียน Commit Message ให้ดีและมีความหมายนั้นนอกจากจะทำให้ การสื่อสารในทีมและระหว่างทีม การเพิ่มทำให้ประสิทธิภาพในการทำงานที่มากขึ้น การช่วยให้กลับมาประวัติต่าง ๆ ได้อย่างไม่ต้องเสียเวลา พร้อมทั้งตัวอย่างที่เห็นภาพได้ชัดเจนไปแล้ว
นอกจากนี้ยังได้ยกตัวอย่างโปรเจค Angular ของ Google ที่ได้มีการเขียนแนวทางการปฏิบัติในการทำงานร่วมกันอย่างชัดเจนสำหรับการเขียน Commit Message เอาไว้ ทำให้สามารถทำงานร่วมกับ Engineers จากทั่วมุมโลกได้ นอกจากนี้ยังสร้างเครื่องมือสำหรับการตรวจสอบ Commit Message ว่าได้ตรงกับแนวทางปฏิบัติที่ได้กำหนดไว้ด้วยเช่นกัน
หากท่านใดสนใจที่จะนำไปใช้หรือเคยใช้กับทีมของท่านเอง สามารถคอมเม้นท์ด้านล่างเพื่อแชร์ประสบการณ์ได้เพื่อน ๆ ได้อ่านเช่นกันครับ หรือท่านใดยังไม่มีแนวทางในใจ ถ้าจะเอาไปลองใช้ก็คงจะเป็นจุดเริ่มต้นที่ดีไม่น้อยเลยละ
เขียน Commit Message ให้ดีขึ้น … แล้วชีวิตคุณจะเปลี่ยนไป
ช่วงขายของ GitKraken
เมื่อพูดถึง Git ต้องนึกถึง GitKraken ในฐานะ GitKraken Ambassador แล้วละก็จะไม่พูดถึงก็กระไรอยู่ ขอพื้นที่สักหน่อย (ตอนแรกว่าจะไม่ขายละ … เอาตอนหลังเลยคืออดไม่ได้)
GitKraken คือ Git UI ที่ดีที่สุดตอนนี้ มันสามารถต่อได้ทั้ง GitHub, GitHub Enterprise, GitLab + Enterprise, BitBucket อีกทั้งต่อกับพวก Jira, Trello ได้ แถมยังใช้ GitFlow ในตัว มี Terminal ในตัว และสามารถมีหลายโปรไฟล์ไม่ว่าจะเป็นโปรไฟล์ที่ทำงาน หรือโปรไฟล์ส่วนตัว ใช้ได้ทั้ง macOS, Windows, Linux ขายขนาดนี้ไม่ลองไม่ได้แล้ว!
ตอนที่เขียนนี้ได้ขึ้นเวอร์ชัน 9 เป็นที่เรียบร้อย มีการออกแบบ UI ใหม่ทั้งหมด เพิ่มฟีเจอร์ที่น่าสนใจเยอะมากสามารถไปลองกันได้เลยครับ
คลิก>>You’ve been invited to use GitKraken Client!
ไม่ใช้ไม่เป็นไร … นึกถึงกันไว้ก็พอ 🫶
แหล่งอ้างอิง