กลับไปหน้าบทความ

อ่าน 11 นาที

ความแตกต่าง

diff diff เป็น คำสั่ง เชลล์ ที่ ใช้เปรียบเทียบ เนื้อหาของไฟล์และรายงานความแตกต่าง คำว่า diff ยังใช้เพื่อระบุผลลัพธ์ของคำสั่งและ ใช้เป็นคำกริยา ในการเรียกใช้คำสั่ง...

ความแตกต่าง

ความแตกต่าง
ผู้เขียนต้นฉบับดักลาส แมคอิลรอย ( เอทีแอนด์ที เบลล์ แล็บโบราทอรีส์ )
นักพัฒนานักพัฒนาซอฟต์แวร์โอเพนซอร์สและเชิงพาณิชย์หลายราย
ปล่อยมิถุนายน พ.ศ. 2517 ( มิถุนายน 1974 )
เขียนเป็นซี
ระบบปฏิบัติการยูนิก , ระบบปฏิบัติการคล้ายยูนิก , V , Plan 9 , อินเฟอร์โน
แพลตฟอร์มข้ามแพลตฟอร์ม
พิมพ์สั่งการ
ใบอนุญาตแผนที่ 9: ใบอนุญาต MIT

diffdiff เป็นคำสั่งเชลล์ ที่ใช้เปรียบเทียบเนื้อหาของไฟล์และรายงานความแตกต่าง คำว่าdiffยังใช้เพื่อระบุผลลัพธ์ของคำสั่งและใช้เป็นคำกริยาในการเรียกใช้คำสั่ง ในการเปรียบเทียบไฟล์ ให้เรียกใช้ diff เพื่อสร้าง diff [ 1 ]

โดยทั่วไป คำสั่งนี้ใช้สำหรับเปรียบเทียบไฟล์ข้อความแต่ก็รองรับการเปรียบเทียบไฟล์ไบนารีด้วย หากไฟล์อินพุตไฟล์ใดไฟล์หนึ่งมีข้อมูลที่ไม่ใช่ข้อความ คำสั่งจะเปลี่ยนไปใช้โหมดย่อโดยค่าเริ่มต้น โดยจะรายงานเฉพาะข้อสรุปว่าไฟล์ทั้งสองแตกต่างกันหรือไม่ หากใช้--textตัวเลือกนี้ จะรายงานความแตกต่างตามบรรทัดเสมอ อย่างไรก็ตาม ผลลัพธ์อาจเข้าใจยาก เนื่องจากข้อมูลไบนารีโดยทั่วไปไม่ได้มีโครงสร้างเป็นบรรทัดเหมือนข้อความ[ 2 ]

แม้ว่าคำสั่งนี้จะใช้เป็นหลักในการวิเคราะห์การเปลี่ยนแปลงระหว่างไฟล์สองไฟล์แบบเฉพาะกิจ แต่การใช้งานพิเศษอย่างหนึ่งคือการสร้างไฟล์แพทช์เพื่อใช้กับpatchคำสั่งนี้ ซึ่งได้รับการออกแบบมาโดยเฉพาะเพื่อใช้รายงานเอาต์พุต diff เป็นไฟล์แพทช์ มาตรฐาน POSIXได้กำหนดมาตรฐาน คำสั่ง diffและpatchรวมถึงรูปแบบไฟล์ที่ใช้ร่วมกัน[ 3 ]

ประวัติศาสตร์

ยูทิลิตี้diff ดั้งเดิมได้รับการพัฒนาในช่วงต้นทศวรรษ 1970 สำหรับระบบปฏิบัติการ Unix ที่Bell Labsใน Murray Hill รัฐนิวเจอร์ซีย์ เป็นส่วนหนึ่งของ Unix รุ่นที่ 5 ที่วางจำหน่ายในปี 1974 [ 4 ]และเขียนโดยDouglas McIlroyและJames Huntงานวิจัยนี้ได้รับการตีพิมพ์ในบทความปี 1976 ซึ่งเขียนร่วมกับ James W. Hunt ผู้พัฒนาต้นแบบเริ่มต้นของdiff [ 5 ] อัลกอริทึมที่อธิบายไว้ในบทความนี้กลายเป็นที่รู้จักในชื่อ อั ลก อริทึม Hunt–Szymanski

