เมื่อทำgit diff
มันบอกว่า"ไม่มีการขึ้นบรรทัดใหม่ที่จุดสิ้นสุดของไฟล์" "ไม่มีการขึ้นบรรทัดใหม่ในตอนท้ายของไฟล์"
ตกลงไม่มีบรรทัดใหม่ที่ท้ายไฟล์ เรื่องใหญ่อะไร
ข้อความสำคัญอะไรและมันพยายามบอกอะไรเรา
เมื่อทำgit diff
มันบอกว่า"ไม่มีการขึ้นบรรทัดใหม่ที่จุดสิ้นสุดของไฟล์" "ไม่มีการขึ้นบรรทัดใหม่ในตอนท้ายของไฟล์"
ตกลงไม่มีบรรทัดใหม่ที่ท้ายไฟล์ เรื่องใหญ่อะไร
ข้อความสำคัญอะไรและมันพยายามบอกอะไรเรา
คำตอบ:
บ่งชี้ว่าคุณไม่มีบรรทัดใหม่ (ปกติ'\n'
คือ CR หรือ CRLF) ที่ท้ายไฟล์
นั่นคือเพียงพูดไบต์สุดท้าย (หรือไบต์ถ้าคุณใช้ Windows) ในไฟล์ไม่ใช่บรรทัดใหม่
ข้อความจะปรากฏขึ้นเพราะมิฉะนั้นจะไม่มีวิธีที่จะบอกความแตกต่างระหว่างไฟล์ที่มีการขึ้นบรรทัดใหม่ในตอนท้ายและอีกหนึ่งที่ไม่มี Diff จะต้องแสดงบรรทัดใหม่หรือผลลัพธ์จะยากต่อการอ่านหรือประมวลผลโดยอัตโนมัติ
โปรดทราบว่ามันเป็นสไตล์ที่ดีที่จะวางบรรทัดใหม่เป็นอักขระตัวสุดท้ายหากได้รับอนุญาตจากรูปแบบไฟล์ นอกจากนี้ตัวอย่างเช่นสำหรับไฟล์ส่วนหัว C และ C ++ จำเป็นสำหรับมาตรฐานภาษา
มันไม่ใช่แค่สไตล์ที่ไม่ดีมันสามารถนำไปสู่พฤติกรรมที่ไม่คาดคิดเมื่อใช้เครื่องมืออื่น ๆ ในไฟล์
นี่คือtest.txt
:
first line
second line
ไม่มีอักขระขึ้นบรรทัดใหม่ในบรรทัดสุดท้าย มาดูกันว่ามีไฟล์อยู่กี่ไฟล์:
$ wc -l test.txt
1 test.txt
อาจเป็นสิ่งที่คุณต้องการ แต่ในกรณีส่วนใหญ่คุณอาจคาดหวังว่าจะมี 2 บรรทัดในไฟล์
นอกจากนี้หากคุณต้องการรวมไฟล์มันอาจไม่ทำงานตามที่คุณคาดหวัง:
$ cat test.txt test.txt
first line
second linefirst line
second line
ในที่สุดมันจะทำให้เสียงรบกวนของคุณเพิ่มขึ้นเล็กน้อยหากคุณต้องการเพิ่มบรรทัดใหม่ หากคุณเพิ่มบรรทัดที่สามมันจะแสดงการแก้ไขในบรรทัดที่สองเช่นเดียวกับการเพิ่มใหม่
เหตุผลเดียวก็คือว่า Unix ในอดีตมีการประชุมของไฟล์ข้อความที่มนุษย์อ่านได้ทั้งหมดซึ่งลงท้ายด้วยบรรทัดใหม่ ในขณะนี้หลีกเลี่ยงการประมวลผลพิเศษเมื่อแสดงหรือเข้าร่วมไฟล์ข้อความและหลีกเลี่ยงการจัดการไฟล์ข้อความที่แตกต่างจากไฟล์ที่มีข้อมูลประเภทอื่น (เช่นข้อมูลไบนารีดิบซึ่งไม่สามารถอ่านได้โดยมนุษย์)
เนื่องจากการประชุมนี้เครื่องมือมากมายจากยุคนั้นจึงคาดหวังว่าจะมีการขึ้นบรรทัดใหม่ซึ่งรวมถึงเครื่องมือแก้ไขข้อความเครื่องมือที่ต่างกันและเครื่องมือประมวลผลข้อความอื่น ๆ Mac OS X สร้างขึ้นบน BSD Unix และ Linux ได้รับการพัฒนาให้ใช้งานร่วมกับ Unix ได้ดังนั้นระบบปฏิบัติการทั้งสองจึงได้รับการสืบทอดแบบแผนพฤติกรรมและเครื่องมือแบบเดียวกัน
Windows ไม่ได้รับการพัฒนาให้รองรับ Unix ดังนั้นจึงไม่มีแบบแผนเดียวกันและซอฟต์แวร์ Windows ส่วนใหญ่จะทำงานได้ดีโดยไม่ต้องขึ้นบรรทัดใหม่
แต่เนื่องจาก Git ได้รับการพัฒนาสำหรับ Linux ก่อนและซอฟต์แวร์โอเพนซอร์ซจำนวนมากถูกสร้างขึ้นบนระบบที่เข้ากันได้กับ Unix เช่น Linux, Mac OS X, FreeBSD เป็นต้นชุมชนโอเพ่นซอร์สส่วนใหญ่และเครื่องมือของพวกเขา (รวมถึงภาษาโปรแกรม) เพื่อทำตามอนุสัญญาเหล่านี้
มีเหตุผลทางเทคนิคที่ทำให้รู้สึกในปี 1971 แต่ในยุคนี้ส่วนใหญ่เป็นการประชุมและการบำรุงรักษาความเข้ากันได้กับเครื่องมือที่มีอยู่
หากคุณเพิ่มบรรทัดข้อความใหม่ในตอนท้ายของไฟล์ที่มีอยู่ซึ่งยังไม่มีnewline character
ในตอนท้าย diff จะแสดงบรรทัดสุดท้ายเก่าว่ามีการแก้ไขแม้ว่าแนวคิดจะไม่ได้
นี่คือเหตุผลที่ดีอย่างน้อยหนึ่งข้อในการเพิ่ม newline character
จุดสิ้นสุด
ไฟล์ประกอบด้วย:
A() {
// do something
}
hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
ตอนนี้คุณแก้ไขเป็น
A() {
// do something
}
// Useful comment
hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d0a 2f2f 2055 something.}.// U
00000020: 7365 6675 6c20 636f 6d6d 656e 742e 0a seful comment..
git diff จะแสดง:
-}
\ No newline at end of file
+}
+// Useful comment.
มันแสดงให้เห็นถึงความแตกต่างที่ใหญ่กว่าความคิดที่เกิดขึ้น มันแสดงให้เห็นว่าคุณลบบรรทัดและเพิ่มบรรทัด}
}\n
ในความเป็นจริงสิ่งนี้เกิดขึ้น แต่ไม่ใช่สิ่งที่เกิดขึ้นในเชิงแนวคิดดังนั้นจึงอาจทำให้เกิดความสับสน
มันเพิ่งระบุว่าจุดสิ้นสุดของไฟล์ไม่มีการขึ้นบรรทัดใหม่ ไม่ใช่ความหายนะมันเป็นเพียงข้อความที่จะทำให้ชัดเจนว่าไม่มีสิ่งใดเกิดขึ้นเมื่อมองไปที่บรรทัดคำสั่ง
เหตุผลที่การประชุมนี้เริ่มนำมาใช้จริงนั้นเป็นเพราะในระบบปฏิบัติการที่เหมือน UNIX ตัวอักขระขึ้นบรรทัดใหม่จะถือเป็นตัวยกเลิกบรรทัดและ / หรือขอบเขตของข้อความ (ซึ่งรวมถึงการไพพ์ระหว่างกระบวนการ
ตัวอย่างเช่นลองพิจารณาว่าไฟล์ที่มีเพียงอักขระบรรทัดใหม่จะถือว่าเป็นบรรทัดเดียวที่ว่างเปล่า ในทางกลับกันไฟล์ที่มีความยาวเป็นศูนย์ไบต์จะเป็นไฟล์เปล่าที่มีเส้นศูนย์ สิ่งนี้สามารถยืนยันได้ตามwc -l
คำสั่ง
โดยสิ้นเชิงพฤติกรรมนี้มีเหตุผลเพราะจะไม่มีวิธีอื่นในการแยกแยะระหว่างไฟล์ข้อความที่ว่างเปล่ากับไฟล์ข้อความที่มีบรรทัดว่างเปล่าเพียงเส้นเดียวหาก\n
ตัวละครนั้นเป็นเพียงตัวแยกบรรทัดแทนที่จะเป็นตัวคั่นบรรทัด ดังนั้นไฟล์ข้อความที่ถูกต้องควรลงท้ายด้วยอักขระขึ้นบรรทัดใหม่ ข้อยกเว้นเพียงอย่างเดียวคือถ้าไฟล์ข้อความตั้งใจที่จะว่างเปล่า (ไม่มีบรรทัด)
มีสิ่งหนึ่งที่ฉันไม่เห็นในคำตอบก่อนหน้าคือ คำเตือนเกี่ยวกับการไม่สิ้นสุดบรรทัดอาจเป็นการเตือนเมื่อส่วนของไฟล์ถูกตัดทอน มันอาจเป็นอาการของข้อมูลที่หายไป
ปัญหาหลักคือสิ่งที่คุณกำหนดเส้นและไม่ว่าลำดับตัวละครปลายสายเป็นส่วนหนึ่งของสายหรือไม่ เครื่องมือแก้ไขที่ใช้ UNIX (เช่น VIM) หรือเครื่องมือ (เช่น Git) ใช้ลำดับอักขระ EOL เป็นตัวยกเลิกบรรทัดดังนั้นจึงเป็นส่วนหนึ่งของบรรทัด มันคล้ายกับการใช้เซมิโคลอน (;) ใน C และ Pascal ใน C เครื่องหมายอัฒภาคยุติคำสั่งใน Pascal มันแยกพวกเขา
สิ่งนี้จะทำให้เกิดปัญหาเนื่องจากการสิ้นสุดบรรทัดถูกแก้ไขไฟล์สกปรกโดยอัตโนมัติโดยไม่ทำการเปลี่ยนแปลงใด ๆ ดูโพสต์นี้สำหรับการแก้ปัญหา
ไฟล์ที่มามักจะต่อกันด้วยเครื่องมือ (C, C ++: ไฟล์ส่วนหัว, Javascript: bundlers) หากคุณไม่ใช้อักขระบรรทัดใหม่คุณสามารถแนะนำข้อบกพร่องที่น่ารังเกียจ (โดยที่บรรทัดสุดท้ายของแหล่งข้อมูลหนึ่งถูกต่อกันกับบรรทัดแรกของไฟล์ต้นฉบับถัดไป) หวังว่าเครื่องมือซอร์สโค้ดทั้งหมดของ concat จะมีการแทรกบรรทัดใหม่ระหว่างไฟล์ที่ต่อกันอยู่แล้ว แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป
ประเด็นสำคัญของปัญหาคือ - ในภาษาส่วนใหญ่บรรทัดใหม่มีความหมายเชิงความหมายและจุดสิ้นสุดของไฟล์ไม่ใช่ภาษาที่กำหนดทางเลือกสำหรับอักขระขึ้นบรรทัดใหม่ ดังนั้นคุณควรยุติทุกคำสั่ง / การแสดงออกด้วยอักขระขึ้นบรรทัดใหม่ - รวมถึงตัวสุดท้าย
//
สไตล์คอมเม้นท์ตรงกลางโค้ด
ไฟล์ต้นฉบับของคุณอาจไม่มีอักขระขึ้นบรรทัดใหม่
อย่างไรก็ตามบรรณาธิการบางคนเช่นgeditใน linux จะเพิ่มบรรทัดใหม่เมื่อสิ้นสุดไฟล์ คุณไม่สามารถกำจัดข้อความนี้ในขณะที่ใช้โปรแกรมแก้ไขประเภทนี้
สิ่งที่ฉันพยายามที่จะเอาชนะปัญหานี้คือการเปิดไฟล์ด้วยโปรแกรมแก้ไขโค้ด visual studio
เครื่องมือแก้ไขนี้แสดงบรรทัดสุดท้ายอย่างชัดเจนและคุณสามารถลบบรรทัดได้ตามต้องการ
สำหรับสิ่งที่คุ้มค่าฉันพบสิ่งนี้เมื่อฉันสร้างโครงการ IntelliJ บน Mac แล้วย้ายโครงการไปยังเครื่อง Windows ของฉัน ฉันต้องเปิดทุกไฟล์ด้วยตนเองและเปลี่ยนการตั้งค่าการเข้ารหัสที่ด้านล่างขวาของหน้าต่าง IntelliJ อาจจะไม่เกิดขึ้นกับคนส่วนใหญ่ถ้าใครที่อ่านคำถามนี้ แต่นั่นอาจช่วยฉันทำงานสองสามชั่วโมง ...