Home Guide การเขียน commit message Git ที่ดี

การเขียน commit message Git ที่ดี

by khomkrit

นอกจากเราควรใช้ git ในแบบที่มันควรจะเป็นแล้ว อีกสิ่งหนึ่งที่ไม่ควรละเลยก็คือ การเขียน commit message ที่ดี

เวลาผมไปแชร์เกี่ยวกับการใช้ git เมื่อไหร่ ผมก็มักเล่าเกี่ยวกับแนวทาง การเขียน commit message ที่ดี พ่วงไปด้วย โดยผมจะอิงจากบทความนี้ ซึ่งมีทั้งหมด 7 ข้อด้วยกัน ดังนี้

1. เว้น 1 บรรทัด ระหว่างชื่อเรื่อง กับเนื้อหาในการ commit ออกจากกัน

แยก commit message เป็น 2 ส่วน แล้วคั่นทั้ง 2 ส่วนนั้นด้วยบรรทัดว่าง 1 บรรทัด โดยส่วนแรกจะถูกมองเป็นเหมือนชื่อของ commit ซึ่งชื่อของ commit นี้จะถูกใช้ในหลายๆ ที่ เช่น ตอนเรารันคำสั่ง git log หรือตอนรันคำสั่ง git shortlog เป็นต้น ส่วนที่สองก็คือส่วนเนื้อหา จะใช้เขียนคำอธิบายว่า commit นั้นๆ ทำอะไรไปบ้าง

แต่ก็ไม่ใช่ทุกกรณีที่ต้องการส่วนของเนื้อหา เช่นการ commit อะไรเล็กๆ น้อยๆ โดยไม่จำเป็นต้องเขียนคำอธิบาย เช่น

Fix typo in introduction to user guide

หากคนอื่นในทีมสงสัยว่าเราแก้อะไรไป ก็สามารถดูได้เองง่ายๆ โดยใช้คำสั่ง git show หรือ git diff ได้อยู่แล้ว เพราะว่าเป็นการแก้ไขไม่เยอะ ไม่ได้ดูยากอะไรเท่าไหร่นัก

แต่ถ้าหาก commit นั้นๆ ต้องการส่วนเนื้อหาเพื่ออธิบาย ก็สามารถเขียนแยกส่วนชื่อเรื่องกับส่วนเนื้อหาโดยคั่นด้วย 1 บรรทัดว่างๆ และเมื่อเรารัน git log ดูก็จะเห็นแบบนี้

$ git log
commit 42e769bdf4894310333942ffc5a15151222a87be
Author: Kevin Flynn <kevin@flynnsarcade.com>
Date:   Fri Jan 01 00:00:00 1982 -0200

 Derezz the master control program

 MCP turned out to be evil and had become intent on world domination.
 This commit throws Tron's disc into MCP (causing its deresolution)
 and turns it back into a chess game.

เมื่อเรารัน git log --oneline หรือ git shortlog ก็จะเห็นว่า git จะเลือกบรรทัดแรกมาแสดงผลให้เราดู

2. จำกัดบรรทัดที่เป็นชื่อเรื่องแค่ 50 ตัวอักษร

อย่างที่บอกไปว่านี่เป็นแค่แนวทาง ไม่ใช่ข้อบังคับอะไร แต่การใช้ความยาวที่ 50 ตัวอักษรนั้นคือความยาวที่ดูกำลังดี จะมากหรือน้อยกว่านี้ก็ไม่ว่ากัน ในเมื่อเราต้องการจำกัดที่ 50 ตัวอักษร ดังนั้นก็แปลว่าเราควรตั้งชื่อ commit ให้สื่อความหมายที่สุดว่า commit นี้ได้ทำอะไรลงไป เพื่อให้คนอื่นๆ เห็นภาพรวมได้กระชับชัดเจนตั้งแต่ทีแรก

3. ขึ้นต้นชื่อ commit ด้วยตัวอักษรพิมพ์ใหญ่

บรรทัดแรกทำหน้าที่เป็นชื่อเรื่อง และชื่อเรื่องควรขึ้นต้นด้วยตัวอักษรตัวพิมพ์ใหญ่ ไม่มีความหมายอื่นมากไปกว่านี้

4. อย่าลงท้ายชื่อ commit ด้วย จุด

ก็ตรงไปตรงมาตามหัวข้อ

5. ใช้คำสั่งในการตั้งชื่อ commit

การเขียน commit message ที่บรรทัดแรก ควรใช้อารมณ์เหมือนกำลังเขียนคำสั่ง ตัวอย่างคำสั่งก็เช่น

  • Clean your room
  • Close the door
  • Take out the trash

การใช้คำสั่งแบบนี้มันดูไม่ค่อยรื่นหูสักเท่าไหร่ แต่ก็เพื่อความเป็นอันหนึ่งอันเดียวกันกับที่ git เองก็ใช้แนวคิดนี้เช่นเดียวกันเวลาที่ git สร้าง commit message ให้เราแบบอัตโนมัติเช่นตอนที่เรา merge หรือ revert เช่น

