2 คะแนน โดย GN⁺ 2025-06-05 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ฟอร์แมต Unified Diff แบบเดิม มีข้อจำกัดที่ยังสะท้อนความต้องการของสภาพแวดล้อมการพัฒนาได้ไม่เพียงพอ
  • DiffX เข้ากันได้อย่างสมบูรณ์กับรูปแบบเดิม และมอบโครงสร้างที่คำนึงถึงอนาคตพร้อมความสามารถในการขยายเมตาดาต้า
  • สามารถจัดเก็บ ข้อมูลคอมมิตหลายรายการ, ไฟล์ไบนารี, การเข้ารหัสอักขระ และเมตาดาต้าในรูปแบบที่ มีโครงสร้าง
  • มีการนำ กฎการพาร์สมาตรฐานมาใช้ ทำให้เชื่อมต่อกับเครื่องมือต่าง ๆ (แพตช์, code review ฯลฯ) ได้ง่าย
  • ใช้งานได้โดยไม่มีปัญหากับ เครื่องมือและเวิร์กโฟลว์เดิม และต้องการการรองรับจากเครื่องมือเฉพาะในส่วนของฟีเจอร์ใหม่เท่านั้น

นักพัฒนาและไฟล์ Diff

  • นักพัฒนาซอฟต์แวร์มักใช้ไฟล์ diff จาก Git, Subversion, CVS เป็นต้น เพื่อตรวจสอบการเปลี่ยนแปลงของโค้ด
  • ไฟล์ Diff มีโครงสร้างที่ประกอบด้วย การแทรกข้อความ(+)·การลบ(-) รวมถึงชื่อไฟล์, พาธ, timestamp และเมตาดาต้าบางส่วน
  • เครื่องมือและผู้ใช้ส่วนใหญ่ใช้รูปแบบ Unified Diff ซึ่งเป็นวิธีที่ค่อนข้างเรียบง่ายในการแสดงภาพความแตกต่าง

ข้อจำกัดของ Unified Diff

  • Unified Diff กำหนดมาตรฐานเฉพาะการระบุไฟล์, ช่วงการเปลี่ยนแปลง, และบรรทัดที่ถูกแทรก·ลบเท่านั้น แต่ไม่ได้กำหนดมาตรฐานสำหรับ encoding, revision, เมตาดาต้าส่วนขยาย เป็นต้น
  • ทำให้รองรับ ระบบจัดการซอร์สที่หลากหลายได้ยาก รวมถึงยากต่อการพาร์สอย่างน่าเชื่อถือและการดึงข้อมูลที่สมบูรณ์
  • ปัญหาต่อไปนี้ยังคงเกิดขึ้นอย่างต่อเนื่อง
    • ไม่สามารถแสดง หลายคอมมิตพร้อมกันได้
    • ขาดรูปแบบมาตรฐานเฉพาะสำหรับ ไฟล์ไบนารี
    • ไม่สามารถทราบ การเข้ารหัสอักขระได้ จึงเกิดการสูญหายของข้อมูลและความสับสน
    • การขาดมาตรฐานของ เมตาดาต้าตามอำเภอใจ ทำให้แต่ละเครื่องมือใช้รูปแบบต่างกัน

แนวทางการปรับปรุง

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

DiffX คืออะไร

  • DiffX คือฟอร์แมต Diff ที่ขยายได้ ซึ่ง เข้ากันได้อย่างสมบูรณ์กับเครื่องมือเดิม รักษาความสามารถในการอ่านของมนุษย์ไว้ และในขณะเดียวกันก็สามารถบรรจุ เมตาดาต้าและองค์ประกอบต่าง ๆ อย่างเป็นโครงสร้าง
  • ตัวอย่างไวยากรณ์:
    • สามารถจัดเก็บ เมตาดาต้าและ เนื้อหาสำหรับไฟล์, คอมมิต, และ diff ทั้งชุด โดยใช้แนวทางเชิงโครงสร้างและการขยาย
    • ในตัวอย่างเอาต์พุตจะมีไวยากรณ์อย่าง #diffx: รวมถึง section, เมตาดาต้า (JSON), พาธไฟล์, ข้อมูลคอมมิต เป็นต้น

