89 คะแนน โดย GN⁺ 21 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อเจอโค้ดเบสใหม่ ให้ใช้ การวิเคราะห์ประวัติ Git เพื่อทำความเข้าใจโครงสร้างของโปรเจกต์และจุดเสี่ยง เพื่อกำหนดทิศทางการสำรวจอย่างมีประสิทธิภาพ
  • ค้นหา ไฟล์ที่ถูกเปลี่ยนบ่อยที่สุด ในช่วง 1 ปีที่ผ่านมา แล้ววิเคราะห์ไขว้กับความหนาแน่นของบั๊กเพื่อระบุ โค้ดความเสี่ยงสูง
  • ใช้ การกระจายตัวของผู้มีส่วนร่วมและแนวโน้มกิจกรรม เพื่อตรวจสอบ bus factor, ช่องว่างด้านการบำรุงรักษา และความเป็นไปได้ของการขาดตอนขององค์ความรู้
  • ติดตาม การเปลี่ยนแปลงของความเร็วและแรงขับในการพัฒนา ของทีมจากจำนวนคอมมิตรายเดือน และประเมิน เสถียรภาพของการปล่อยใช้งาน จากความถี่ของ Revert และ Hotfix
  • คำสั่งทั้งห้านี้เป็น เครื่องมือเชิงปฏิบัติที่ช่วยวินิจฉัยสุขภาพของโปรเจกต์ได้อย่างรวดเร็ว ก่อนเปิดอ่านโค้ดแม้แต่บรรทัดเดียว