งานของ McIlroy ได้รับอิทธิพลและต่อยอดมาจากโปรแกรมเปรียบเทียบของSteve Johnson บน GECOSและโปรแกรมพิสูจน์ของMike Lesk โปรแกรม พิสูจน์ ก็มีต้นกำเนิดบน Unix เช่นกัน และเช่นเดียวกับdiffมันสร้างการเปลี่ยนแปลงแบบบรรทัดต่อบรรทัด และยังใช้เครื่องหมายวงเล็บมุม (">" และ "<") เพื่อระบุการแทรกและการลบบรรทัดในผลลัพธ์ของโปรแกรม อย่างไรก็ตาม วิธีการเชิงอนุมานที่ใช้ในแอปพลิเคชันยุคแรกเหล่านี้ถูกมองว่าไม่น่าเชื่อถือ ประโยชน์ที่เป็นไปได้ของเครื่องมือ diff ทำให้ McIlroy ค้นคว้าและออกแบบเครื่องมือที่แข็งแกร่งกว่าสำหรับงานต่างๆ ที่สามารถทำงานได้ดีภายใต้ข้อจำกัดด้านการประมวลผลและขนาดของ ฮาร์ดแวร์ PDP-11แนวทางของเขาในการแก้ปัญหานี้เกิดจากการทำงานร่วมกับบุคคลต่างๆ ที่ Bell Labs รวมถึงAlfred Aho , Elliot Pinson, Jeffrey Ullmanและ Harold S. Stone

ในบริบทของ Unix การใช้ โปรแกรมแก้ไขบรรทัด edทำให้diffมีความสามารถโดยธรรมชาติในการสร้าง "สคริปต์แก้ไข" ที่เครื่องสามารถใช้งานได้ สคริปต์แก้ไขเหล่านี้ เมื่อบันทึกไว้ในไฟล์ สามารถนำกลับมารวมกับไฟล์ต้นฉบับ และรวมเข้ากับไฟล์ที่แก้ไขแล้วได้อย่างสมบูรณ์โดยedซึ่งช่วยลดพื้นที่จัดเก็บข้อมูลสำรองที่จำเป็นในการเก็บรักษาไฟล์หลายเวอร์ชันได้อย่างมาก McIlroy เคยพิจารณาที่จะเขียนโปรแกรมประมวลผลหลังการทำงานสำหรับdiffที่สามารถออกแบบและใช้งานรูปแบบเอาต์พุตที่หลากหลายได้ อย่างไรก็ตาม เขาพบว่าการให้diffรับผิดชอบในการสร้างไวยากรณ์และลำดับการป้อนข้อมูลแบบย้อนกลับที่คำสั่ง ed ยอมรับนั้นประหยัดและง่ายกว่า

ในปี พ.ศ. 2527 Larry Wallได้สร้าง ยูทิลิตี้ patch (เผยแพร่ซอร์สโค้ดบนกลุ่มข่าวmod.sourcesและnet.sources [ 6 ] [ 7 ] [ 8 ] ) สำหรับการแก้ไขไฟล์ข้อความ โดยใช้เอาต์พุตจากdiffบวกกับไฟล์อินพุต diff ที่มีเนื้อหาก่อนการเปลี่ยนแปลงเพื่อสร้างไฟล์ที่มีเนื้อหาหลังการเปลี่ยนแปลง

คู่มือการพกพา X/Openฉบับที่ 2 ของปี 1987 มีความแตกต่างของโหมดบริบท โหมดบริบทถูกเพิ่มใน POSIX.1-2001 (ฉบับที่ 6) โหมดรวมถูกเพิ่มใน POSIX.1-2008 (ฉบับที่ 7) [ 9 ]

ใน ช่วงแรกๆ การใช้งานทั่วไปของ diffได้แก่ การเปรียบเทียบการเปลี่ยนแปลงในซอร์สโค้ดซอฟต์แวร์และมาร์กอัปสำหรับเอกสารทางเทคนิค การตรวจสอบเอาต์พุตการดีบักโปรแกรม การเปรียบเทียบรายการระบบไฟล์ และการวิเคราะห์โค้ดแอสเซมบลีของคอมพิวเตอร์ เอาต์พุตที่มุ่งเป้าไปที่edมีแรงจูงใจเพื่อให้การบีบอัดสำหรับลำดับการแก้ไขที่ทำกับไฟล์[ 10 ]ระบบควบคุมซอร์สโค้ด (SCCS) และความสามารถในการเก็บถาวรการแก้ไขเกิดขึ้นในช่วงปลายทศวรรษ 1970 อันเป็น ผลมาจากการจัดเก็บสคริปต์แก้ไขจากdiff

อัลกอริทึม

แตกต่างจาก แนวคิด ระยะห่างการแก้ไขที่ใช้เพื่อวัตถุประสงค์อื่นdiffระยะห่างการแก้ไขจะเน้นที่บรรทัดมากกว่าตัวอักษร แต่ก็คล้ายกับระยะห่างของ Levenshteinตรงที่พยายามหาชุดการลบและการแทรกที่เล็กที่สุดเพื่อสร้างไฟล์หนึ่งจากอีกไฟล์หนึ่ง

การดำเนินการdiffขึ้นอยู่กับการแก้ปัญหาลำดับย่อยร่วมที่ยาวที่สุด[ 5 ]ในปัญหานี้ กำหนดลำดับรายการสองลำดับ:

a b c d f g h j q z
a b c d e f g i j krxy z

