7 คะแนน โดย GN⁺ 2024-10-28 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • JavaScript monorepo ขนาดใหญ่ของ Microsoft อย่าง 1JS เติบโตจนมีผู้ใช้ที่ใช้งานต่อเดือน 1,000 คน แพ็กเกจราว 2,500 แพ็กเกจ และโค้ดราว 20 ล้านบรรทัด โดยล่าสุดขนาดตอน clone พุ่งไปถึง 178GB จนทำให้นักพัฒนาบางคน clone ได้ยากตั้งแต่ต้น
  • คอขวดที่พบในช่วงแรกคือโครงสร้างที่ไฟล์เปลี่ยนแปลงของ Beachball สะสมอยู่ในโฟลเดอร์เดียวเป็นหลักหมื่นไฟล์ และเมื่อเพิ่มถึง 40,000 ไฟล์ ก็ทำให้ทุกครั้งที่เพิ่มไฟล์ใหม่จะเกิด tree object ขนาดใหญ่
  • สาเหตุที่ใหญ่กว่าคือ Git packing code แบบเดิมเลือกเป้าหมายสำหรับ delta โดยดูแค่ 16 อักขระท้ายสุด ของชื่อไฟล์ ทำให้เกิดปัญหาเมื่อมีการอัปเดตซ้ำ ๆ กับชื่อไฟล์ยาวอย่าง CHANGELOG.md และ CHANGELOG.json
  • git repack -adf --window=250 ช่วยได้ระดับหนึ่ง แต่เมื่อรัน git repack -adf --path-walk บน Microsoft Git fork 2.47.0.vfs.0.2 ซึ่งเป็นการแพ็กแบบอิงเส้นทาง ก็ทำให้ repository ในเครื่องลดจาก 178GB เหลือ 5GB
  • หากใน monorepo ขนาดใหญ่มีไฟล์ชื่อยาวที่เปลี่ยนบ่อย ก็ควรตรวจสอบ pack.usePathWalk true และคำสั่งใหม่ git survey โดยการเปลี่ยนแปลงที่เกี่ยวข้องมีแผนจะถูกรวมเข้า Git upstream ด้วย

ขนาดและคอขวดของ 1JS monorepo

  • 1JS ซึ่งเป็น JavaScript monorepo ขนาดใหญ่ภายใน Microsoft มีทั้งขนาด repository ขนาดโค้ด และขนาดการมีส่วนร่วมที่ใหญ่มาก
    • ผู้ใช้ที่ใช้งานต่อเดือนมากกว่า 1,000 คน
    • ราว 2,500 แพ็กเกจ
    • โค้ดราว 20 ล้านบรรทัด
  • ขนาด repository ที่ clone มาใหม่ล่าสุดอยู่ที่ 178GB และนักพัฒนาบางคนในยุโรปไม่สามารถ clone repository ได้เพราะขนาดใหญ่เกินไป
  • ตอน clone ครั้งแรกมีขนาดเพียงราว 1–2GB แต่ไม่กี่เดือนต่อมาก็โตเป็นประมาณ 4GB และยังเพิ่มขึ้นต่อเนื่องหลังจากนั้น

บทเรียน #1: อย่าสะสมไฟล์หลายพันไฟล์ไว้ในโฟลเดอร์เดียว

  • git-sizer ช่วยให้เห็นปัญหา blob ขนาดใหญ่และไฟล์เปลี่ยนแปลงของ Beachball
  • blob ขนาดใหญ่มักเกิดจากการ commit ไฟล์ไบนารีเข้าไปโดยไม่ตั้งใจ และสามารถป้องกันได้ด้วยความสามารถอย่างการจำกัดขนาด check-in ของ Azure DevOps
    • แต่ไฟล์ที่เข้าไปอยู่ใน history แล้วจะลบออกภายหลังได้ไม่ง่าย
  • 1JS ใช้ Beachball change files เพื่อทำให้การเพิ่มช่วง semver ของแพ็กเกจเป็นแบบอัตโนมัติ
    • จุดประสงค์การใช้งานคล้ายกับ Changesets
    • เป้าหมายคือทำให้การเพิ่มเวอร์ชันแพ็กเกจเป็นอัตโนมัติเหมือน semantic-release
  • เนื่องจากไม่มีการลบไฟล์เปลี่ยนแปลง ทำให้มีไฟล์สะสมอยู่ในโฟลเดอร์เดียวมากถึง 40,000 ไฟล์ และเมื่อเพิ่มไฟล์ใหม่ในสภาพนี้ก็จะสร้าง tree object ขนาดใหญ่
  • แนวทางรับมือมี 2 ข้อ
    • แก้ Beachball PR ให้เก็บหลายการเปลี่ยนแปลงไว้ในไฟล์เปลี่ยนแปลงเดียว แทนการมีหนึ่งไฟล์ต่อหนึ่งแพ็กเกจ
    • เขียน pipeline สำหรับจัดระเบียบโฟลเดอร์ไฟล์เปลี่ยนแปลงแบบอัตโนมัติเป็นระยะ