คำสั่ง Git ห้าข้อที่ควรรันก่อนอ่านโค้ด

  • เมื่อวิเคราะห์โค้ดเบสใหม่ แนวทางนี้คือ วินิจฉัยสุขภาพของโปรเจกต์จากประวัติ Git ก่อนเปิดไฟล์
    • ดูจากประวัติคอมมิตเพื่อเข้าใจว่า ใครเป็นคนสร้าง, ปัญหากระจุกอยู่ตรงไหน, และ ทีมปล่อยงานได้เสถียรแค่ไหน
  • อะไรถูกเปลี่ยนบ่อยที่สุด

    • คำสั่ง:
      git log --format=format: --name-only --since="1 year ago" | sort | uniq -c | sort -nr | head -20
      
    • แสดง 20 ไฟล์ที่ถูกแก้ไขมากที่สุดในช่วง 1 ปีที่ผ่านมา
    • ไฟล์อันดับต้น ๆ มักเป็นไฟล์ที่ทีม “ไม่กล้าแตะ” และเมื่อ ความถี่ในการเปลี่ยนแปลงสูง (churn) รวมกับ การหลีกเลี่ยงความเป็นเจ้าของ ก็จะกลายเป็นภาระที่ใหญ่ที่สุดของโค้ดเบส
    • งานวิจัยของ Microsoft Research (2005) ระบุว่า ตัวชี้วัดที่อิงจากความถี่ในการเปลี่ยนแปลงมีพลังในการคาดการณ์ข้อบกพร่องสูงกว่าตัวชี้วัดด้านความซับซ้อน
    • ให้นำ 5 ไฟล์อันดับแรกไปวิเคราะห์ไขว้กับคำสั่งดูความหนาแน่นของบั๊ก เพื่อระบุ ไฟล์ที่เปลี่ยนบ่อยและมีบั๊กบ่อย ว่าเป็นจุดเสี่ยงสูงสุด
  • ใครเป็นคนสร้างโค้ดนี้

    • คำสั่ง:
      git shortlog -sn --no-merges
      
    • จัดอันดับผู้มีส่วนร่วมตามจำนวนคอมมิต
    • ถ้าคนคนเดียวมีสัดส่วนเกิน 60% แสดงว่ามีความเสี่ยงด้าน bus factor
    • ถ้าผู้มีส่วนร่วมอันดับต้น ๆ ไม่มีความเคลื่อนไหวในช่วง 6 เดือนที่ผ่านมา อาจมี ช่องว่างด้านการบำรุงรักษา
    • หากมีผู้มีส่วนร่วม 30 คน แต่ในรอบ 1 ปีที่ผ่านมามีเพียง 3 คนที่ยังเคลื่อนไหวอยู่ อาจเกิด การขาดตอนขององค์ความรู้จากการเปลี่ยนตัวนักพัฒนา
    • แต่ถ้าทีมใช้กลยุทธ์ squash-merge ข้อมูลผู้เขียนอาจบิดเบือนไปทางผู้ที่ทำการ merge เป็นหลัก จึง ควรตรวจสอบกลยุทธ์การ merge ด้วย
  • บั๊กกระจุกอยู่ตรงไหน

    • คำสั่ง:
      git log -i -E --grep="fix|bug|broken" --name-only --format='' | sort | uniq -c | sort -nr | head -20
      
    • ดึง 20 อันดับไฟล์ที่เกี่ยวข้องกับบั๊กมากที่สุด โดยอิงจากคอมมิตที่มีคีย์เวิร์ดเกี่ยวกับบั๊ก
    • นำรายการนี้ไปเทียบกับรายการความถี่ในการเปลี่ยนแปลง เพื่อระบุ ไฟล์ที่แก้บ่อยและพังบ่อย ว่าเป็นโค้ดความเสี่ยงสูง
    • แม้ความแม่นยำของผลลัพธ์จะขึ้นกับคุณภาพของข้อความคอมมิต แต่แค่ใช้เป็น แผนที่ความหนาแน่นของบั๊กแบบคร่าว ๆ ก็มีประโยชน์มากแล้ว
  • โปรเจกต์กำลังเร่งความเร็วหรือกำลังชะงัก

    • คำสั่ง:
      git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c
      
    • ใช้จำนวนคอมมิตรายเดือนเพื่อ มองแนวโน้มกิจกรรมได้อย่างชัดเจน
    • จังหวะที่สม่ำเสมอหมายถึงโปรเจกต์ที่มีสุขภาพดี
    • ถ้าจำนวนคอมมิตลดลงครึ่งหนึ่งภายในเดือนเดียว อาจหมายถึง การสูญเสียกำลังหลักของทีม
    • หากลดลงต่อเนื่อง 6–12 เดือน แปลได้ว่า แรงขับของทีมกำลังถดถอย ขณะที่รูปแบบพุ่งขึ้นเป็นช่วง ๆ แล้วนิ่งอาจบ่งชี้ถึง รูปแบบการปล่อยงานแบบเป็นรอบใหญ่
    • มีกรณีจริงที่ CTO มองกราฟความเร็วของคอมมิตแล้วนึกออกว่า “นั่นคือช่วงที่วิศวกรอาวุโสลาออก”
    • ข้อมูลนี้จึงมีความหมายในฐานะ ข้อมูลของทีม ไม่ใช่แค่ข้อมูลของโค้ด
  • ทีมต้องรับมือเหตุฉุกเฉินบ่อยแค่ไหน

    • คำสั่ง:
      git log --oneline --since="1 year ago" | grep -iE 'revert|hotfix|emergency|rollback'
      
    • ใช้วัด ความถี่ของ Revert และ Hotfix
    • เกิดไม่กี่ครั้งต่อปีถือว่าปกติ แต่ถ้าเกิดทุก 2 สัปดาห์ นั่นเป็นสัญญาณของ ความไม่น่าเชื่อถือในกระบวนการปล่อยใช้งาน
    • นี่อาจเป็นสัญญาณของปัญหาที่ลึกกว่านั้น เช่น การทดสอบที่ไม่นิ่ง, การไม่มี staging, หรือขั้นตอน rollback ที่ซับซ้อน
    • ถ้าผลลัพธ์เป็น 0 อาจแปลว่าทีมมีเสถียรภาพ หรือไม่ก็ข้อความคอมมิตไม่แม่นยำ
    • รูปแบบของภาวะวิกฤตจะปรากฏชัดเจน และเพียงแค่มีหรือไม่มีก็ใช้ตัดสินระดับความน่าเชื่อถือได้แล้ว

