- Git notes เป็นเครื่องมือทรงพลังที่ใช้แนบ metadata ให้กับคอมมิตและอ็อบเจ็กต์อื่น ๆ ได้
- ฟีเจอร์นี้ช่วยให้สามารถเก็บข้อมูลเสริมได้ในกรณีที่ไม่สามารถแก้ไขข้อความคอมมิตได้
- สามารถนำไปใช้เก็บข้อมูลได้หลากหลาย เช่น ประวัติการรีวิวโค้ด หรือผลการทดสอบ
- มันสามารถต่อยอดไปถึงการสร้างระบบรีวิวโค้ดแบบกระจายศูนย์ได้ แต่การใช้งานและการรับรู้ยังต่ำ
- การรองรับที่ไม่เพียงพอ เช่น การถูกปิดใช้งานบน GitHub ทำให้ยังไม่ถูกนำไปใช้ในชีวิตประจำวันมากนัก
Git notes คืออะไร
- Git notes เป็นฟีเจอร์ใน git ที่ทำให้สามารถแนบ metadata ให้กับอ็อบเจ็กต์ใด ๆ ที่ git ติดตามอยู่ได้ (คอมมิต, blob, tree)
- โดยทั่วไปข้อความคอมมิตที่ถูกบันทึกไปแล้วจะไม่สามารถเปลี่ยนแปลงได้ แต่เมื่อใช้ git notes ก็สามารถเพิ่มข้อมูลใหม่ได้โดยไม่ต้องแก้ไขเนื้อหาของคอมมิต
- ตัวอย่างเช่น สามารถเพิ่ม notes ให้กับคอมมิตได้ดังนี้
git notes add -m 'Acked-by: <이메일>'
- notes จะแสดงร่วมกันใน
git log ในส่วนแยกต่างหาก
กรณีการใช้งานจริง
- แม้แต่โปรเจ็กต์ git เองก็ใช้ git notes เพื่อเชื่อมโยงคอมมิตกับเธรดการสนทนาในเมลลิงลิสต์
- ตัวอย่างการใช้งานจริงของ notes มีดังนี้
- ติดตามเวลาการทำงานแยกตามคอมมิตหรือบรันช์
- เก็บบันทึกการรีวิวโค้ดและผลการทดสอบ
- ออกแบบระบบรีวิวโค้ดแบบกระจายศูนย์อย่างสมบูรณ์
การเก็บรีวิวโค้ดและผลการทดสอบ
- มีกรณีเพิ่มขึ้นที่ code forge หรือระบบรีวิวรองรับการเก็บ metadata ของการรีวิวโค้ดแบบออฟไลน์ หรือก็คือเก็บไว้ใน git เอง
- reviewnotes plugin ของ Gerrit จะแสดงผู้รีวิวและประวัติการรันทดสอบเป็น notes ร่วมกันใน
git log
- ผู้ใช้จึงสามารถตรวจสอบประวัติการรีวิวโค้ดได้จากในเครื่องโดยไม่ต้องเปิดเบราว์เซอร์แยก
ระบบรีวิวโค้ดแบบกระจายศูนย์
- มีตัวอย่างอย่าง git-appraise ที่พัฒนาโดย Google ซึ่งใช้ git notes เพื่อทำให้การรีวิวโค้ดแบบกระจายศูนย์เกิดขึ้นได้จริง
- git-appraise บันทึกทุกขั้นตอนไว้ใน git notes ไม่ว่าจะเป็นคำขอรีวิวโค้ด ความเห็นต่อการเปลี่ยนแปลง หรือการ merge หลังรีวิว และทำงานได้อย่างอิสระโดยไม่ขึ้นกับบริการโฮสต์โค้ดออนไลน์
- การทำงานร่วมกันทั้งหมดทำได้ในสภาพแวดล้อมแบบโลคัล และยังมีเว็บอินเทอร์เฟซให้ด้วย
การใช้งานและการรับรู้ที่ต่ำ
- Git notes แทบไม่ถูกใช้งาน เพราะอินเทอร์เฟซใช้งานไม่สะดวกและไม่ค่อยเป็นธรรมชาติสำหรับผู้ใช้ทั่วไป
- GitHub หยุดแสดงคอมมิต notes ตั้งแต่ปี 2014 ทำให้โอกาสในการใช้งานยิ่งลดลง
- แม้การจัดการ notes สำหรับคอมมิตจะทำให้ง่ายขึ้นได้ด้วยการตั้งค่า git แต่ถ้าจะติด notes ให้กับ blob หรือ tree object ก็ยังต้องเข้าใจโครงสร้างภายในของ git (plumbing) เพิ่มเติม
- ผลก็คือ git notes ยังคงเป็นฟีเจอร์เฉพาะกลุ่มและแทบไม่มีใครรู้จัก
ความเป็นอิสระจาก Open Forge
- ตัว git เองรองรับทั้งการจัดการเวอร์ชันแบบกระจายศูนย์และการรีวิวโค้ดได้ แต่คุณค่าเสริมจำนวนมาก เช่น ประวัติการรีวิว มักผูกติดกับบริการโฮสต์อย่าง GitHub อย่างมาก
- การใช้ฟีเจอร์ Git notes เปิดทางให้ไม่เพียงเก็บและเผยแพร่ประวัติการเปลี่ยนแปลงของโค้ดเท่านั้น แต่รวมถึงประวัติทั้งหมดของโปรเจ็กต์ในรูปแบบกระจายศูนย์ด้วย
- สิ่งนี้มีความหมายสำคัญต่อระบบนิเวศการพัฒนาแบบกระจายศูนย์อย่างแท้จริงและการเก็บรักษาบันทึกระยะยาว
1 ความคิดเห็น
ความเห็นจาก Hacker News
มีการแชร์ข้อมูลว่ามีฟีเจอร์ที่ไม่ค่อยเป็นที่รู้จักชื่อว่า Git trailers โดย trailers สามารถแทรกเมทาดาทาในรูปแบบ key-value ตอนสร้าง commit ได้ และถูกนำไปใช้เพื่อแนบ Change-Id ใน Gerrit ลิงก์บทความที่เกี่ยวข้อง
มีฟีเจอร์คล้ายกันใน PostgreSQL ชื่อ COMMENT มีการแชร์ข้อมูลว่า COMMENT สามารถเพิ่มข้อความให้กับอ็อบเจ็กต์ในฐานข้อมูลได้ และหวังว่า PostgreSQL จะมีความสามารถแก้ไขเมทาดาทาแบบมีโครงสร้างในรูปแบบ key-value ด้วย ลิงก์เอกสารที่เกี่ยวข้อง
มีการแชร์ประสบการณ์ใช้ git notes เพื่อทำเครื่องหมาย commit ที่ผ่าน unit test แล้วระหว่างทำงานกับ upstream ของโอเพนซอร์ส ซึ่งมีประโยชน์ตอนเกลาสาขาด้วย git rebase -i แต่ตอนนี้ trailers ดูเหมือนจะเป็นวิธีที่ดีกว่า หากฟีเจอร์อย่าง Change-Id ถูกรวมอยู่ใน git เอง เครื่องมือต่าง ๆ ก็น่าจะเข้าใจมันได้ดีขึ้น การแยกแยะ commit ด้วยข้อความ commit นั้นเปราะบางแบบละเอียดอ่อน ส่วน commit id แม้จะดีเรื่องความเป็นเอกลักษณ์ แต่เมื่อย้ายการเปลี่ยนแปลงเดิมไปอยู่บน commit อื่นก็มีประโยชน์ด้านการระบุตัวตนน้อยลง แก้ไขเพิ่มเติม: trailers เป็นส่วนหนึ่งของ commit จึงไม่สามารถแทน notes ได้ทั้งหมด
เพิ่งรู้ว่า GitHub ช่วงหลังใช้ trailer แยกต่างหากแทน [skip ci] น่าจะเพื่อให้แยกออกจากข้อความ commit ได้ง่ายขึ้น ไม่แน่ใจว่าทำไม GitHub ถึงบังคับให้ใช้เฉพาะ trailer ตัวสุดท้าย คาดว่าอาจเป็นเพราะการประมวลผลด้วย regular expression ลิงก์เอกสารที่เกี่ยวข้อง
เพิ่งรู้จักฟีเจอร์ trailers เป็นครั้งแรก ในฐานะแฟนของ Conventional Commits รู้สึกว่า trailers น่าจะเหมาะกว่าสำหรับเพิ่มเมทาดาทาแบบนี้ และสงสัยว่าการเพิ่มด้วยมือในข้อความ commit กับการใช้แฟลก --trailer ให้ผลเหมือนกันในเชิงฟังก์ชันหรือไม่
โดยธรรมชาติแล้วอยากเชื่อมกับระบบ issue tracking แต่การใส่ข้อมูลนั้นไว้ในที่อย่าง trailer ดูไม่มีประสิทธิภาพเพราะห่างจากตัว issue tracker มากเกินไป issue tracker มักวิ่งตามเทรนด์และเพิ่มฟีเจอร์หลายอย่างช้า กฎที่บังคับให้ใช้ชื่อ branch ที่มาจากชื่อตั๋วเป็นชื่อ PR เสมอนั้นน่ารำคาญ อยากเชื่อม commit กับ issue ผ่านเมทาดาทาอื่นเพื่อให้ชื่อ PR มีความหมายมากขึ้น แต่ก็ไม่ใช่ปัญหาที่แก้ได้ง่าย เลยเป็นเรื่องที่ได้แต่บ่นบนอินเทอร์เน็ต
มีการแชร์ข้อมูลว่า Forgejo เริ่มรองรับ trailers ตั้งแต่เวอร์ชัน 10 ที่ออกในเดือนมกราคมปีนี้ release notes pull request
สงสัยเกี่ยวกับการทำงานร่วมกันระหว่าง git notes กับการเขียนประวัติใหม่ เช่น amend, rebase เป็นต้น เพราะ notes ผูกกับ commit/tree/blob ID จึงสงสัยว่าเมื่อถูกแทนที่ด้วย commit ใหม่ notes จะถูกคัดลอกตามไปหรือหายไป และถ้ารวมหลาย commit ด้วย interactive rebase จะเกิดอะไรขึ้น อีกทั้งยังแชร์มุมมองว่าการที่ notes ผูกกับ "เนื้อหา" ของไฟล์/ไดเรกทอรีนั้นต่างจากที่คาดไว้ เช่น ถ้าแนบ note กับ blob ของสตริง "Hello world!" จะหมายความว่าไฟล์ทุกไฟล์ที่มีเนื้อหาเดียวกันจะมี note นั้นด้วยหรือไม่ และถ้าไฟล์ถูกแก้ไขจะเสีย notes ไปหรือไม่
ที่ทำงานปัจจุบันมีการใช้ git notes อย่างจริงจัง โดยมีเป้าหมายเพื่อเก็บบันทึกการรีวิวโค้ดภายในโดยไม่ทำให้ข้อความ commit ซับซ้อนหรือไม่ต้องสร้าง PR สำหรับทุกการเปลี่ยนแปลง แต่ละ commit จะเก็บบริบทไว้ในสาขา เช่น แมปกับ ticket ไหน มีข้อจำกัดด้านโครงสร้างพื้นฐานอะไร หรือถ้าเป็นการแก้ไขก็ใส่ลิงก์ไปยัง incident thread ข้อมูลนี้ถูกเก็บใน repo ทำให้เข้าใจได้ง่ายว่าทำไมโค้ดบรรทัดนั้นถึงถูกเปลี่ยนโดยไม่ต้องไปค้นใน slack หรือ jira มองว่าถ้าใช้ในวงกว้างจะลดความจำเป็นของ platform UI ได้อย่างชัดเจน และเห็นว่า reproducibility ไม่ได้จำเป็นแค่กับ build แต่รวมถึง ‘intent’ ด้วย
มองว่า git notes มีประโยชน์จริงก็ต่อเมื่อจำเป็นต้องเพิ่มข้อมูลหลังจาก commit ไปแล้วเท่านั้น ตัวอย่างอย่าง Acked-By หรือลิงก์การอภิปรายใน mailing list เป็นข้อมูลที่รู้อยู่แล้วตอน commit จึงควรใส่ในข้อความ commit ได้เลย ตรงกันข้าม จุดเด่นจริงของ git note คือการใส่คำอธิบายเพิ่มเติมภายหลัง เช่น ให้กับ commit ที่ถูก revert ในภายหลัง
บ่อยครั้งข้อความ commit ชอบประกาศว่าซ่อมบั๊กแล้ว ทั้งที่จริงยังไม่ซ่อม และทำให้เกิดบั๊กต่อเนื่องเป็นลูกโซ่ อีกทั้งเพื่อนร่วมงานก็มักมองข้ามเจตนาเดิมของผู้เขียนและปล่อยผ่านแบบลวก ๆ หลังเจอลูกค้าที่ไม่พอใจกับกรณีบั๊กกลับมาเกิดซ้ำ ก็รู้สึกว่าควรระมัดระวังมากขึ้นกับคำว่า bug fix บางครั้งการเปลี่ยนแปลงครั้งเดียวก็แก้ได้หลายบั๊ก หรือเปิดโอกาสให้รีแฟกเตอร์เพื่อเพิ่มประสิทธิภาพหรือรองรับฟีเจอร์ใหม่ด้วย
Acked-By, การรีวิว, การอภิปราย มักจะดำเนินต่อหลัง commit อยู่แล้ว จึงยังไม่รู้ในตอนที่ commit เสร็จ ส่วนกรณี revert commit นั้นกลับมีประโยชน์กว่าถ้าเพิ่มไว้ในข้อความ commit เพราะฟังก์ชัน blame แสดงการเปลี่ยนแปลงล่าสุดอยู่แล้ว จึงติดตาม commit ที่ถูก revert ได้โดยธรรมชาติ
หลายครั้งการอภิปรายก็ยังดำเนินต่อหลัง commit
คิดว่านี่เป็นจุดที่น่าสนใจในการลองสำรวจฟีเจอร์ notes เพื่อใช้เป็นบริบทเพิ่มเติมให้กับ code agent
นี่ไม่ใช่ปัญหาความรู้ แต่เป็นปัญหา UI ถ้า GitHub แสดง notes ได้ดี คนก็น่าจะใช้มากขึ้นทันที
ใน git ยังมีฟีเจอร์ประเภท ‘เจ๋งที่สุดแต่ไม่ค่อยมีใครรัก’ อีกมาก เช่น bisect, pickaxe, reflog, range-diff, archive, annotated tags แต่คนส่วนใหญ่มองมันเหมือน Google Drive เลยไม่ค่อยได้ใช้
รู้สึกว่า git notes ซ้ำซ้อนอยู่ดี เพราะยังไงก็ตามต้องใช้เครื่องมือจัดการโปรเจกต์แยกต่างหากอยู่แล้ว เช่น Jira เพื่อติดตาม feature, roadmap และบริบทที่ไม่ใช่เชิงเทคนิค ตามปรัชญา Unix แต่ละเครื่องมือก็ควรโฟกัสหน้าที่ของตัวเอง
เพิ่งเคยได้ยินฟีเจอร์ pickaxe เป็นครั้งแรก ถือว่าคาดไม่ถึง และทำให้รู้สึกว่าไม่ควรมั่นใจตัวเองมากเกินไป
ฟีเจอร์แนวประดับพวกนี้ในหลายกรณีก็ไม่ได้มีประโยชน์มากนัก มองว่าเป็นเทคนิคยิบย่อยที่วนรอบแก่นหลัก
มีความเห็นว่า git notes ไม่ได้เป็น unloved feature ที่ ‘เจ๋ง’ จริง ๆ แต่มีประโยชน์เฉพาะในสถานการณ์ที่จำกัดมากเท่านั้น การใส่ข้อมูลที่จำเป็นทั้งหมดไว้ในข้อความ commit แล้วให้ระบบอื่นอย่าง JIRA มาอ้างอิงกลับเป็นข้อดีมากกว่า ระบบอย่าง JIRA ยังทำหน้าที่เป็นช่องทางสื่อสารกับคนที่ไม่ใช่นักพัฒนา เช่น นักวิเคราะห์ธุรกิจหรือฝ่ายซัพพอร์ต และก็สมเหตุสมผลที่คนที่ไม่ใช่นักพัฒนาจะไม่มีสิทธิ์เข้าถึง repo หรือโค้ด ในสถานการณ์ที่ต้องดูแลหลาย service/หลาย repo พร้อมกัน การอ้างอิง feature ผ่าน notes แบบนี้แทบเป็นไปไม่ได้ในทางปฏิบัติ จึงต้องเชื่อมกับระบบภายนอก
รู้จัก notes ครั้งแรกผ่าน man page ราวปี 2020 โดยพื้นฐานแล้ว notes ใช้กับ local repo เท่านั้น จึงยังไม่เคยมีประสบการณ์ใช้งานจริง การจะใช้ในระดับทีมต้องตกลงกันเรื่องการตั้งค่า pushing/fetching แยกต่างหาก แต่ทีมของตนไม่ได้เลือกแนวทางนั้น