บทเรียน #2: ปัญหา versioned branch และการแพ็ก changelog

  • flow การจัดการเวอร์ชันของ 1JS จะคง branch versioned ที่เป็น mirror ของ main เอาไว้
    • เพื่อเก็บเวอร์ชันแพ็กเกจจริงและหลีกเลี่ยง Git conflict บน main
    • เพื่อให้เห็นความสัมพันธ์ระหว่างเวอร์ชัน semver ที่ปล่อยเป็น NPM package กับ Git commit ได้อย่างแม่นยำ
  • branch versioned มี commit ที่ส่วนใหญ่เป็นแค่การเติมเนื้อหาในไฟล์ CHANGELOG.md และ CHANGELOG.json แต่กลับโตขึ้นจนการ clone ทำได้ยากขึ้นเรื่อย ๆ
  • แม้ repository จะโตขึ้นตามธรรมชาติจากการเพิ่มโค้ดหลายแสนบรรทัดต่อปีและนักพัฒนาหลายร้อยคนตั้งแต่ปี 2021 แต่เมื่ออัตราการเติบโตสูงกว่า monorepo ของ Office ภายใน Microsoft ก็เริ่มสงสัยว่ามีสาเหตุเฉพาะอื่นอยู่
  • เมื่อนักพัฒนาที่สร้างฟีเจอร์สำหรับ monorepo ขนาดใหญ่ของ Git อย่าง shallow checkout และ sparse index เข้ามาตรวจสอบ ก็พบว่าเวลานำ branch versioned มาใช้งานมีการ fetch ข้อมูล Git เพิ่มอีก 125GB

วิธีที่ Git packing code สร้าง delta ผิดเป้าหมาย

  • สาเหตุมาจาก Git packing code รุ่นเก่าที่เวลาบีบอัดไฟล์จะตรวจดูแค่ 16 อักขระท้ายสุด ของชื่อไฟล์เพื่อหาคู่เปรียบเทียบ
  • โดยปกติ Git จะ push แค่ diff ของไฟล์ที่เปลี่ยนแปลง แต่ปัญหาการแพ็กนี้ทำให้เกิดการเปรียบเทียบกันระหว่างไฟล์ CHANGELOG.md ของคนละแพ็กเกจ
  • ตัวอย่างเช่นเมื่อแก้ repo/packages/foo/CHANGELOG.json Git อาจสร้าง diff กับ repo/packages/bar/CHANGELOG.json ในขั้นตอนเตรียม push
  • ผลคือในหลายกรณีต้อง push ทั้งไฟล์เดิมซ้ำแล้วซ้ำอีก และบางไฟล์อาจมีขนาดหลายสิบ MB
  • รายละเอียดเชิงลึกของปัญหาถูกรวบรวมไว้ใน โพสต์บน Git mailing list ของ Stolee

