Khi thực hiện, git diff
nó nói "Không có dòng mới ở cuối tập tin" .
Ok, không có dòng mới ở cuối tập tin. Vấn đề lớn là gì?
Tầm quan trọng của thông điệp là gì và nó đang cố nói gì với chúng tôi?
Khi thực hiện, git diff
nó nói "Không có dòng mới ở cuối tập tin" .
Ok, không có dòng mới ở cuối tập tin. Vấn đề lớn là gì?
Tầm quan trọng của thông điệp là gì và nó đang cố nói gì với chúng tôi?
Câu trả lời:
Nó cho biết rằng bạn không có dòng mới (thường '\n'
là CR hoặc CRLF) ở cuối tệp.
Nghĩa là, nói một cách đơn giản, byte cuối cùng (hoặc byte nếu bạn có trên Windows) trong tệp không phải là một dòng mới.
Thông báo được hiển thị bởi vì nếu không, không có cách nào để phân biệt sự khác biệt giữa một tệp có dòng mới ở cuối và một nơi không có. Diff phải xuất ra một dòng mới, hoặc kết quả sẽ khó đọc hoặc xử lý tự động hơn.
Lưu ý rằng đó là một phong cách tốt để luôn đặt dòng mới là ký tự cuối cùng nếu nó được định dạng tệp cho phép. Hơn nữa, ví dụ, đối với các tệp tiêu đề C và C ++, nó được yêu cầu bởi tiêu chuẩn ngôn ngữ.
Đó không chỉ là phong cách xấu, nó có thể dẫn đến hành vi bất ngờ khi sử dụng các công cụ khác trên tệp.
Đây là test.txt
:
first line
second line
Không có ký tự dòng mới trên dòng cuối cùng. Hãy xem có bao nhiêu dòng trong tệp:
$ wc -l test.txt
1 test.txt
Có thể đó là những gì bạn muốn, nhưng trong hầu hết các trường hợp, bạn có thể mong đợi có 2 dòng trong tệp.
Ngoài ra, nếu bạn muốn kết hợp các tệp, nó có thể không hoạt động theo cách bạn mong đợi:
$ cat test.txt test.txt
first line
second linefirst line
second line
Cuối cùng, nó sẽ làm cho sự khác biệt của bạn trở nên ồn ào hơn nếu bạn thêm một dòng mới. Nếu bạn đã thêm một dòng thứ ba, nó sẽ hiển thị một chỉnh sửa cho dòng thứ hai cũng như bổ sung mới.
Lý do duy nhất là Unix trong lịch sử đã có một quy ước về tất cả các tệp văn bản có thể đọc được của con người kết thúc bằng một dòng mới. Tại thời điểm đó, điều này tránh xử lý thêm khi hiển thị hoặc nối các tệp văn bản và tránh xử lý các tệp văn bản khác với các tệp chứa các loại dữ liệu khác (ví dụ: dữ liệu nhị phân thô không thể đọc được).
Do quy ước này, nhiều công cụ từ thời kỳ đó mong đợi dòng mới kết thúc, bao gồm trình soạn thảo văn bản, công cụ tìm khác biệt và các công cụ xử lý văn bản khác. Mac OS X được xây dựng trên BSD Unix và Linux được phát triển để tương thích với Unix, vì vậy cả hai hệ điều hành đều được thừa hưởng cùng một quy ước, hành vi và công cụ.
Windows không được phát triển để tương thích với Unix, do đó, nó không có cùng một quy ước và hầu hết các phần mềm Windows sẽ hoạt động tốt mà không có dòng mới.
Nhưng, vì Git được phát triển cho Linux trước tiên và rất nhiều phần mềm nguồn mở được xây dựng trên các hệ thống tương thích Unix như Linux, Mac OS X, FreeBSD, v.v., hầu hết các cộng đồng nguồn mở và các công cụ của họ (bao gồm cả ngôn ngữ lập trình) vẫn tiếp tục để theo các quy ước này.
Có những lý do kỹ thuật có ý nghĩa vào năm 1971, nhưng trong thời đại này, nó chủ yếu là quy ước và duy trì khả năng tương thích với các công cụ hiện có.
Nếu bạn thêm một dòng văn bản mới vào cuối tệp hiện tại chưa có newline character
ở cuối, thì diff sẽ hiển thị dòng cuối cùng cũ như đã được sửa đổi, mặc dù về mặt khái niệm thì không.
Đây là ít nhất một lý do tốt để thêm newline character
vào cuối.
Một tệp chứa:
A() {
// do something
}
Hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
Bây giờ bạn chỉnh sửa nó thành
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..
Các git diff sẽ hiển thị:
-}
\ No newline at end of file
+}
+// Useful comment.
Nói cách khác, nó cho thấy một sự khác biệt lớn hơn so với khái niệm xảy ra. Nó cho thấy rằng bạn đã xóa dòng }
và thêm dòng }\n
. Trên thực tế, đây là những gì đã xảy ra, nhưng nó không phải là những gì đã xảy ra về mặt khái niệm , vì vậy nó có thể gây nhầm lẫn.
Lý do quy ước này được áp dụng là vì trên các hệ điều hành giống UNIX, một ký tự dòng mới được coi là dấu kết thúc dòng và / hoặc ranh giới thông báo (bao gồm đường ống giữa các quy trình, bộ đệm dòng, v.v.).
Ví dụ, xem xét rằng một tệp chỉ có một ký tự dòng mới được coi là một dòng trống duy nhất. Ngược lại, một tệp có độ dài bằng 0 byte thực sự là một tệp trống có các dòng bằng không. Điều này có thể được xác nhận theo wc -l
lệnh.
Nhìn chung, hành vi này là hợp lý bởi vì sẽ không có cách nào khác để phân biệt giữa một tệp văn bản trống so với tệp văn bản với một dòng trống duy nhất nếu \n
ký tự chỉ là dấu phân cách dòng chứ không phải là dấu kết thúc dòng. Do đó, các tệp văn bản hợp lệ phải luôn luôn kết thúc bằng một ký tự dòng mới. Ngoại lệ duy nhất là nếu tệp văn bản được dự định để trống (không có dòng).
Có một điều mà tôi không thấy trong các phản hồi trước đây. Cảnh báo về việc không có dòng cuối có thể là một cảnh báo khi một phần của tệp đã bị cắt ngắn. Nó có thể là một triệu chứng của dữ liệu bị thiếu.
Vấn đề cốt lõi là những gì bạn xác định dòng và liệu chuỗi ký tự cuối dòng có phải là một phần của dòng hay không. Các trình soạn thảo dựa trên UNIX (như VIM) hoặc các công cụ (như Git) sử dụng chuỗi ký tự EOL làm đầu cuối dòng, do đó nó là một phần của dòng. Nó tương tự như việc sử dụng dấu chấm phẩy (;) trong C và Pascal. Trong dấu chấm phẩy C chấm dứt các câu lệnh, trong Pascal, nó phân tách chúng.
Điều này thực sự gây ra vấn đề vì các kết thúc dòng được tự động sửa đổi các tệp bẩn mà không thực hiện bất kỳ thay đổi nào đối với chúng. Xem bài này để giải quyết.
Các tệp nguồn thường được nối bởi các công cụ (C, C ++: tệp tiêu đề, Javascript: gói). Nếu bạn bỏ qua ký tự dòng mới, bạn có thể đưa ra các lỗi khó chịu (trong đó dòng cuối cùng của một nguồn được nối với dòng đầu tiên của tệp nguồn tiếp theo). Hy vọng rằng tất cả các công cụ nối mã nguồn ngoài đó đều chèn một dòng mới giữa các tệp được nối nhưng dù sao thì điều đó dường như không phải là trường hợp.
Mấu chốt của vấn đề là - trong hầu hết các ngôn ngữ, dòng mới có ý nghĩa ngữ nghĩa và phần cuối của tệp không phải là ngôn ngữ được xác định thay thế cho ký tự dòng mới. Vì vậy, bạn nên chấm dứt mọi tuyên bố / biểu thức bằng một ký tự dòng mới - bao gồm cả ký tự cuối cùng.
//
nhận xét kiểu ở giữa mã.
Tập tin gốc của bạn có thể không có ký tự dòng mới.
Tuy nhiên, một số trình soạn thảo như gedit trong linux âm thầm thêm dòng mới vào cuối tệp. Bạn không thể thoát khỏi tin nhắn này trong khi sử dụng loại trình soạn thảo này.
Điều tôi đã cố gắng khắc phục vấn đề này là mở tệp bằng trình chỉnh sửa mã phòng thu trực quan
Trình chỉnh sửa này hiển thị rõ ràng dòng cuối cùng và bạn có thể xóa dòng theo ý muốn.
Để biết giá trị của nó, tôi đã gặp phải điều này khi tôi tạo một dự án IntelliJ trên máy Mac, và sau đó chuyển dự án sang máy Windows của tôi. Tôi đã phải tự mở mọi tệp và thay đổi cài đặt mã hóa ở dưới cùng bên phải của cửa sổ IntelliJ. Có lẽ không xảy ra với hầu hết mọi người nếu đọc câu hỏi này nhưng điều đó có thể giúp tôi tiết kiệm được một vài giờ làm việc ...