และเราต้องการหาลำดับของรายการที่ยาวที่สุดที่ปรากฏอยู่ในลำดับดั้งเดิมทั้งสองลำดับในลำดับเดียวกัน กล่าวคือ เราต้องการหาลำดับใหม่ที่สามารถได้มาจากการลบรายการบางส่วนออกจากลำดับดั้งเดิมแรก และจากการลบรายการอื่นๆ ออกจากลำดับดั้งเดิมที่สอง นอกจากนี้เรายังต้องการให้ลำดับนี้มีความยาวมากที่สุดเท่าที่จะเป็นไปได้ ในกรณีนี้คือ

abcdfgjz 

จากการหาลำดับย่อยร่วมที่ยาวที่สุด การสร้างผลลัพธ์ที่คล้ายกับ diffนั้นทำได้ง่าย ๆ กล่าวคือ หากรายการใดไม่มีอยู่ในลำดับย่อย แต่มีอยู่ในลำดับดั้งเดิมแรก แสดงว่ารายการนั้นถูกลบออกไปแล้ว (ดังที่แสดงด้วยเครื่องหมาย '-' ด้านล่าง) และหากรายการนั้นไม่มีอยู่ในลำดับย่อย แต่มีอยู่ในลำดับดั้งเดิมที่สอง แสดงว่ารายการนั้นถูกเพิ่มเข้ามา (ดังที่แสดงด้วยเครื่องหมาย '+')

ehiqkrxy + - + - + + + + 

ใช้

คำสั่ง นี้diffรับอาร์กิวเมนต์สองตัว เช่น`<ชื่อไฟล์>`, ... diff originalnew-r

รูปแบบเอาต์พุตเริ่มต้น

ตัวอย่างด้านล่างแสดงเนื้อหาไฟล์ต้นฉบับและไฟล์ใหม่ รวมถึงdiffผลลัพธ์ที่ได้ในรูปแบบเริ่มต้น ผลลัพธ์จะแสดงด้วยการระบายสีเพื่อปรับปรุงความอ่านง่าย GNU diff สามารถระบายสีผลลัพธ์ได้เมื่อ--colorใช้ตัวเลือก เมื่อไม่ได้--colorระบุตัวเลือกใดๆ การแสดงผลสีจะถูกปิดใช้งานโดยค่าเริ่มต้น[ 11 ]

ในรูปแบบเริ่มต้นนี้aแสดงถึงการเพิ่มdแสดงถึงการลบ และcแสดงถึงการเปลี่ยนแปลง หมายเลขบรรทัดของไฟล์ต้นฉบับจะปรากฏก่อนรหัสตัวอักษรเดี่ยว และหมายเลขบรรทัดของไฟล์ใหม่จะปรากฏหลังจากนั้น เครื่องหมาย น้อยกว่าและมากกว่า (ที่ต้นบรรทัดที่เพิ่ม ลบ หรือเปลี่ยนแปลง) ระบุว่าบรรทัดนั้นอยู่ในไฟล์ใด บรรทัดที่เพิ่มจะถูกเพิ่มเข้าไปในไฟล์ต้นฉบับและปรากฏในไฟล์ใหม่ บรรทัดที่ลบจะถูกลบออกจากไฟล์ต้นฉบับและจะไม่มีอยู่ในไฟล์ใหม่

โดยค่าเริ่มต้น บรรทัดที่เหมือนกันในทั้งสองไฟล์จะไม่แสดง บรรทัดที่ย้ายจะแสดงเป็นบรรทัดที่เพิ่มเข้ามาที่ตำแหน่งใหม่และเป็นบรรทัดที่ถูกลบออกจากตำแหน่งเดิม[ 12 ]อย่างไรก็ตาม เครื่องมือเปรียบเทียบความแตกต่างบางอย่างจะเน้นบรรทัดที่ย้าย

แก้ไขสคริปต์

สคริปต์แก้ไขสามารถสร้างขึ้นได้โดยโปรแกรม diff เวอร์ชันใหม่ๆ โดยใช้-eตัวเลือกดังกล่าว สคริปต์แก้ไขที่ได้สำหรับตัวอย่างนี้มีดังนี้:

24 ก.ย่อหน้านี้มีการเพิ่มเติมข้อมูลใหม่ที่สำคัญในเอกสารนี้ . 17 ค. ตรวจสอบเอกสารนี้ . 11,15 d 0 a นี่เป็นประกาศสำคัญ! ดังนั้นควรวางไว้ที่ตอนต้นของเอกสารนี้! . 

ในการแปลงเนื้อหาของไฟล์ต้นฉบับให้เป็นเนื้อหาของไฟล์ใหม่โดยใช้edนั้น เราต้องเพิ่มสองบรรทัดลงในไฟล์ diff นี้ บรรทัดหนึ่งมีคำสั่ง (เขียน) และอีกบรรทัดหนึ่งมีคำสั่ง (ออก) (เช่น โดย) ในที่นี้เราตั้งชื่อไฟล์ diff ว่าmydiffและการแปลงจะเกิดขึ้นเมื่อเรารันคำสั่ง wqprintf"w\nq\n">>mydiffed-soriginal<mydiff