บทสรุป

  • คำสั่งทั้งห้านี้รันได้ในเวลาไม่กี่นาที และช่วยชี้ทางว่า ควรเริ่มอ่านจากตรงไหน ก่อนเปิดดูโค้ดแม้แต่บรรทัดเดียว
  • ทำให้วันแรกไม่ต้องสำรวจแบบไร้ทิศทาง แต่สามารถ วิเคราะห์โค้ดอย่างเป็นระบบโดยยึดพื้นที่ปัญหาเป็นศูนย์กลาง
  • ขั้นตอนนี้เปรียบได้กับ ชั่วโมงแรกของการตรวจสอบโค้ดเบส (codebase audit) ก่อนจะต่อยอดไปสู่การวิเคราะห์ตลอดสัปดาห์หลังจากนั้น

1 ความคิดเห็น

 
GN⁺ 21 일 전
ความคิดเห็นใน Hacker News
  • มีการแชร์ตัวอย่างใน Jujutsu ที่ใช้แทนคำสั่งวิเคราะห์ของ git ได้
    สามารถใช้คำสั่ง jj log เพื่อตรวจดูไฟล์ที่เปลี่ยนบ่อยที่สุดในช่วง 1 ปีที่ผ่านมา, ผู้มีส่วนร่วมหลัก, จุดที่บั๊กกระจุกตัว, ความมีชีวิตชีวาของโปรเจ็กต์, ความถี่ของการแก้ด่วน เป็นต้น
    ไวยากรณ์จะ ใกล้เคียงการเขียนโปรแกรมมากกว่าสคริปต์เชลล์ แต่มีแฟลกที่ต้องจำไม่มาก

    • สำหรับฉัน jujutsu ดูเหมือน Nix ของระบบควบคุมเวอร์ชัน
      Nix เท่ก็จริงแต่เพิ่มความซับซ้อน และ jujutsu ก็ให้ความรู้สึกแบบนั้น
      ลองใช้ไปไม่กี่เดือนแล้วก็กลับไปใช้ git เพราะคุ้นมือและใช้ได้ทุกที่
    • ไม่เข้าใจเลยว่าคนเราจำ ภาษาเขียนสคริปต์เฉพาะทาง พวกนี้กันได้ยังไง
      แค่จำลูปอาร์เรย์ของ jq ได้ก็ดีใจแล้ว แต่ไวยากรณ์แบบนี้จับทางไม่ถูกจริงๆ
    • ทั้งคำสั่ง jj และ git ยาวและซับซ้อนเกินกว่าจะคิดจำ
      ถ้าต้องใช้บ่อยก็จะ ย่อด้วย alias เอา
    • การไม่มีคอมมิตไม่ได้แปลว่าโปรเจ็กต์ตาย แต่อาจหมายถึงมัน เสถียร ก็ได้
      ตัวอย่างเช่นมีไลบรารีสร้าง QR code ตัวหนึ่งที่ไม่อัปเดตมา 10 ปีแล้วแต่ยังทำงานได้สมบูรณ์
      บางทีก็แอบคิดว่าควรให้บอตเพิ่มคอมมิตไร้ประโยชน์เข้าไปไหม
    • ไม่อยากเขียนโปรแกรมให้ git แค่อยาก ทำงานให้เสร็จ
      เลยชอบ คำสั่ง UNIX แบบ pipe ดั้งเดิมมากกว่าเครื่องมืออย่าง jujutsu
      เหตุผลที่ใช้ Maven แทน Gradle ก็อยู่ในบริบทเดียวกัน
  • น่าสนใจที่ผู้เขียนสมมติว่านักพัฒนาเขียนข้อความคอมมิตกันดี
    ความจริงส่วนใหญ่ก็ระดับ “changed stuff” เท่านั้น
    คนที่ให้ความสำคัญกับ commit log แบบฉันมีน้อยมาก
    ข้อความคอมมิตที่ AI สร้าง น่าจะช่วยปัญหานี้ได้มาก

    • นี่เป็น ปัญหาเรื่องภาวะผู้นำ ทีมลีดหรือ CTO ที่ดีจะกำหนดความคาดหวังเรื่องคุณภาพของข้อความคอมมิตให้ชัดเจน
    • ในทีมที่ merge แบบ squash, เนื้อหา PR จะกลายเป็นข้อความคอมมิต จึงมักมีคุณภาพดีกว่า
    • ใน workflow แบบ squash & merge สุดท้ายแล้ว ชื่อ PR คือข้อความสำคัญหลัก
      นักพัฒนาจะเขียนข้อความคอมมิตยังไงก็ได้ เพราะสุดท้ายไม่มีใครอ่านอยู่ดี
    • ทีมเราจะแยก repo หลัก กับ repo ที่ไม่ใช่แกนหลัก
      ฝั่ง Core ต้องมี PR review และคำอธิบายละเอียด ส่วน Non-Core เปิดให้ทดลองได้อิสระ
      ใน Core บางทีข้อความคอมมิตยาวกว่าโค้ด 20 เท่า ส่วน Non-Core ก็ระดับ “hope this works”
    • ที่นักพัฒนาไม่เขียนข้อความคอมมิตดีๆ เป็น ปัญหาเรื่องวัฒนธรรม
      บริษัทเราคาดหวังเรื่องนี้จากกันและกัน
  • ลองรันคำสั่งกับหลาย codebase แล้วพบว่าผลลัพธ์ไม่ตรงกับความเป็นจริง
    ตัวอย่างเช่นในผลของ git shortlog -sn --no-merges คนที่มีคอมมิตมากที่สุดอาจลาออกไปแล้วก็ได้
    การมีคอมมิตเยอะไม่ได้แปลว่า มีส่วนร่วมสูง

    • เพราะแบบนี้ฉันเลยชอบ squash-and-merge
      เก็บคอมมิตยิบย่อยไว้แค่ใน feature branch แล้วค่อย merge เข้า main แบบสะอาดๆ
    • คำสั่งพวกนี้มีประโยชน์ตอน วินิจฉัยโปรเจ็กต์ที่มีปัญหา
      แต่กับ codebase ทั่วไปก็มักได้ผลลัพธ์ที่ไม่มีความหมายมากนัก
    • พูดตรงๆ ก็สงสัยว่าผู้เขียนได้ลองรันคำสั่งจริงไหม เพราะมันเหมือน บทความที่ LLM เขียน
    • ถ้า workflow อัตโนมัติใช้ credentials ของคนคนเดียว สถิติก็อาจบิดเบือน
    • ฉันเองก็มีจำนวนคอมมิตทิ้งห่างมากใน codebase กลางของบริษัทหนึ่ง
      เพราะเป็นคนเริ่มโปรเจ็กต์ตั้งแต่ต้น แต่ตอนนี้คนอื่นคอมมิตบ่อยกว่าฉันแล้ว
  • ประโยคที่ว่า “ไฟล์ที่ถูกเปลี่ยนมากที่สุดคือไฟล์ที่คนกลัวจะแก้” น่าสนใจดี

    • มันเหมือนความย้อนแย้งแบบ “ร้านอาหารที่แน่นจนไม่มีใครไป”
    • พอลองทดสอบดู ไฟล์ที่แก้บ่อยที่สุดกลับเป็น ไฟล์ที่สร้างอัตโนมัติ หรือไฟล์ทางเข้าโปรแกรมที่น่าเบื่อ
    • คำสั่งแบบนี้ ควรมีคำเตือนกำกับ
      ถ้าสรุปจากผลที่รันได้ตรงๆ เลย อาจดูงี่เง่ามากกว่า
      ในความเป็นจริงมันแค่บอกว่าช่วงปีที่ผ่านมาไปทำฟีเจอร์อะไรบ้าง
    • ถ้าดูทั้ง Churn (ความถี่ในการเปลี่ยนแปลง) และ Complexity (ความซับซ้อน) พร้อมกันจะมีประโยชน์กว่ามาก
      จุดที่ทั้งสองค่าสูงคือโซนปัญหาจริง
      ถ้าโซนแบบนี้สะสมไปเรื่อยๆ ก็จะเริ่มมีคนพูดว่า “แอปนี้ควรเขียนใหม่ตั้งแต่ต้น”
    • ไฟล์ที่คนกลัวคือไฟล์ที่ จำเป็นและซับซ้อนในเวลาเดียวกัน
      ทุกคนต้องแก้ แต่ใหญ่เกินกว่าจะรับมือได้ง่าย
  • ฉันทำ summary alias ให้ git เพื่อสรุป branch, จำนวนคอมมิต, จำนวนผู้เขียน, จำนวนไฟล์ ฯลฯ ในครั้งเดียว
    ได้ไอเดียมาจาก GitAlias/gitalias

    • สงสัยว่าทำไมถึงเขียนเป็นฟังก์ชันใน .gitconfig ทั้งที่ทำเป็น สคริปต์ git-summary น่าจะง่ายกว่า
    • การพิมพ์คำสั่งพวกนี้เองทุกครั้งก็ดูเหมือน บทความที่ AI เขียน เพราะคนที่ชำนาญจริงมักทำ alias ไว้ใช้ซ้ำ
    • สคริปต์ดูดี แต่ในสภาพแวดล้อมของฉันไม่มีคำสั่งอย่าง log-of-count-and-email
    • น่าจะดีถ้าทำ man page ไว้ในเครื่องด้วย
  • ควรเพิ่ม ขอบเขตคำ (\b) ใน regex
    เช่นคำว่า “bug” ใน “debugger” อาจทำให้ได้ผลลัพธ์ผิดพลาด
    ตัวอย่างที่แก้แล้วเป็นดังนี้
    git log -i -E --grep="\b(fix|fixed|fixes|bug|broken)\b" ...

    • บน macOS ไม่รองรับ \b จึงควรใช้ ตัวเลือก regex แบบ Perl คือ -P แทน -E
      สามารถแก้เป็นรูปแบบ git log -i -P --grep="\b(...)\b"
    • ที่ทีมเราก็ใช้คำว่า “rollback” ในอีกความหมายหนึ่ง เลยต้องกรองเหมือนกัน
    • ทักได้ดีเลย แบบนี้แม่นขึ้นมาก
  • ถ้าไม่ทำ squash-merge คนที่มีคอมมิตเยอะอาจเป็น นักพัฒนาที่แย่ที่สุด ก็ได้
    เคยมีคนแบบนั้นอยู่คนหนึ่ง แก้ไฟล์เดิมซ้ำไปซ้ำมาจนสุดท้ายก็โดนไล่ออก
    squash เป็นวิธีที่ช่วยกลบปัญหาแบบนี้ได้ดี

  • สถิติจำนวนคอมมิตแบบง่ายๆ ไม่น่าเชื่อถือ
    บางคนคอมมิตเฉพาะโค้ดที่ผ่านการทดสอบอย่างสมบูรณ์ บางคนคอมมิตทีละบรรทัดบ่อยๆ
    มูลค่าของหนึ่งคอมมิตต่างกันได้ถึง 100 เท่าระหว่างแต่ละคน

    • แต่จุดประสงค์ของผู้เขียนคือการดู แนวโน้มการเปลี่ยนแปลง
      อัตราการเปลี่ยนสำคัญกว่าค่าสัมบูรณ์
  • แนวทางการวิเคราะห์แบบนี้ทำให้นึกถึง “Your Code as a Crime Scene” ของ Adam Tornhill
    ลิงก์ต้นฉบับ
    และยังคล้ายกับแนวคิด Developer’s Legacy Index ด้วย

    • ชอบบทความยุคแรกๆ ของ Tornhill ที่เกี่ยวกับ C มาก ดีใจที่มีคนพูดถึง
  • ถ้าผู้เขียนแสดงผลลัพธ์ของแต่ละคำสั่งให้ดูโดยตรงก็น่าจะดีกว่านี้
    ตัวอย่าง output น่าจะโน้มน้าวได้มากกว่าคำอธิบาย

    • ฉันก็รู้สึกว่าบทความมีกลิ่น AI เขียน นิดๆ แต่ก็ยังได้เรียนรู้ 5 คำสั่งอยู่ดี ก็ไม่เลวนะ