ผลลัพธ์ของ repack และ path-walk

  • ขั้นแรกมีการใช้ git repack -adf --window=250 เพื่อขยายหน้าต่างการเปรียบเทียบและปรับปรุงการบีบอัดของ pack file ซึ่งช่วยลดขนาด repository ลงได้มาก
  • จากนั้น git-for-windows PR #5171 ก็เพิ่ม วิธีแพ็กที่เดินตาม Git path แทนวิธีเดิมที่เดินตาม commit
  • มีการ clone ใหม่แล้วรัน repack ด้วยวิธีใหม่บน Microsoft git git version 2.47.0.vfs.0.2 ซึ่งเป็น Git fork ของ Microsoft
    • คำสั่งที่ใช้: git repack -adf --path-walk
    • ผลลัพธ์: ขนาด repository ลดจาก 178GB เหลือ 5GB
  • ตัวเลือกการตั้งค่าใหม่นี้ยังช่วยให้ตอน push สร้าง delta ได้ถูกต้องด้วย
    • git config --global pack.usePathWalk true
  • นักพัฒนาที่ใช้ git version 2.47.0.vfs.0.2 สามารถรัน repack หลัง clone ลงเครื่อง และใช้อัลกอริทึม push แบบ path-walk ใหม่เพื่อลดอัตราการโตของ repository ได้

ผลกระทบต่อ GitHub, Azure DevOps และ upstream Git

  • GitHub มีการทำ repack และ Git garbage collection เป็นระยะ แต่ปัจจุบันวิธีแพ็กของ GitHub ยังไม่สามารถคำนวณ delta ของไฟล์อย่าง CHANGELOG.md และ CHANGELOG.json ได้อย่างถูกต้อง
  • กรณีชื่อไฟล์ยาวที่มีตัวอักษรท้ายเหมือนกันเกิน 16 ตัว และถูกแก้ไขบ่อยตามกาลเวลา ก็อาจได้รับผลกระทบเช่นกัน
    • มีการยกตัวอย่างเป็นไฟล์สตริงขนาดใหญ่สำหรับ i18n
  • Azure DevOps ที่ 1JS ใช้อยู่ยังไม่ได้ทำ repack แบบนี้ และกำลังดำเนินงานที่เกี่ยวข้องเพื่อช่วยลดขนาด repository ฝั่งเซิร์ฟเวอร์ด้วย
  • การเปลี่ยนแปลงที่เกี่ยวข้องมีแผนจะถูกส่งกลับเข้า Git upstream