รูปแบบบริบท

การแจกจ่าย Unix ของ Berkeleyเน้นการเพิ่มรูปแบบบริบท ( -c) และความสามารถในการเรียกซ้ำบนโครงสร้างไดเร็กทอรีของระบบไฟล์ ( -r) โดยเพิ่มคุณสมบัติเหล่านี้ใน BSD 2.8 ซึ่งวางจำหน่ายในเดือนกรกฎาคม พ.ศ. 2524 รูปแบบบริบทของ diff ที่นำเสนอใน Berkeley ช่วยในการแจกจ่ายแพตช์สำหรับซอร์สโค้ดที่อาจมีการเปลี่ยนแปลงเพียงเล็กน้อย

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

จำนวนบรรทัดที่ไม่เปลี่ยนแปลงที่แสดงอยู่ด้านบนและด้านล่างของส่วน ที่เปลี่ยนแปลง นั้น ผู้ใช้สามารถกำหนดได้เอง แม้กระทั่งศูนย์บรรทัด แต่โดยทั่วไปค่าเริ่มต้นคือสามบรรทัด หากเนื้อหาของบรรทัดที่ไม่เปลี่ยนแปลงในส่วนหนึ่งทับซ้อนกับส่วนที่อยู่ติดกัน โปรแกรม diff จะหลีกเลี่ยงการทำซ้ำบรรทัดที่ไม่เปลี่ยนแปลงและรวมส่วนต่างๆ เข้าเป็นส่วนเดียว

เครื่องหมาย " !" แทนการเปลี่ยนแปลงระหว่างบรรทัดที่ตรงกันในไฟล์ทั้งสองไฟล์ ในขณะที่เครื่องหมาย " +" แทนการเพิ่มบรรทัด และเครื่องหมาย " -" แทนการลบบรรทัด ช่องว่างแทนบรรทัดที่ไม่เปลี่ยนแปลง ที่จุดเริ่มต้นของแพทช์จะมีข้อมูลไฟล์ รวมถึงเส้นทางแบบเต็มและเวลาประทับที่คั่นด้วยอักขระแท็บ ที่จุดเริ่มต้นของแต่ละส่วนจะมีหมายเลขบรรทัดที่ใช้กับการเปลี่ยนแปลงที่เกี่ยวข้องในไฟล์ ช่วงหมายเลขที่ปรากฏระหว่างชุดเครื่องหมายดอกจันสามตัวจะใช้กับไฟล์ต้นฉบับ ชุดเครื่องหมายขีดสามตัวจะใช้กับไฟล์ใหม่ ช่วงของส่วนจะระบุหมายเลขบรรทัดเริ่มต้นและสิ้นสุดในไฟล์นั้นๆ

คำสั่งนี้diff -c original newจะสร้างผลลัพธ์ดังต่อไปนี้:

*** /path/to/original timestamp --- /path/to/new timestamp *************** *** 1,3 **** --- 1,9 ---- + นี่คือประกาศสำคัญ! ดังนั้นจึงควร+ วางไว้ที่+ ต้น+ เอกสารนี้! +ส่วนนี้ของ เอกสารยังคง เหมือนเดิมตั้งแต่เวอร์ชันถึง *************** *** 8.20 **** ลดขนาดของ การเปลี่ยนแปลงลง - ย่อหน้านี้มีข้อความที่ล้าสมัย- จะถูกลบออกในอนาคตอันใกล้นี้การสะกดคำนั้นสำคัญ ! ตรวจสอบเอกสารนี้ด้วย อย่างไรก็ตาม การ สะกดคำผิดไม่ใช่ เรื่องใหญ่โตอะไร --- 14,21 ----บีบอัดขนาดของ การเปลี่ยนแปลง การสะกดคำนั้นสำคัญมาก ! โปรดตรวจสอบเอกสารนี้อย่างไรก็ตาม การสะกดคำผิดเพียงเล็กน้อยก็ไม่ใช่ เรื่องใหญ่โตอะไร *************** *** 22,24 **** --- 23,29 ----ย่อหน้านี้จำเป็นต้อง แก้ไข สามารถ เพิ่มสิ่งต่างๆ ต่อท้ายได้ + + ย่อหน้านี้มี+ ส่วนเพิ่มเติมใหม่ที่สำคัญ+ ในเอกสารนี้

รูปแบบรวม

