При этом 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, C ++: заголовочные файлы, Javascript: упаковщики). Если вы пропустите символ новой строки, вы можете ввести неприятные ошибки (когда последняя строка одного источника объединяется с первой строкой следующего исходного файла). Надеюсь, что все инструменты конкатата исходного кода вставляют новую строку между конкатенированными файлами в любом случае, но это не всегда так.
Суть проблемы в том, что в большинстве языков переводы строки имеют семантическое значение, а конец файла не является языковой альтернативой для символа перевода строки. Таким образом, вы должны завершать каждое утверждение / выражение символом новой строки, включая последний.
//
комментарий стиля в середине кода.
Ваш исходный файл, вероятно, не имел символа новой строки.
Тем не менее, некоторые редакторы, такие как Gedit в linux, молча добавляют символ новой строки в конец файла. Вы не можете избавиться от этого сообщения при использовании такого рода редакторов.
Что я пытался преодолеть эту проблему, чтобы открыть файл с редактора кода Visual Studio
Этот редактор четко показывает последнюю строку, и вы можете удалить строку по своему усмотрению.
Что бы это ни стоило, я столкнулся с этим, когда создал проект IntelliJ на Mac, а затем перенес проект на мою машину с Windows. Мне пришлось вручную открывать каждый файл и изменять настройки кодировки в правом нижнем углу окна IntelliJ. Вероятно, этого не случится с большинством, кто читает этот вопрос, но это могло бы сэкономить мне пару часов работы ...