สิ่งที่ควรตรวจสอบใน monorepo ขนาดใหญ่

  • หากใน monorepo ขนาดใหญ่มีการอัปเดต CHANGELOG.md หรือไฟล์ชื่อค่อนข้างยาวซ้ำ ๆ ก็ควรติดตามการเปลี่ยนแปลงที่เกี่ยวกับ path-walk
  • คำสั่งใหม่ git survey ให้ heuristic สำหรับประเมินสภาพ repository
    • Top Files By Disk Size
    • Top Directories By Inflated Size
    • Top Files By Inflated Size
  • heuristic เหล่านี้ช่วยประเมินได้ว่างานด้าน path-walk จะส่งผลต่อขนาด repository นั้นหรือไม่

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

 
GN⁺ 2024-10-28
ความคิดเห็นจาก Hacker News
  • ถ้าสงสัยว่าคำสั่งใหม่ git-survey อยู่ที่ไหน คำตอบคือมันยังไม่ได้เข้า git.git
    ผู้เขียนใช้ Git fork ของ Microsoft และคำสั่งนี้ถูกเพิ่มเข้ามาเมื่อฤดูร้อนที่ผ่านมา: https://github.com/microsoft/git/pull/667

    • full-name-hash กับ path-walk ก็ดูเหมือนจะมีแค่ใน fork หรือมีแค่ใน Git HEAD เท่านั้น
      หาไม่เจอทั้งในหน้า manual และใน บันทึกการเปลี่ยนแปลงของ 2.47
  • สงสัยว่าประโยคที่ว่า “คนในยุโรปโคลนรีโปไม่ได้เพราะขนาดรีโป” หมายความว่าอะไร
    มันฟังดูแปลกที่รีโปขนาดใหญ่จะดาวน์โหลดในยุโรปไม่ได้ แต่ที่อื่นกลับได้ และก็ดูเหมือนว่าก่อนจะมีการเปลี่ยนฝั่งเซิร์ฟเวอร์ก็คงยังโคลนไม่ได้อยู่ดี
    ประโยค “push ไฟล์ทั้งก้อนซ้ำไปเรื่อยๆ” เหมือนถูกตัดกลางคัน และระหว่างอ่านบทความก็รู้สึกว่า GIF รบกวนสายตามาก แถมยังโผล่มาแม้ในโหมดอ่าน

    • ผมอ่านประโยคนั้นเป็นเกร็ดเล่าเสียมากกว่า
      ถ้าจะเขียนให้ครบขึ้นก็น่าจะประมาณว่า “มีคนหนึ่งตั้งใจจะโคลนรีโปทั้งหมดลงโน้ตบุ๊กเพื่อใช้ระหว่างเดินทางในยุโรป แต่ตอนนั้นดิสก์เต็มเลยทำไม่ได้ หลังจากนั้นเคลียร์ดิสก์แล้วจึงโคลนได้”
      ไม่น่าจะได้หมายถึงปัญหาใหญ่ระดับว่ายุโรปรับมือกับ ไฟล์ 180GB ไม่ได้
    • ตรงนี้ “ยุโรป” น่าจะเป็นคำแทนของ latency สูง แบนด์วิดท์ต่ำ มากกว่า
      โดยเฉพาะถ้าคนคนนั้นใช้ VPN และยิ่งถ้าเป็นลูกเล่น “SSL VPN” ที่แย่มากด้วยก็ยิ่งใช่ ซอฟต์แวร์ที่จัดการ latency ได้ไม่ดีหรือเซิร์ฟเวอร์ที่ตั้งค่า window scaling พังๆ ก็ยังพบได้บ่อยอย่างน่าประหลาด
      ถ้านักพัฒนาส่วนใหญ่อยู่ใกล้เซิร์ฟเวอร์และใช้การเชื่อมต่อที่แบนด์วิดท์ดี ปัญหาแบบนี้ก็มักไม่ค่อยโผล่มาให้เห็น
    • ผมอยู่ในออสเตรเลีย ทำงานกับอีกทีมภายใน Microsoft และใช้ monorepo ขนาดใหญ่บน Azure DevOps ซึ่งแทบจะโคลนทั้งก้อนไม่ได้เลย
      การโคลนจาก Azure DevOps ใช้แบนด์วิดท์ของการเชื่อมต่อแบบกิกะบิตผ่านสายได้ไม่เต็มเลย และเพราะใช้เวลานานเกินไป สุดท้ายไม่ฝั่งผมหรือฝั่ง Azure DevOps ก็จะหยุดไปเองจนต้องยอมแพ้
      โชคดีที่แทบทุกอย่างทำได้ด้วย shallow clone ใน Codespaces เลยไม่ใช่ปัญหาใหญ่มาก และถ้ารีโปของเรามีปัญหาขนาดพองแบบเดียวกับรีโป 1JS ในบทความนี้ ก็หวังว่าจะมีการแก้เหมือนกัน
    • รีโปน่าจะอยู่ฝั่งชายฝั่งตะวันตกของสหรัฐ ดังนั้นเวลาจะโคลนจากยุโรปก็คงต้องวิ่งข้าม มหาสมุทรแอตแลนติก ทุกครั้งหรือเปล่า
    • หรืออาจอยู่ในประเทศที่โครงสร้างพื้นฐานอินเทอร์เน็ตพัฒนาน้อยกว่า เช่น เยอรมนี
  • อัปเดต: เป็นความผิดพลาดงี่เง่ามาก และชื่อไฟล์ไม่ได้รวมพาธทั้งหมดไว้
    ดูเหมือนคำอธิบายจะถูกกลบไปท่ามกลาง GIF แต่ 16 ตัวอักษรสุดท้ายตรงนี้ต่างกัน: เป็นตัวอย่างที่เปลี่ยน repo/packages/foo/CHANGELOG.md แต่ Git กลับสร้าง diff โดยเทียบกับ repo/packages/bar/CHANGELOG.md ระหว่างเตรียม push

    • Derrick อธิบายไว้ดีกว่าใน cover letter นี้: https://lore.kernel.org/git/pull.1785.git.1725890210.gitgitg...
      cover letter ของ API path-walk ก็น่าอ่านเช่นกัน: https://lore.kernel.org/all/pull.1786.git.1725935335.gitgitg...
      ตัวอย่างในบล็อกอาจไม่ชัดมากนัก แต่จริง ๆ แล้ว Git ดึงทุกเวอร์ชันของทุกไฟล์ในรีโพมาใส่ 16 ไบต์สุดท้ายของพาธ ลงในแฮชเทเบิล แล้วจับกลุ่มสิ่งที่มันคาดว่าเป็นคนละเวอร์ชันของไฟล์เดียวกันไว้สำหรับ delta compression
      foo/CHANGELOG.md กับ bar/CHANGELOG.md ในบทความยาวแค่ 13 ตัวอักษร จึงไม่ถูกต้องตามตัวอย่างเป๊ะ ๆ และต้องนึกถึงพาธที่มีคำต่อท้ายร่วมกันยาวกว่านี้
      ส่วนนี้ถูกแก้ด้วยออปชัน --full-name-hash ซึ่งตอนนี้จะเทียบพาธทั้งหมดแทนที่จะดูแค่ 16 ไบต์
      ส่วนการเพิ่มขนาดหน้าต่างที่พูดถึงถัดมานั้นใกล้เคียงกับการแฮ็กเพื่อหลบการจัดกลุ่มไฟล์ที่แย่มากกว่า ไม่ใช่การแก้จริง
      มันยังคงป้อนอินพุตที่เลวร้ายให้ตัวบีบอัดอยู่ และแค่อ้อมปัญหาด้วยการใช้หน่วยความจำมหาศาล เลยทำให้งงที่ถูกนำเสนอเหมือนเป็นวิธีแก้
      ส่วนที่น่าสนใจจริง ๆ คือ path-walk API และ --full-name-hash
    • อยากให้บทความอธิบายให้ชัดกว่านี้ว่าเกิดอะไรขึ้นกันแน่ มากกว่าจะเน้นการเล่าเรื่องแบบ “มีสีสัน”
      ตรงนี้สงสัยว่าชื่อไฟล์หมายถึง พาธ หรือ Git จะหยิบไฟล์อะไรก็ได้ที่ชื่อเหมือนกันมาสร้าง diff
      แล้วก็อยากรู้ว่ามีรูปแบบอะไรไหมในการเลือกไฟล์อื่นนั้น
    • ใช่แล้ว มันพิจารณาพาธเต็ม
      ดูได้จากข้อความ commit แรกของ PR --full-name-hash: https://github.com/git-for-windows/git/pull/5157/commits/d5c...
      ยกข้อความมาคือ "/CHANGELOG.json" ยาว 15 ตัวอักษร สร้างโดยเครื่องมือ beachball และมีเพียงอักษรตัวสุดท้ายของไดเรกทอรีแม่ที่ใช้แยกความต่างระหว่างเวอร์ชันต่าง ๆ ของไฟล์นี้ได้ แต่ถึงอย่างนั้นก็สะท้อนออกมาแค่ 2 บิตบนสุด
      ถ้าอักษรนั้นเป็นตัวอักษรภาษาอังกฤษ มันก็จะชนกันเสมอ และพาธ "/CHANGELOG.md" ก็มีปัญหาคล้ายกัน แต่พอมีพื้นที่ให้ต่างกันในไดเรกทอรีแม่มากกว่าเล็กน้อย
      อัลกอริทึมการจัดกลุ่มจะให้น้ำหนักอักขระน้อยลงเรื่อย ๆ ยิ่งอยู่ไกลจากด้านขวาของชื่อ: hash = (hash >> 2) + (c << 24)
      แฮชมีขนาด 32 บิต และอักขระ 8 บิตแต่ละตัวของพาธทั้งหมดจะถูกใส่ต่อกันเข้าไปใน 8 บิตบนสุดของแฮช พร้อมกับเลื่อนบิตเดิมของแฮชไปทางขวา 2 บิต ดังนั้นแฮชสุดท้ายจึงได้รับอิทธิพลจากแค่ 16 ตัวอักษรสุดท้าย
      ดูสิ่งที่เกิดขึ้นจริงได้ที่นี่: https://go.dev/play/p/JQpdUGXdQs7
      มีการพอร์ตไปเป็น Go เพื่อเทียบค่าท้ายสุดของ "aaa/CHANGELOG.md" กับ "zzz/CHANGELOG.md" ดังนั้นลองแทนค่า aaa และ zzz แบบต่าง ๆ จะเห็นว่ามันส่งผลต่อค่าท้ายสุดน้อยมากแค่ไหน
    • ไม่จำเป็นเสมอไปที่ชื่อไฟล์จะรวมพาธทั้งหมด
      16 ตัวอักษรสุดท้ายของ CHANGELOG.md ก็คือชื่อไฟล์เต็ม และถ้าแปลความแบบนั้นก็อธิบายได้ว่าทำไมวิธีแก้แบบ filepathwalk ถึงช่วยแก้ปัญหา
      แต่ถ้ามันอิงแค่ 16 ตัวอักษรสุดท้ายของชื่อไฟล์จริง ๆ และไม่ใช่พาธทั้งหมด ปัญหานี้ก็น่าจะเกิดบ่อยกว่านี้มาก โดยเฉพาะในโมโนรีโพ
    • ฉันก็ติดใจตรงนั้นเหมือนกัน
      น่าจะสับสนเพราะ foo กับ bar เป็นตัวแปรสมมุติ และชื่อแพ็กเกจจริงอาจเป็นอะไรอย่าง firstPkg, secondPkg ที่มีคำต่อท้ายร่วมกัน
      แค่ "/CHANGELOG.md" อย่างเดียวก็ยาว 13 ตัวอักษรแล้ว ดังนั้นถ้ามีคำต่อท้ายร่วมกันอีก 3 ตัวอักษร ก็เกิด การชนกันของ 16 ตัวอักษร ได้แล้ว
  • เพิ่งลองกับ nixpkgs ทันที และถ้า clone จาก GitHub ตรง ๆ จะอยู่ที่ราว 5GB
    ออปชันแรกที่บทความพูดถึงคือ --window 250 ลดขนาดลงเหลือ 1.7GB และออปชัน --path-walk ใหม่ใน Microsoft Git fork ได้ผลน้อยกว่า ทำให้รวมแล้วเหลือ 1.9GB
    ทั้งสองแบบเล็กกว่าครึ่งของขนาดตั้งต้น ดังนั้นก็คงดีถ้า GitHub มีวิธีรันงานแบบนี้ให้ และจะยิ่งดีถ้าเริ่มมีบริการโฮสต์ที่เปิดให้ผู้ใช้ควบคุมเรื่องแบบนี้ได้เอง

  • มี Derrick Stolee ปรากฏตัว คนที่ขุดลึกถึงการเปลี่ยนแปลงที่บทความต้องใช้และเป็นคนปล่อยออกมา
    ถ้าสนใจโครงสร้างภายในของ Git การลดขนาด clone ของ Git ทั้งบนเครื่องโลคัลและใน CI Derrick เขียนบทความดี ๆ ไว้มากมายในบล็อก GitHub: https://github.blog/author/dstolee/
    เว็บไซต์ส่วนตัวของเขาก็น่าอ่านเช่นกัน: https://stolee.dev/

  • ถ้าเผลอ commit ไบนารีขนาดใหญ่เข้าไป วิธีแก้ก็คือรัน filter-branch เพื่อลบไบนารีต้นปัญหาออก จากนั้นสอนและตั้งค่าให้ทุกคนใช้ git-lfs สำหรับไฟล์ไบนารี แล้วค่อย force push และทำให้สภาพแวดล้อมการทำงานของแต่ละคนกลับมาอยู่ในสถานะปกติ
    แม้จะไม่ใช่วิธีที่ดีที่สุด แต่ก็ยังดีกว่าปล่อยไฟล์ใหญ่ที่ไม่ได้ใช้งานค้างอยู่ใน Git ต่อไป

    • ถ้าใครรู้สึกว่า filter-branch น่ากลัว ก็ยังมี BFG: https://rtyley.github.io/bfg-repo-cleaner/
      อย่างที่มีคนอื่นชี้ไว้ ปัญหานี้เกี่ยวกับไฟล์ขนาดเล็กที่เปลี่ยนบ่อย ดังนั้นถ้าอยากประหยัดพื้นที่ก็แค่ลบเวอร์ชันเก่าออกจากประวัติ และใช้ LFS ต่อจากนี้ไป
    • ปัญหาหลักไม่ใช่ไฟล์ไบนารีที่เข้าไปครั้งเดียวแล้วไม่เปลี่ยนอีก แต่คือ ไฟล์ไบนารีขนาดเล็กที่เปลี่ยนบ่อย
    • ทุกวันนี้แนวทางที่แนะนำคือ filter-repo: https://github.com/newren/git-filter-repo
    • โทษ Linus ง่ายกว่า
  • การแฮ็ก Git ก็คงสนุกดี แต่ก็อดคิดไม่ได้ว่าแต่แรกมีวิธีไม่เอา แพ็กเกจ 2,500 ตัวไว้ในโมโนเรโป ไหม

    • จำนวนบรรทัดของโค้ดโดยมากมีแนวโน้มเพิ่มขึ้นแบบเอ็กซ์โปเนนเชียล
      ยิ่ง codebase ใหญ่ขึ้น ก็ยิ่งยากที่จะคาดหวังให้คนไม่สร้างล้อขึ้นมาใหม่ เพราะพวกเขาอาจไม่รู้ว่าโค้ดนั้นมีอยู่ หรือกลัวว่าถ้าปรับให้รองรับ use case ของตัวเองแล้วจะไปทำของเดิมพัง
      จากประสบการณ์ส่วนตัว เวลาที่ใช้ในการเพิ่มจาก 100 โมดูลเป็น 200 โมดูล น้อยกว่าตอนเพิ่มจาก 50 เป็น 100 โมดูลเสียอีก
    • งั้นก็แบกรับ overhead ที่เกี่ยวข้องทั้งหมด แล้วแยกเป็น Git repository 2,500 อัน ไปเลย
    • นี่คือความคิดแรกของฉันเหมือนกัน
      ดูเป็นปัญหาที่สร้างขึ้นมาเองล้วน ๆ
  • ช่วงหลังมานี้ฉันตามดูความคืบหน้าเรื่องโมโนเรโปและการสเกลจากงานเปิดตัว GitMerge ที่ GitButler เพิ่งโพสต์ไว้ ซึ่งมีของดีออกมาจาก Microsoft, GitHub และ GitLab เยอะมาก
    อยากเข้าใจให้มากขึ้นว่าปัญหาการตรวจ 16 อักขระสุดท้ายกับการตรวจพาธทั้งหมดนั้นทำงานร่วมกับ delta compression, pack index และ multi-pack index อย่างไร

    • ถ้ามันเป็นประโยชน์กับโอเพนซอร์สขนาดนั้น ก็สงสัยว่าเขามีแผนจะเปิด merge request เพื่อนำคำสั่ง Git แบบคัสตอมกลับไปรวมใน Git อย่างเป็นทางการหรือไม่
  • ดีที่เห็น Microsoft ใช้ Azure DevOps เองโดยตรง
    ช่วงหลังรู้สึกว่าบริการ Azure ยิ่งนานยิ่งมี native connector ให้แค่ GitHub เลยคิดว่า Azure DevOps กำลังถูกปล่อยทิ้งไว้ข้างหลัง

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

    • แน่นอนว่าการมีความสัมพันธ์ใกล้ชิดกับองค์กรอย่าง GitHub ช่วยได้มาก แต่ถ้าเป็นองค์กรที่มีนักพัฒนาจำนวนมากระดับนั้น ไม่ว่าที่ไหนก็น่าจะมีเหตุผลพอที่จะจ้าง ที่ปรึกษาเฉพาะทางระดับสูง มาจัดการปัญหาเฉพาะกลุ่มแบบนี้