รูปแบบรวม (หรือunidiff ) [ 13 ] [ 14 ]สืบทอดการปรับปรุงทางเทคนิคที่ทำโดยรูปแบบบริบท แต่สร้าง diff ที่เล็กกว่าโดยมีข้อความเก่าและใหม่แสดงอยู่ติดกันทันที รูปแบบรวมมักจะถูกเรียกใช้โดยใช้ตัวเลือกบรรทัดคำสั่ง-u " " เอาต์พุตนี้มักใช้เป็นอินพุตสำหรับ โปรแกรม แพทช์ โครงการหลายโครงการร้องขอให้ส่ง "diffs" ในรูปแบบรวมโดยเฉพาะ ทำให้รูปแบบ unified diff เป็นรูปแบบที่พบบ่อยที่สุดสำหรับการแลกเปลี่ยนระหว่างนักพัฒนาซอฟต์แวร์

รูปแบบการเปรียบเทียบความแตกต่างแบบรวมบริบท (Unified context diffs) ถูกพัฒนาขึ้นครั้งแรกโดย Wayne Davison ในเดือนสิงหาคม 1990 (ในunidiffซึ่งปรากฏใน comp.sources.misc เล่มที่ 14) Richard Stallmanได้เพิ่มการรองรับการเปรียบเทียบความแตกต่างแบบรวมบริบทให้กับ diff ของ โครงการ GNU ในอีกหนึ่งเดือนต่อมา ฟีเจอร์นี้เปิดตัวครั้งแรกใน GNU diff 1.15 ซึ่งวางจำหน่ายในเดือนมกราคม 1991 ตั้งแต่นั้นมา GNU diff ได้ขยายรูปแบบบริบทเพื่อให้สามารถจัดรูปแบบการเปรียบเทียบความแตกต่างได้ตามต้องการ

รูปแบบเริ่มต้นด้วย ส่วนหัวสองบรรทัดเช่นเดียวกับรูปแบบบริบท ยกเว้นว่าไฟล์ต้นฉบับจะนำหน้าด้วย "---" และไฟล์ใหม่จะนำหน้าด้วย "+++"ถัดจากนี้จะเป็นส่วนที่มีการเปลี่ยนแปลง อย่างน้อยหนึ่งส่วน ซึ่งประกอบด้วยความแตกต่างของบรรทัดในไฟล์ อักขระเว้นวรรคจะอยู่หน้าบรรทัดที่ไม่เปลี่ยนแปลงตามบริบท เครื่องหมายบวกจะอยู่หน้าบรรทัดที่เพิ่มเข้ามา และเครื่องหมายลบจะอยู่หน้าบรรทัดที่ลบออก"

ส่วนหนึ่งของข้อมูลจะเริ่มต้นด้วยข้อมูลช่วงโดยจะอยู่ก่อนหน้าการเพิ่มบรรทัด การลบบรรทัด และบรรทัดบริบทต่างๆ ข้อมูลช่วงจะล้อมรอบด้วยเครื่องหมาย @ สองตัว และรวมสิ่งที่ปรากฏในสองบรรทัดในรูปแบบบริบท ( ด้านบน ) ไว้ในบรรทัดเดียวรูปแบบของบรรทัดข้อมูลช่วงมีดังนี้:

@@ -l,s +l,s @@ หัวข้อส่วนเสริม

ข้อมูลช่วงส่วนย่อย (hunk range) ประกอบด้วยช่วงส่วนย่อยสองช่วง เครื่องหมายลบนำหน้าช่วงสำหรับส่วนย่อยของไฟล์ต้นฉบับ และเครื่องหมายบวกนำหน้าช่วงสำหรับส่วนย่อยของไฟล์ใหม่ แต่ละช่วงส่วนย่อยมีรูปแบบl,sโดยที่lคือหมายเลขบรรทัดเริ่มต้น และsคือจำนวนบรรทัดที่ส่วนย่อยที่เปลี่ยนแปลงนั้นใช้กับไฟล์แต่ละไฟล์ ใน GNU diff หลายเวอร์ชัน แต่ละช่วงสามารถละเว้นเครื่องหมายจุลภาคและค่าs ที่ต่อท้ายได้ ในกรณีนี้sจะมีค่าเริ่มต้นเป็น 1 โปรดทราบว่าค่าที่น่าสนใจจริงๆ มีเพียงค่าl ซึ่งเป็น หมายเลขบรรทัดของช่วงแรกเท่านั้น ค่าอื่นๆ ทั้งหมดสามารถคำนวณได้จาก diff

ช่วงของส่วนข้อมูล (hunk range) สำหรับไฟล์ต้นฉบับควรเป็นผลรวมของบรรทัดส่วนข้อมูลตามบริบทและการลบ (รวมถึงส่วนที่เปลี่ยนแปลง) ทั้งหมด ส่วนช่วงของส่วนข้อมูลสำหรับไฟล์ใหม่ควรเป็นผลรวมของบรรทัดส่วนข้อมูลตามบริบทและการเพิ่ม (รวมถึงส่วนที่เปลี่ยนแปลง) ทั้งหมด หากข้อมูลขนาดของส่วนข้อมูลไม่ตรงกับจำนวนบรรทัดในส่วนข้อมูลนั้น การเปรียบเทียบอาจถือว่าไม่ถูกต้องและถูกปฏิเสธ