จุดเด่นหลักของ DiffX

  • มี กฎการพาร์สมาตรฐาน ทำให้เครื่องมือสามารถอ่านและเขียนข้อมูลได้อย่างน่าเชื่อถือ
  • ทำให้การ จัดเก็บ·การจัดการเมตาดาต้าเป็นทางการ: ใช้ได้ทั้งในระดับ diff ทั้งชุด, คอมมิต, และไฟล์
  • เข้ากันได้กับเครื่องมือทั้งหมด เช่น parser เดิม, patcher, code review เป็นต้น (ฟีเจอร์ใหม่ต้องมีการรองรับเพิ่มเติม แต่ฟังก์ชันเดิมยังคงรับประกันความเข้ากันได้)
  • สามารถแสดง หลายคอมมิต, binary diff, ข้อมูลการเข้ารหัสข้อความ และเนื้อหาหลายประเภทในไฟล์เดียวได้ด้วยโครงสร้างที่มีประสิทธิภาพ
  • รองรับ การแก้ไขเปลี่ยนแปลงได้ (mutability) โดยเครื่องมือสามารถเปิด diff เพื่อบันทึกและแก้ไขข้อมูลที่ต้องการ แล้วบันทึกกลับได้

เป้าหมายและสิ่งที่ DiffX ไม่มุ่งทำ

  • ไม่บังคับให้ทุกเครื่องมือต้องรองรับฟอร์แมตนี้ และไม่สร้างปัญหาด้านความเข้ากันได้
  • ไม่ก่อให้เกิด vendor lock-in และไม่ทำลาย เวิร์กโฟลว์เดิม
  • มุ่งแก้ปัญหาของไฟล์ Diff แบบเดิม และมอบประสบการณ์การใช้งานที่สม่ำเสมอและน่าเชื่อถือในเครื่องมือสำหรับการพัฒนา การรีวิว และการวิเคราะห์

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

 
GN⁺ 2025-06-05
ความคิดเห็นใน Hacker News
  • ฉันไม่ชอบฟอร์แมตที่ซับซ้อนเป็นลำดับชั้นอย่าง ..meta และ ...meta สำหรับความชัดเจนของการแสดงผล ฉันคิดว่าถ้าแบ่งเพียงสามระดับคือ diff ทั้งก้อน, ไฟล์, และ chunk แล้วตั้งชื่อให้ต่างกันไป จะเป็นฟอร์แมตที่อ่านเข้าใจง่ายกว่า ต่อให้ไม่มี meta block ก็ยังแยกเป้าหมายได้ในทันที จึงช่วยลดความผิดพลาดหรือข้อผิดพลาดได้ด้วย การที่เมทาดาทาของ diff ทั้งก้อนกับเมทาดาทาระดับไฟล์ใช้ฟิลด์ชุดเดียวกันก็ดูไม่สมเหตุสมผล และก็ไม่เข้าใจว่าทำไมต้องมีทั้ง JSON และฟอร์แมต key=value สองแบบ ถ้าจำนวนสิ่งที่ต้องดูแลมีไม่มาก การใช้ฟอร์แมตเดียวจะดีกว่ามากทั้งในแง่การ implement และการเชื่อมกับเครื่องมือเดิม ๆ (ใช้แค่ grep, sed หรือ jq อย่างใดอย่างหนึ่งก็พอ) นอกจากนี้ ถ้าอนุญาตให้มี trailing comma ในลิสต์ก็น่าจะดี และ diff เดิมทีเป็นโครงสร้างที่ apply แบบแยกส่วนได้อยู่แล้ว เลยสงสัยว่าฟอร์แมตนี้ส่งผลต่อจุดนั้นอย่างไร (เช่น ถ้าจะ apply แค่บางส่วนของ diff ต้องคัดลอก preamble และคัดลอก block แยกอีก ทำให้รู้สึกว่ายุ่งยาก) อีกอย่างก็สงสัยว่า revision เป็นคุณสมบัติของไฟล์ หรือเป็น checksum ของ commit กันแน่

    • เราลองทดลองหลายแนวทางกับโครงสร้างนี้ สุดท้ายจึงสรุปมาเป็นรูปแบบ #<section_level><section_type> เพื่อความเรียบง่ายในมุมของ parser แต่ละ meta block แค่ตรวจระดับในแนวตั้งก็พอ และนับจำนวนจุดก็แยกได้ตามธรรมชาติว่าเป็น meta ของระดับไหน ฟอร์แมต header แบบคีย์/ค่า เราตั้งใจให้ใช้เก็บเฉพาะคุณสมบัติง่าย ๆ ที่ parser รู้จักล่วงหน้าเท่านั้น ส่วนเมทาดาทาที่ยืดหยุ่นได้ให้เก็บใน meta block แยกต่างหาก นอกจาก JSON เดิมแล้ว เรายังสามารถระบุฟอร์แมตใน header เพื่อให้ขยายต่อได้หากในอนาคตจำเป็นต้องใช้วิธี serialization แบบอื่น นี่คือผลจากการพยายามหาสมดุลระหว่างความเรียบง่ายกับความยืดหยุ่น ส่วน trailing comma โดยส่วนตัวผมก็อยากใส่ แต่ด้วยปัญหาความเข้ากันได้ของ JSON ระดับพื้นฐาน จึงยากที่จะบังคับให้ต้องใช้ JSON5 parser diff ยังคงแยกส่วนได้เหมือนเดิม และเพราะเราใส่ข้อมูลไว้ในส่วนที่ Unified Diff มองข้ามอยู่แล้ว เครื่องมืออย่าง GNU patch จึงจะมองข้ามและไม่เกิดปัญหา อย่างไรก็ตาม ถ้าจะแยกเป็นไฟล์ DiffX สองไฟล์ ก็ต้องเพิ่ม header ใหม่ ทำให้ซับซ้อนขึ้นเล็กน้อย diff ของ SCM บางตัวแม้จะแยกแล้วก็อาจทำให้เมทาดาทาบางส่วนหายไป (เช่น ข้อมูล parent commit) หรือเกิดการสูญเสียข้อมูลตามเป้าหมายที่จะ apply ส่วน revision นั้นแตกต่างกันไปตาม SCM มีได้ทั้ง commit ID, ID รายไฟล์ หรือชุดผสมของสิ่งเหล่านี้รวมถึงข้อมูลเพิ่มเติมอื่น ๆ โครงสร้างนี้ถูกออกแบบมาโดยคำนึงถึงความต้องการที่หลากหลายของแต่ละ SCM
  • สำหรับผม จากสี่ข้อสังเกตข้างล่าง มีเพียงข้อเดียวที่สมเหตุสมผลจริง ๆ ในฐานะการทำให้ไฟล์ diff เป็นแบบทั่วไปมากขึ้น คือสัญกรณ์สำหรับ binary patch นอกนั้นเป็นปัญหาของข้อมูลหรือโปรโตคอลภายในของระบบควบคุมเวอร์ชัน (SCM) แต่ละตัว ซึ่งใช้กันได้แค่ใน client, server หรือระบบ backup ของตัวเองเท่านั้น อย่างอื่นทั้งหมดดูไม่จำเป็น

    • ไม่สามารถลำดับหลาย commit ใน diff เดียวได้

    • ไม่มีมาตรฐานสำหรับ binary patch

    • ไม่สามารถระบุการเข้ารหัสข้อความได้ (ซึ่งจริง ๆ แล้วเป็นปัญหาเงียบ ๆ)

    • ไม่มีฟอร์แมตมาตรฐานสำหรับเมทาดาทาตามอำเภอใจ

    • เราพัฒนาผลิตภัณฑ์ code review ที่เชื่อมต่อ SCM มากกว่า 12 ตัวมาตลอด 20 ปี และเจอทั้งฟอร์แมต diff แปลก ๆ และปัญหาเฉพาะของ SCM แต่ละตัวนับไม่ถ้วน จริงอยู่ที่ไม่ใช่ปัญหาที่ end user ต้องมาสนใจเอง แต่ในมุมของผู้พัฒนาเครื่องมือ มันคือ pain point ที่จำเป็นต้องแก้ SCM บางตัวไม่มีฟอร์แมต diff ของตัวเองเลย หรือมีข้อมูลไม่ครบมาก (เช่น ไม่สามารถระบุไฟล์ที่ถูกลบได้) จนทำให้เครื่องมืออื่นระบุไฟล์ได้ไม่ถูกต้อง เราจึงรู้สึกว่าจำเป็นต้องมีการปรับปรุงแบบนี้

    • ปัจจุบันอาจพบน้อยลง แต่ผมเองก็ยังใช้เครื่องมือคล้าย patch(1) อยู่เป็นครั้งคราว เวลานักพัฒนาหลายแพลตฟอร์มร่วมงานกัน ปัญหาอย่างตัวพิมพ์ใหญ่เล็กของชื่อไฟล์หรือการเข้ารหัสอักขระก็ยังเกิดขึ้นอยู่เสมอ

  • ถ้าใช้วิธีฝัง JSON แบบ self-delimitered พร้อมข้อมูลความยาว ต่อให้เปลี่ยนแค่ช่องว่างหนึ่งตัวในเนื้อหา JSON เอง แม้ JSON จะยัง valid แต่ DiffX อาจพังทั้งชุดได้ มันให้ความรู้สึกเป็นการประกอบกันที่ทั้งเกะกะและยุ่งเหยิงในเชิงโครงสร้าง (ทั้งการผสม header ของตัวเองกับ JSON payload, การที่ถ้าไม่นับจำนวนจุดก็แยก meta block คนละชนิดไม่ได้, และโครงสร้างที่ต้องใช้ parser สองตัว) แนวคิดที่จะทำ diff แบบขยายได้สำหรับเมทาดาทาให้เป็นมาตรฐานนั้นดี แต่ implementation ครั้งนี้ดูเหมือนงานลองผิดลองถูก

  • ผมคิดว่าฟอร์แมต patch แก้ปัญหาเหล่านี้ได้หมดแล้ว ลิงก์คำอธิบาย git format-patch

    • วันนี้เพิ่งรู้ว่ามีฟอร์แมตแบบนี้ด้วย ขอบคุณสำหรับข้อมูล (ผมเป็นแค่ผู้ใช้อินเทอร์เน็ตธรรมดา ไม่ใช่ผู้เขียน)

    • ใน git มันแก้ได้ แต่ถ้าเป็นผลิตภัณฑ์อย่าง Review Board ที่ต้องเชื่อมกับ VCS หลายแบบอย่าง SVN, CVS, Perforce ฯลฯ นั่นน่าจะเป็นที่มาของฟอร์แมตนี้ ผมเองก็เคยใช้ Review Board กับ SVN แล้วพอมีนักพัฒนาหลายคนใช้ทั้ง git-svn และ svn ปนกัน ก็มักมีปัญหาตอนอัปโหลด diff เพื่อรีวิวอยู่บ่อย ถ้ามีฟอร์แมต diff มาตรฐานที่รองรับทั้งสองฝั่งได้ก็คงช่วยให้ใช้งานเครื่องมือได้มากขึ้นมาก

  • ผมเองไม่ค่อยรู้สึกว่าปัญหาที่ยกมามันมีอยู่จริงเท่าไร (ยกเว้นไฟล์ไบนารี)

    • แม้ encoding ต่างกัน patch algorithm ก็เหมือนเดิม จึงไม่ต้องใส่ใจมากก็ได้ (อักขระเองก็ไม่จำเป็นต้องเป็น utf-8 ที่ valid เสมอไป)

    • ก็ไม่เห็นว่าจะมีเหตุผลอะไรที่อยากใส่หลาย commit ลงใน diff เดียว แยกเป็นหลาย diff ดูตรงไปตรงมามากกว่า

    • เมทาดาทาก็ดูเหมือนจะมีผลใช้ได้แค่ภายในระบบไม่ใช่หรือ

    • ในเรื่อง encoding เอง patch data ก็ควรถูกจัดการเหมือนข้อมูลไบนารีที่อิงบน ascii อยู่ดี เพราะอาจต้องแก้ไฟล์ที่มี mixed encoding ดังนั้นการบังคับ encoding เดียวจึงดูไม่มีความหมายเท่าไร

    • ผมมองว่าไม่ใช่ปัญหาเลย คิดว่าน่าจะไปฟังประสบการณ์จริงจากคนที่ใช้ diff เยอะ ๆ ดีกว่า และไม่ควร overengineering ฟอร์แมตที่ใช้งานได้ดีอยู่แล้วโดยไม่จำเป็น

    • ปัญหาเรื่องข้อมูลไบนารีนั้นผมคิดว่ามีอยู่จริงแน่นอน

    • โดยปกติจะเจอปัญหาเหล่านี้จริงก็ต่อเมื่อสร้างเครื่องมือเองหรือจำเป็นต้องเชื่อมต่อกับ SCM บางตัว

      1. ปัญหา encoding มีทั้งในชื่อไฟล์และเนื้อหา Git ใส่ใจกับ encoding ของชื่อไฟล์ แต่ SCM ส่วนใหญ่ไม่ทำ ทำให้ diff ที่สร้างอัตโนมัติในสภาพแวดล้อมหนึ่ง อาจหาไฟล์ชื่อเดียวกันไม่เจอในอีกสภาพแวดล้อมหนึ่ง (ผมเคยเห็นกับ Perforce, Subversion ฯลฯ) ส่วนเนื้อหาก็เช่นกัน diff อาจเสียได้ตาม local encoding ของแต่ละ SCM และเมื่อข้ามไปมาระหว่าง Windows กับ Linux ก็เคยเจอทั้งปัญหา newline ปนกันจน apply patch ไม่ได้ หรือ GNU patch พังเพราะ BOM
      2. เวลาจัดการหลาย commit พร้อมกันหรือส่งต่อให้เครื่องมือ อาจเกิดปัญหาหลากหลาย เช่น ไฟล์ตกหล่นหรือความไม่สอดคล้องกัน และการ sanity check ทีละ diff ก็ยุ่งยาก แถมแต่ละเครื่องมือยังรองรับฟอร์แมตต่างกันอีก จึงไม่สะดวก
      3. หากต้องค้นหาไฟล์ใน repository แต่ละระบบก็ต้องใช้ตัวระบุหลากหลายแบบ เช่น ระดับ commit, ระดับไฟล์, แบบผสม หรือข้อมูลความสัมพันธ์ รวมถึงข้อมูลอย่าง symbolic link, file mode หรือข้อมูลเฉพาะของ SCM ที่ไม่มีอยู่ใน Unified diff แต่จำเป็นต้องใช้
  • เอกสารโดยรวมอ่านยากสำหรับผม คำว่า ‘diff’ ในความเข้าใจของผมหมายถึงความแตกต่างระหว่างสองสิ่ง (ไฟล์, ไดเรกทอรี ฯลฯ) แต่ diff ที่ TFA พูดถึงคือสิ่งที่ผมรู้จักในชื่อ ‘patch’ สิ่งที่กำลังคุยกันตรงนี้ไม่ใช่ diff แต่เป็นเรื่องการจัดการเมทาดาทาของ patch ถ้าจะทำให้เมทาดาทามีมาตรฐานด้วยรูปแบบบังคับอย่าง JSON ก็น่าสนใจ แต่โครงสร้างแบบ self-describing length-delimited ที่คลุมเครือเช่นนี้ให้ความรู้สึกเหมือนซ่อนปัญหาไว้ การทำให้เป็นมาตรฐานนั้นดี แต่ผมรู้สึกว่ายังต้องการโซลูชันที่จัดระเบียบได้ชัดเจนกว่านี้ และก็น่าสนใจเหมือนกันที่ในสายตาผม สไตล์ git diff กลับดูใกล้เคียงมาตรฐานโดยพฤตินัยมากกว่า

    • เห็นด้วยกับประโยคสุดท้ายอย่างยิ่ง แค่แยกใช้ diff หลายไฟล์ก็พอแล้ว
  • ผมสงสัยว่าฟอร์แมตนี้ตั้งใจมาแก้ปัญหาอะไร บอกว่าฟอร์แมต patch/diff เดิมไม่ดีพอ แต่ต้องอธิบายให้ชัดกว่านี้ว่าปรับปรุงเพื่อใคร เพราะชุมชน GNU Patch บ่นกันมากขึ้นหรืออย่างไร หรือมีเหตุผลอะไรแน่ ๆ ผมยังสงสัยอยู่ว่าทำไมถึงจำเป็นต้องมีฟอร์แมต patch ที่ดีกว่านี้จริง ๆ

    • ผมมีบทความที่ยาวเกินกว่าจะโพสต์ที่นี่แยกไว้อีกอัน สรุปสั้น ๆ คือเป็นโจทย์สำหรับคนที่สร้าง SCM เองหรือพัฒนาเครื่องมือที่เชื่อมกับ SCM สำหรับผู้ใช้ทั่วไปไม่จำเป็นต้องสนใจ ฟอร์แมต diff ของแต่ละ SCM ก็แตกต่างกันหมด บางแบบออกแบบมาดีมาก บางแบบขาดอย่างหนัก หรือบางทีก็ไม่มีฟอร์แมตเลย สำหรับผลิตภัณฑ์อย่าง Review Board ที่ต้องครอบคลุม SCM หลายตัว มาตรฐานกลางแบบนี้จึงจำเป็นมากในทางปฏิบัติ นี่เป็นความพยายามปรับปรุงที่สะท้อน feedback จากการทำงานร่วมกับผู้ขาย SCM จริง ๆ

    • ดูเป็นฟอร์แมตที่ใช้กับ Review Board เป็นหลัก เพราะผลิตภัณฑ์นี้รองรับ VCS หลากหลายชนิด และ diff เป็นหัวใจของการรีวิวซอร์สโค้ด จึงน่าจะเป็นเหตุผลที่นำมาใช้

  • วิธีแสดง diff ที่ทั่วไปและชัดเจนที่สุดคือใส่ไฟล์ทั้งสองไฟล์ไปตรง ๆ ทุกวันนี้ขนาดข้อมูลไม่ใช่ปัญหาแล้ว ดังนั้นแทน diff a b | patch c ก็น่าจะทำเป็น apply a b c ไปเลย แล้วจะใช้การแทนข้อมูลภายในแบบไหนก็ได้ diff นั้นมนุษย์อ่านยาก และมุมมองแบบสีสองฝั่งเคียงกันก็ดีกว่ามาก ดังนั้นการรับทั้งสองไฟล์มาตั้งแต่ต้นจึงตรงไปตรงมากว่า ผมไม่คิดว่าจำเป็นต้องส่ง diff ที่ไม่ได้มาตรฐานกันต่อ

    • diff ที่ได้จากไฟล์สองไฟล์ไม่ได้มีแค่แบบเดียว แต่มีได้หลายเวอร์ชันตามวัตถุประสงค์ที่ต่างกัน การมีฟอร์แมต diff ช่วยแยก logic การสร้าง diff กับการ apply ออกจากกัน ทำให้ปัญหาแบบ n*m ลดเหลือ n+m

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

    • การส่งและจัดการไฟล์สองชุดนั้นทำได้ยากหากไม่มีคอนเทนเนอร์เฉพาะทาง และถ้าจะส่งหลายการเปลี่ยนแปลงพร้อมกัน (เช่น แก้ 10 ไฟล์ + ลบ + เพิ่ม) ผ่านอีเมลหรือช่องทางอื่น ก็เหมือนถอยกลับไปยุคก่อนมี VCS ที่ต้องพึ่ง tar/zip และโครงสร้างซับซ้อนอื่น ๆ

    • ถึงแม้การส่งทั้งไฟล์แทน diff จะตรงไปตรงมากว่า แต่ในงานจริงและสภาพแวดล้อมต่าง ๆ diff ก็ยังมีความสำคัญมาก ปัจจุบันเวลาใช้ LLM สร้างผลลัพธ์อย่าง code edit ถ้าส่งคำขอเป็น diff จะประหยัดโทเคนได้มาก และลด latency ของคำตอบได้ถึง 5-10 เท่าอย่างชัดเจน การส่งทั้งสองไฟล์เป็นการสิ้นเปลืองโทเคนและต้นทุน หากจะ apply อย่างรวดเร็วบน code sandbox หรือเครื่องระยะไกล diff ให้ข้อได้เปรียบด้านการเพิ่มประสิทธิภาพอย่างมาก ถ้ามีไฟล์ A, A2 และ diff AxA2 ก็สร้าง A2 กลับขึ้นมาใหม่ได้ง่ายและช่วยเพิ่มประสิทธิภาพด้าน storage ด้วย ถ้ามีปัญหา merge conflict ค่อยเข้าไปจัดการเองในตอนนั้น สรุปคือ diff ยอดเยี่ยมมาก

  • ผมยังไม่ชอบที่เครื่องมือ diff ยังยึดติดกับหน่วยบรรทัดมากเกินไป เวลาเจอบรรทัดที่ยาวมาก (เช่น JSON, อาร์เรย์ยาว ๆ) มันรีวิวยากมาก

    • ผมก็เห็นด้วย คิดว่ายังมีพื้นที่ให้สำรวจรูปแบบ diff ที่ดีกว่านี้สำหรับข้อมูลที่มีโครงสร้าง (เช่น AST diff) ฟอร์แมตนี้ (DiffX) เน้นว่าเป็นส่วนขยายของฟอร์แมต Unified Diff เดิม และถ้าในอนาคตฟอร์แมตที่เฉพาะเจาะจงกว่าอย่าง AST ถูกใช้อย่างแพร่หลาย ก็ออกแบบมาให้ฝังและรองรับได้ง่ายเช่นกัน

    • รูปแบบที่ใช้กันทั่วไปมักเป็นจุดประนีประนอมระหว่างการอ่านของมนุษย์กับการ parse ของเครื่องมือ จึงมีโครงสร้างที่ก้ำกึ่ง ครั้งนี้ดูเหมือนพยายามแก้ปัญหาบางส่วนด้วยการขยายเมทาดาทา แต่ทางออกที่ดีจริง ๆ น่าจะเป็นการกำหนดฟอร์แมตใหม่ที่ไม่ใช่ plain text แต่ยังอ่านง่ายและ parse ได้ การสร้างอัลกอริทึม diff ที่ดีกว่าเดิมสำหรับบรรทัดยาวหรือข้อมูลเชิงโครงสร้างอาจเป็นโจทย์ที่ยาก แต่ผมคิดว่าแก้ได้แน่นอน

    • git ก็รองรับ word diff ที่ละเอียดกว่าการ diff ระดับบรรทัดเช่นกัน และตัวคั่นเริ่มต้นคือช่องว่าง

  • ผมสงสัยกับการที่ JSON เป็นฟอร์แมตเมทาดาทาแบบเดียวที่รองรับ เพราะถ้าออกแบบเป็นมาตรฐานเมทาดาทาเพื่อใช้งานทั่วไป JSON กลับดูซับซ้อนเกินไป

    • อยากฟังคำอธิบายที่เป็นรูปธรรมว่าทำไมถึงคิดว่า JSON ซับซ้อนเกินจำเป็น