Merge branch 'myfeature'

Revert "Add the thing with the stuff"
This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.

Merge pull request #123 from someuser/somebranch

ตัวอย่างการเขียน git commit message แบบคำสั่ง

  • Refactor subsystem X for readability
  • Update getting started documentation
  • Remove deprecated methods
  • Release version 1.0.0

พอบอกว่าเป็นคำสั่ง แรกๆ บางคนอาจเผลอเขียนออกมาแบบนี้

  • Fixed bug with Y
  • Changing behavior of X
  • More fixes for broken stuff
  • Sweet new API methods

ซึ่งสุดท้ายมาดูอีกทีก็อาจพบว่าแทบจะเขียนแบบนี้ในแทบทุก commit เลย ซึ่งมันแทบไม่บอกอะไรเท่าไหร่นัก จริงๆ แล้วแนวทางในการตั้งชื่อ commit ก็คือ ให้คิดในใจว่า

If applied, this commit will … นี่คือ commit title …

เช่น

  • If applied, this commit will refactor subsystem X for readability
  • If applied, this commit will update getting started documentation
  • If applied, this commit will remove deprecated methods
  • If applied, this commit will release version 1.0.0
  • If applied, this commit will merge pull request #123 from user/branch

เราจะใช้คำสั่งเฉพาะชื่อ commit เท่านั้น ส่วนคำอธิบายในส่วนที่สองนั้น เราจะเขียนให้อ่อนโยนสุภาพลงแค่ไหนก็ได้ แต่ต้องยึดกฎว่าชื่อ commit ต้องเป็นอารมณ์คำสั่งเท่านั้น

6. ส่วนเนื้อหาในแต่ละบรรทัดต้องยาวไม่เกิน 72 ตัวอักษร

เพื่อความสวยงามเวลาแสดงผล เช่นตอนรัน git log ล้วนๆ เลย ไม่มีอะไรมากไปกว่านี้

7. ส่วนเนื้อหาให้โฟกัสที่ what / why แทนที่จะเขียน how

นี่คือตัวอย่างการเขียน commit mesage ที่ดีโดยใช้แนวทางเดียวกับที่วกตัวอย่างมาทั้ง 6 ข้อก่อนหน้านี้จาก Bitcoin Core

commit eb0b56b19017ab5c16c745e6da39c53126924ed6
Author: Pieter Wuille <pieter.wuille@gmail.com>
Date:   Fri Aug 1 22:57:55 2014 +0200

   Simplify serialize.h's exception handling

   Remove the 'state' and 'exceptmask' from serialize.h's stream
   implementations, as well as related methods.

   As exceptmask always included 'failbit', and setstate was always
   called with bits = failbit, all it did was immediately raise an
   exception. Get rid of those variables, and replace the setstate
   with direct exception throwing (which also removes some dead
   code).

   As a result, good() is never reached after a failure (there are
   only 2 calls, one of which is in tests), and can just be replaced
   by !eof().

   fail(), clear(n) and exceptions() are just never called. Delete
   them.

ส่วนใหญ่แล้วเราแทบไม่จำเป็นต้องเขียนคำอธิบายเกี่ยวกับ how เลยเพราะเวลาเราเขียนโค้ดมันก็ควรจะ self-explain อยู่แล้ว หากอยากรู้ว่าทำอย่างไรก็ไปดูที่โค้ดต่อได้ ซึ่งถ้าหากว่าโค้ดมันซับซ้อนเกินกว่าจะไล่ให้เข้าใจได้ง่ายๆ เราก็เขียน commit ลงไปอธิบายในโค้ดแทน

สิ่งที่ต้องโฟกัสในการเขียน commit message ในส่วนของเนื้อหาก็คือ ให้เราเริ่มจากการเขียนเหตุผลก่อนว่าทำไมเราถึงทำตรงนี้มา จากนั้นให้อธิบายต่อว่าก่อนหน้านี้มันทำงานยังไง และหลังจากแก้ไปแล้วมันทำงานยังไง และทำไมเราถึงเลือกแก้ด้วยวิธีนี้

ส่งท้าย

อย่างไรก็ตาม ทั้ง 7 ข้อที่เขียนมานี้เป็นแค่แนวทางเท่านั้น จะทำตามหรือไม่ทำตามอย่างเคร่งครัดแค่ไหนก็ได้ ขึ้นอยู่กับทีมจะตกลงกัน เนื่องจาก commit message นั้นคือช่องทางการสื่อสารหนึ่งภายในทีม ดังนั้นเราจึงควรให้ความสำคัญกับการเลือกวิธีสื่อสารที่มีประสิทธิภาพที่สุดต่อทีมไว้ก่อน

ที่มา: chris.beams.io

You may also like