โดยเลือกได้ว่าช่วงของส่วนย่อยจะตามด้วยหัวข้อของส่วนหรือฟังก์ชันที่ส่วนย่อยนั้นเป็นส่วนหนึ่ง ซึ่งส่วนใหญ่จะช่วยให้อ่านความแตกต่างได้ง่ายขึ้น เมื่อสร้างความแตกต่างด้วย GNU diff หัวข้อจะถูกระบุโดยการจับคู่แบบนิพจน์ปกติ[ 15 ]

หากมีการแก้ไขบรรทัด จะแสดงเป็นการลบและการเพิ่ม เนื่องจากส่วนของไฟล์ต้นฉบับและไฟล์ใหม่ปรากฏอยู่ในส่วนเดียวกัน การเปลี่ยนแปลงดังกล่าวจึงจะปรากฏอยู่ติดกัน[ 16 ] ตัวอย่างต่อไปนี้แสดงให้เห็นถึงกรณีดังกล่าว:

-ตรวจสอบเอกสารนี้ +ตรวจสอบเอกสารนี้ด้วย 

คำสั่งนี้diff -u original newจะสร้างผลลัพธ์ดังต่อไปนี้:

--- /path/to/original timestamp +++ /path/to/new timestamp @@ -1,3 +1,9 @@ +นี่คือประกาศสำคัญ! ดังนั้นควรอยู่ตอนต้นของเอกสารนี้! +ส่วนนี้ของ เอกสารยังคงเหมือน เดิมตั้งแต่เวอร์ชันถึง @@ -8,13 +14,8 @@บีบอัดขนาดของ การเปลี่ยนแปลง -ย่อหน้านี้มีข้อความที่ล้าสมัย - จะถูกลบในอนาคตอันใกล้นี้- การตรวจสอบการสะกดคำ ในเอกสารนี้เป็นสิ่งสำคัญ โปรด ตรวจสอบเอกสารนี้อีกครั้ง อย่างไรก็ตาม คำที่สะกดผิดไม่ใช่ เรื่องใหญ่โตอะไร @@ -22,3 +23,7 @@ย่อหน้านี้จำเป็นต้อง แก้ไข สามารถ เพิ่มสิ่งต่างๆ ต่อท้ายได้ + +ย่อหน้านี้มีการเพิ่มเติมใหม่ที่สำคัญในเอกสารนี้

เพื่อให้สามารถแยกชื่อไฟล์ออกจากเวลาได้อย่างถูกต้อง จะใช้ตัวอักษรแท็บเป็นตัวคั่น ซึ่งตัวอักษรแท็บนี้มองไม่เห็นบนหน้าจอ และอาจหายไปเมื่อคัดลอกและวางส่วนต่างจากหน้าจอคอนโซล/เทอร์มินัล

ส่วนขยาย

รูปแบบการเปรียบเทียบความแตกต่าง (diff) มีการดัดแปลงและเพิ่มเติมบางอย่างที่โปรแกรมบางโปรแกรมและในบริบทเฉพาะใช้และเข้าใจ ตัวอย่างเช่น ระบบ ควบคุมเวอร์ชัน บางระบบ เช่นSubversionระบุหมายเลขเวอร์ชัน "สำเนาใช้งาน" หรือข้อความแสดงความคิดเห็นอื่นๆ แทนหรือเพิ่มเติมจากเวลาในส่วนหัวของการเปรียบเทียบความแตกต่าง

เครื่องมือบางอย่างอนุญาตให้รวมส่วนต่างของไฟล์หลายไฟล์เข้าด้วยกัน โดยใช้ส่วนหัวสำหรับแต่ละไฟล์ที่แก้ไข ซึ่งอาจมีลักษณะดังนี้:

ดัชนี: path/to/file.cpp 

กรณีพิเศษของไฟล์ที่ไม่มีบรรทัดใหม่ท้ายไฟล์ไม่ได้รับการจัดการ ทั้ง มาตรฐาน unidiffPOSIX และตัวแก้ไข ไม่ diffได้กำหนดวิธีการจัดการไฟล์ประเภทนี้ (อันที่จริง ไฟล์ดังกล่าวไม่ใช่ไฟล์ "ข้อความ" ตามคำจำกัดความที่เข้มงวดของ POSIX [ 17 ] ) GNU diff และ git จะแสดงข้อความวินิจฉัยว่า "ไม่มีบรรทัดใหม่ที่ท้ายไฟล์" (หรือเวอร์ชันที่แปลแล้ว) แต่พฤติกรรมนี้ไม่สามารถพกพาได้[ 18 ] GNU patch ดูเหมือนจะไม่จัดการกรณีนี้ ในขณะที่ git-apply จัดการได้[ 19 ]

