การเปรียบเทียบข้อความทำงานอย่างไร
diff ตอบคำถามเดียว คือต้องเปลี่ยนอะไรบ้างเพื่อให้ข้อความแรกกลายเป็นข้อความที่สอง คู่มือนี้อธิบายว่าเครื่องมือ diff หาคำตอบอย่างไร วิธีอ่านผลลัพธ์ และวิธีเตรียมสองเวอร์ชันเพื่อให้ผลลัพธ์แสดงการเปลี่ยนแปลงที่สำคัญ ไม่ใช่สิ่งรบกวน
diff แสดงอะไร
เครื่องมือ diff ส่วนใหญ่ รวมถึงเครื่องมือเปรียบเทียบข้อความของ LeedyBox เปรียบเทียบข้อความทีละบรรทัด แต่ละบรรทัดในผลลัพธ์เป็นหนึ่งในสามประเภท ได้แก่ ไม่เปลี่ยนแปลง (มีในทั้งสองเวอร์ชัน) ถูกลบ (มีเฉพาะในต้นฉบับ) หรือถูกเพิ่ม (มีเฉพาะในเวอร์ชันใหม่) ไม่มีประเภท “ถูกแก้ไข” แยกต่างหาก บรรทัดที่คุณแก้คำเดียวจึงปรากฏสองครั้ง ครั้งหนึ่งเป็นบรรทัดที่ถูกลบ และอีกครั้งเป็นบรรทัดที่ถูกเพิ่ม
Dear customer,
- Your order ships on Monday.
+ Your order ships on Tuesday.
Kind regards
เครื่องหมายเป็นไปตามแบบแผนเก่า - สำหรับถูกลบ + สำหรับถูกเพิ่ม และช่องว่างสำหรับบรรทัดที่ไม่เปลี่ยนแปลง สีซึ่งมักเป็นแดงและเขียวก็บอกข้อมูลเดียวกันซ้ำอีกครั้ง
บรรทัดถูกจับคู่อย่างไร
เครื่องมือ diff หาลำดับบรรทัดที่ยาวที่สุดซึ่งปรากฏในทั้งสองข้อความตามลำดับเดียวกัน เรียกว่าลำดับย่อยร่วมที่ยาวที่สุด บรรทัดเหล่านั้นคงเป็นบรรทัดที่ไม่เปลี่ยนแปลง ส่วนบรรทัดอื่นถูกทำเครื่องหมายเป็นถูกลบหรือถูกเพิ่ม หากต้นฉบับคือ A, B, C, D และข้อความใหม่คือ A, C, B, D ลำดับร่วมที่ยาวที่สุดมีสามบรรทัด เช่น A, B, D ดังนั้น C จึงดูเหมือนถูกย้าย คือถูกลบที่หนึ่งและถูกเพิ่มอีกที่หนึ่ง
บ่อยครั้งมีคำตอบหลายแบบที่ยาวเท่ากัน และแต่ละเครื่องมือเลือกต่างกัน นี่คือเหตุที่ไฟล์คู่เดียวกันอาจให้ diff ต่างกันเล็กน้อยในสองโปรแกรม Git ใช้อัลกอริทึม Myers เป็นค่าเริ่มต้น และมี patience กับ histogram เป็นทางเลือก ซึ่งมักให้ผลที่อ่านง่ายกว่าสำหรับโค้ดที่มีบรรทัดซึ่งมีแค่วงเล็บปีกกาปิดจำนวนมาก
การหาลำดับร่วมที่ยาวที่สุดต้องใช้งานที่เพิ่มขึ้นตามจำนวนบรรทัดของข้อความหนึ่งคูณกับจำนวนบรรทัดของอีกข้อความ เครื่องมือของ LeedyBox จะแยกบรรทัดที่เหมือนกันตอนต้นและตอนท้ายออกก่อน เปรียบเทียบส่วนที่เหลือ และหยุดพร้อมข้อความแจ้งหากผลคูณนั้นเกิน 4,000,000 เช่น บรรทัดที่ต่างกันราว 2,000 ต่อ 2,000 บรรทัด
อ่าน unified diff จาก git และการรีวิวโค้ด
ระบบควบคุมเวอร์ชันแสดงเฉพาะส่วนของไฟล์ที่เปลี่ยน ในรูปแบบ unified diff
--- a/config.yml
+++ b/config.yml
@@ -12,4 +12,5 @@
server:
- port: 8080
+ port: 8081
+ timeout: 30
database:
บรรทัด --- และ +++ ระบุไฟล์เก่าและไฟล์ใหม่ ส่วนหัวของกลุ่ม @@ -12,4 +12,5 @@ หมายความว่า กลุ่มนี้เริ่มที่บรรทัด 12 และครอบคลุม 4 บรรทัดในไฟล์เก่า และเริ่มที่บรรทัด 12 และครอบคลุม 5 บรรทัดในไฟล์ใหม่ บรรทัดที่ไม่เปลี่ยนแปลงรอบ ๆ แต่ละการเปลี่ยนแปลง ซึ่งค่าเริ่มต้นคือสามบรรทัด ทำหน้าที่ให้บริบท เครื่องมือที่แสดงข้อความทั้งหมด เช่น ของ LeedyBox ไม่มีส่วนหัวของกลุ่มเพราะเห็นทุกบรรทัดอยู่แล้ว และด้วยเหตุเดียวกัน ผลลัพธ์จึงนำไปใช้เป็นแพตช์ไม่ได้
เตรียมข้อความเพื่อการเปรียบเทียบที่มีประโยชน์
diff เปรียบเทียบอักขระ ไม่ใช่ความหมาย ความต่างเล็ก ๆ ที่มองไม่เห็นทำให้บรรทัดไม่ตรงกัน และอาจกลบการเปลี่ยนแปลงจริง
- ช่องว่างและแท็บ ที่ท้ายบรรทัด หรือเวอร์ชันหนึ่งใช้แท็บแต่อีกเวอร์ชันใช้ช่องว่าง ให้ลบช่องว่างท้ายบรรทัดและใช้การเยื้องแบบเดียวกันทั้งสองเวอร์ชัน
- อักขระที่มองไม่เห็น เช่น ช่องว่างไม่ตัดบรรทัดหรือช่องว่างความกว้างศูนย์ ซึ่งพบบ่อยในข้อความที่คัดลอกจากหน้าเว็บและโปรแกรมประมวลผลคำ ข้อความภาษาไทยที่ผ่านเครื่องมือตัดคำบางตัวอาจมีช่องว่างความกว้างศูนย์แทรกระหว่างคำด้วย
- รูปแบบ Unicode ตัวอักษรที่มีเครื่องหมายเสริม เช่น é อาจเก็บเป็นอักขระเดียว หรือเป็น e บวกเครื่องหมายผสม ข้อความจากชื่อไฟล์ใน macOS หรือ PDF บางไฟล์มักใช้แบบที่สอง
- เครื่องหมายคำพูดแบบโค้งและขีดยาว โปรแกรมประมวลผลคำเปลี่ยน " เป็น “ ” และ - เป็น – สำเนาที่วางจึงไม่ตรงกับข้อความธรรมดาต้นฉบับอีกต่อไป
- การขึ้นบรรทัดใหม่ Windows จบบรรทัดด้วย CR LF ส่วน macOS และ Linux ใช้ LF เบราว์เซอร์แปลงการขึ้นบรรทัดใหม่ทุกครั้งในช่องข้อความเป็น LF ความต่างนี้จึงไม่ปรากฏในเครื่องมือของ LeedyBox แต่ปรากฏในเครื่องมือที่เปรียบเทียบไฟล์โดยตรง
- การจัดรูปแบบข้อมูลและโค้ด JSON ที่เยื้องใหม่หรือเรียงคีย์ต่างกันทำให้แทบทุกบรรทัดต่างกัน ให้จัดรูปแบบทั้งสองเวอร์ชันแบบเดียวกันก่อน เช่น เรียงคีย์และใช้การเยื้องเดียวกัน
การเปรียบเทียบข้อความร้อยแก้ว
ในเอกสารทั่วไป ย่อหน้าทั้งย่อหน้ามักเป็นบรรทัดยาวบรรทัดเดียว การแก้คำเดียวจึงทำให้ทั้งย่อหน้าถูกทำเครื่องหมายว่าถูกลบและถูกเพิ่ม มีสองวิธีที่ช่วยได้ ก่อนเปรียบเทียบ ให้แยกแต่ละประโยคไว้คนละบรรทัด เพื่อให้เห็นเฉพาะประโยคที่เปลี่ยน หรือใช้เครื่องมือที่เปรียบเทียบคำภายในบรรทัด เช่น git diff --word-diff หรือฟีเจอร์เปรียบเทียบพร้อมติดตามการเปลี่ยนแปลงในโปรแกรมประมวลผลคำ ภาษาไทยไม่เว้นวรรคระหว่างคำ การเปรียบเทียบระดับคำจึงขึ้นอยู่กับว่าเครื่องมือตัดคำภาษาไทยได้ดีเพียงใด
ข้อความที่คัดลอกจาก PDF มีกับดักของตัวเอง บรรทัดถูกตัดตรงที่เลย์เอาต์ของหน้าตัด และคำอาจถูกตัดด้วยยัติภังค์ที่ท้ายบรรทัด ให้ต่อบรรทัดของแต่ละย่อหน้ากลับก่อนเปรียบเทียบกับเอกสารต้นทาง
สิ่งที่ diff แบบบรรทัดบอกไม่ได้
- การย้าย ย่อหน้าที่ถูกย้ายไปที่อื่นปรากฏเป็นถูกลบที่หนึ่งและถูกเพิ่มอีกที่หนึ่ง บางเครื่องมือ เช่น git กับ
--color-movedทำเครื่องหมายบล็อกที่ถูกย้ายแยกต่างหาก - ความหมาย ข้อความสองชิ้นที่บอกสิ่งเดียวกันด้วยคำต่างกันจะต่างกันทั้งหมด และการเปลี่ยนเพียงอักขระเดียว เช่น คำว่า “ไม่” ที่หายไป ดูเล็กน้อยแต่อาจกลับความหมายของประโยค
- เนื้อหาไบนารี เอกสาร Word, PDF และรูปภาพไม่ใช่ข้อความธรรมดา ให้ดึงข้อความออกมาก่อน หรือใช้ฟีเจอร์เปรียบเทียบของโปรแกรมที่สร้างไฟล์นั้น
ความเป็นส่วนตัวเมื่อเปรียบเทียบเอกสาร
สัญญา ไฟล์การตั้งค่า และล็อก มักมีชื่อ คีย์ หรือรหัสผ่าน บริการเปรียบเทียบออนไลน์บางแห่งเก็บข้อความที่วางไว้บนเซิร์ฟเวอร์ บางครั้งพร้อมลิงก์ที่แชร์ได้ เครื่องมือเปรียบเทียบข้อความของ LeedyBox ทำงานในเบราว์เซอร์ของคุณ และไม่ส่งหรือเก็บข้อความ แต่ก็ยังเป็นนิสัยที่ดีที่จะลบความลับออกก่อนวางไฟล์การตั้งค่าไม่ว่าที่ใด
คำถามที่พบบ่อย
ทำไมทั้งย่อหน้าถูกทำเครื่องหมายว่าเปลี่ยน ทั้งที่ฉันแก้แค่คำเดียว
ย่อหน้านั้นเป็นบรรทัดเดียว และ diff แบบบรรทัดเปรียบเทียบทั้งบรรทัด ให้แยกข้อความเป็นประโยคหรือบรรทัดที่สั้นลงก่อนเปรียบเทียบ หรือใช้การเปรียบเทียบระดับคำ
ละเว้นความต่างของช่องว่างได้ไหม
เครื่องมือของ LeedyBox เปรียบเทียบบรรทัดแบบตรงทุกอักขระ ให้ทำความสะอาดข้อความทั้งสองก่อน เช่น ลบช่องว่างท้ายบรรทัดและเปลี่ยนแท็บเป็นช่องว่าง สำหรับไฟล์ git มีตัวเลือกอย่าง --ignore-space-change
เปรียบเทียบเอกสาร Word สองไฟล์อย่างไร
Word มีฟีเจอร์เปรียบเทียบในตัวซึ่งแสดงการเปลี่ยนแปลงการจัดรูปแบบด้วย หากต้องการเปรียบเทียบเฉพาะเนื้อความ ให้คัดลอกข้อความของทั้งสองเอกสารไปยังเครื่องมือเปรียบเทียบข้อความ
การผสานแบบสามทาง (three-way merge) คืออะไร
เมื่อสองคนแก้ไขต้นฉบับเดียวกัน เครื่องมือผสานจะเปรียบเทียบแต่ละเวอร์ชันกับต้นฉบับร่วม การเปลี่ยนแปลงในตำแหน่งต่างกันถูกรวมโดยอัตโนมัติ ส่วนการเปลี่ยนแปลงในบรรทัดเดียวกันถูกรายงานเป็นความขัดแย้งที่ต้องมีคนแก้