โปรแกรมpatchไม่จำเป็นต้องรับรู้เอาต์พุต diff เฉพาะการใช้งาน อย่างไรก็ตาม GNU patch รับรู้ git patches และจะดำเนินการแตกต่างออกไปเล็กน้อย[ 20 ]

การเปลี่ยนแปลงตั้งแต่ปี 1975 รวมถึงการปรับปรุงอัลกอริทึมหลัก การเพิ่มคุณสมบัติที่มีประโยชน์ให้กับคำสั่ง และการออกแบบรูปแบบเอาต์พุตใหม่ อัลกอริทึมพื้นฐานอธิบายไว้ในเอกสารAn O(ND) Difference Algorithm and its VariationsโดยEugene W. Myers [ 21 ] และในA File Comparison Programโดย Webb Miller และ Myers [ 22 ] อัลกอริทึมนี้ถูกค้นพบและอธิบายโดยอิสระในAlgorithms for Approximate String MatchingโดยEsko Ukkonen [ 23 ] โปรแกรม diff รุ่นแรกๆ ถูกออกแบบมาสำหรับการเปรียบเทียบบรรทัดของไฟล์ข้อความ โดยคาดหวังว่า อักขระขึ้นบรรทัด ใหม่จะใช้เป็นตัวแบ่งบรรทัด ในช่วงทศวรรษ 1980 การสนับสนุนไฟล์ไบนารีทำให้การออกแบบและการใช้งานของแอปพลิเคชันเปลี่ยนไป

GNU diff และ diff3 รวมอยู่ใน แพ็คเกจ diffutils พร้อมกับ ยูทิลิตี้อื่นๆ ที่เกี่ยวข้องกับdiff และpatch [ 24 ]

ตัวจัดรูปแบบและส่วนหน้า

โปรแกรมประมวลผลหลังการพิมพ์sdiffและdiffmkแสดงรายการความแตกต่างแบบเคียงข้างกันและใส่เครื่องหมายการเปลี่ยนแปลงลงในเอกสารที่พิมพ์ตามลำดับ ทั้งสองโปรแกรมได้รับการพัฒนาขึ้นที่อื่นใน Bell Labs ในปี 1981 หรือก่อนหน้านั้น

Diff3เปรียบเทียบไฟล์หนึ่งไฟล์กับไฟล์อื่นอีกสองไฟล์โดยการประสานความแตกต่างสองรายการ เดิมทีคิดค้นโดย Paul Jensen เพื่อประสานการเปลี่ยนแปลงที่ทำโดยบุคคลสองคนที่แก้ไขซอร์สโค้ดเดียวกัน นอกจากนี้ยังใช้โดยระบบควบคุมเวอร์ชัน เช่นRCSสำหรับการรวม[ 25 ]

Emacsมีฟังก์ชัน Ediffซึ่งแสดงการเปลี่ยนแปลงที่แพทช์จะสร้างขึ้นในอินเทอร์เฟซผู้ใช้ที่ผสมผสานความสามารถในการแก้ไขแบบโต้ตอบและการรวมไฟล์แพทช์เข้าด้วยกัน

Vimมีvimdiffสำหรับเปรียบเทียบไฟล์ตั้งแต่สองถึงแปดไฟล์ โดยจะไฮไลต์ความแตกต่างด้วยสี[ 26 ] แม้ว่าในอดีตจะเรียกใช้โปรแกรม diff แต่ Vim รุ่นใหม่ใช้ โค้ดไลบรารี xdiff เวอร์ชันของ git (LibXDiff) ซึ่งให้ความเร็วและฟังก์ชันการทำงานที่ดีขึ้น[ 27 ]

GNU Wdiff [ 28 ]เป็นส่วนหน้าของ diff ที่แสดงคำหรือวลีที่เปลี่ยนแปลงในเอกสารข้อความภาษาเขียน แม้จะมีการตัดคำหรือความกว้างคอลัมน์ที่แตกต่างกันก็ตาม

colordiff เป็นตัวห่อหุ้ม Perl สำหรับ 'diff' ที่สร้างเอาต์พุตเดียวกัน แต่มีการระบายสีสำหรับส่วนที่เพิ่มและลบ[ 29 ] diff-so-fancy และ diff-highlight เป็นตัวที่คล้ายกันที่ใหม่กว่า[ 30 ] "delta" เป็นการเขียนใหม่ด้วย Rust ที่เน้นการเปลี่ยนแปลงและโค้ดพื้นฐานในเวลาเดียวกัน[ 31 ]

Patchutilsมีเครื่องมือที่รวม จัดเรียงใหม่ เปรียบเทียบ และแก้ไขความแตกต่างของบริบทและความแตกต่างแบบรวม[ 32 ]

อนุพันธ์เชิงอัลกอริทึม

ยูทิลิตี้ที่เปรียบเทียบไฟล์ต้นฉบับตามโครงสร้างทางไวยากรณ์ส่วนใหญ่ถูกสร้างขึ้นเป็นเครื่องมือวิจัยสำหรับภาษาโปรแกรมบางภาษา[ 33 ] [ 34 ] [ 35 ]บางส่วนมีให้บริการเป็นเครื่องมือเชิงพาณิชย์[ 36 ] [ 37 ]นอกจากนี้ เครื่องมือฟรีที่ทำการเปรียบเทียบแบบรู้ไวยากรณ์ ได้แก่:

  • C++: zograscope ที่ใช้ AST [ 38 ]
  • HTML: Daisydiff, [ 39 ] html-differ
  • XML: xmldiffpatchโดย Microsoft และxmldiffmergeสำหรับ IBM [ 40 ] [ 41 ]
  • JavaScript : astii (อิงตาม AST)
  • หลายภาษา: Pretty Diff (จัดรูปแบบโค้ดแล้วจึงเปรียบเทียบความแตกต่าง) [ 42 ]

spiffเป็นตัวแปรของdiffที่ไม่สนใจความแตกต่างในการคำนวณจุดลอยตัวที่มีข้อผิดพลาดจากการปัดเศษและช่องว่างซึ่งโดยทั่วไปแล้วไม่เกี่ยวข้องกับการเปรียบเทียบซอร์สโค้ดBellcoreเป็นผู้เขียนเวอร์ชันดั้งเดิม[ 43 ] [ 44 ]เวอร์ชันHPUXเป็นเวอร์ชันที่เผยแพร่สู่สาธารณะล่าสุด spiff ไม่รองรับไฟล์ไบนารี spiff ส่งออกไปยังเอาต์พุตมาตรฐานในรูปแบบ diff มาตรฐานและรับอินพุตในภาษาโปรแกรมC , Bourne shell , Fortran , Modula-2และLisp [ 45 ] [ 46 ] [ 43 ] [ 47 ] [ 44 ]

LibXDiff เป็นไลบรารี LGPL ที่มีอินเทอร์เฟซสำหรับอัลกอริทึมหลายตัวตั้งแต่ปี 1998 อัลกอริทึม Myers ที่ได้รับการปรับปรุงพร้อมลายนิ้วมือ Rabinถูกนำมาใช้ครั้งแรก (ในเวอร์ชันสุดท้ายปี 2008) [ 48 ]แต่Gitและlibgit2ได้ขยายคลังเก็บข้อมูลด้วยอัลกอริทึมของตนเองมากมาย อัลกอริทึมหนึ่งที่เรียกว่า "histogram" โดยทั่วไปถือว่าดีกว่าอัลกอริทึม Myers ดั้งเดิม ทั้งในด้านความเร็วและคุณภาพ[ 49 ] [ 50 ] นี่คือ LibXDiffเวอร์ชันสมัยใหม่ที่ Vim ใช้[ 27 ]

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • Paul Heckel (เมษายน 1978). "เทคนิคสำหรับการแยกความแตกต่างระหว่างไฟล์" . Communications of the ACM . 21 (4): 264– 268. doi : 10.1145/359460.359467 . S2CID  207683976 .เทคนิคในการแยกความแตกต่างระหว่างไฟล์
  • การนำอัลกอริทึม Myers SES/LCS มาใช้งานโดยทั่วไป ร่วมกับการปรับปรุงความละเอียดเชิงพื้นที่เชิงเส้นของ Hirschberg (ซอร์สโค้ดภาษา C)
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Diff&oldid=1359774096 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ความแตกต่าง

diff diff เป็น คำสั่ง เชลล์ ที่ ใช้เปรียบเทียบ เนื้อหาของไฟล์และรายงานความแตกต่าง คำว่า diff ยังใช้เพื่อระบุผลลัพธ์ของคำสั่งและ ใช้เป็นคำกริยา ในการเรียกใช้คำสั่ง...

ประวัติศาสตร์

ยูทิลิตี้ diff ดั้งเดิมได้รับการพัฒนาในช่วงต้นทศวรรษ 1970 สำหรับระบบปฏิบัติการ Unix ที่ Bell Labs ใน Murray Hill รัฐนิวเจอร์ซีย์ เป็นส่วนหนึ่งของ Unix รุ่นที่ 5 ที่วางจำหน่ายในปี 1974 [ 4 ] และเขียนโดย Douglas McIlroy และ James Hunt...

อัลกอริทึม

แตกต่างจาก แนวคิด ระยะห่างการแก้ไข ที่ใช้เพื่อวัตถุประสงค์อื่น diff ระยะห่างการแก้ไขจะเน้นที่บรรทัดมากกว่าตัวอักษร แต่ก็คล้ายกับ ระยะห่างของ Levenshtein ตรงที่พยายามหาชุดการลบและการแทรกที่เล็กที่สุดเพื่อสร้างไฟล์หนึ่งจากอีกไฟล์หนึ่ง

ใช้

คำสั่ง นี้ diff รับอาร์กิวเมนต์สองตัว เช่น` `, ... diff original new -r