web-dev-qa-db-ja.com

ファイルの終わりに改行なし

git diffをするとき、それは「ファイルの終わりに改行がありません」と言います。

わかりました、ファイルの終わりに改行はありません。大したことは何ですか?

メッセージの意味は何ですか、そして何を伝えようとしているのでしょうか。

400
Pacerier

ファイルの最後に改行(通常は'\n'、別名CRまたはCRLF)がないことを示します。

つまり、単純に言えば、ファイルの最後のバイト(Windowsの場合はバイト)は改行ではありません。

メッセージが表示されるのは、そうでなければ、最後に改行があるファイルとそうでないファイルの違いを見分ける方法がないからです。とにかくdiffは改行を出力しなければなりません、さもなければ結果は自動的に読んだり処理したりするのが難しくなるでしょう。

ファイル形式で許可されている場合は、常に改行を最後の文字として配置することをお勧めします。さらに、例えば、CおよびC++ヘッダーファイルの場合は、言語標準で必要とされています。

393

スタイルが悪いだけではなく、ファイルで他のツールを使用しているときに予期しない動作が発生する可能性があります。

これは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

最後に、新しい行を追加すると、差分がやや騒々しくなります。 3行目を追加した場合は、2行目の編集と新しい追加が表示されます。

82
Dean

唯一の理由は、Unixは歴史的にすべての人間が読めるテキストファイルが改行で終わるという規約を持っていたということです。当時、これはテキストファイルを表示したり結合したりする際の余分な処理を避け、テキストファイルを他の種類のデータ(人間が読めない生のバイナリデータなど)を含むファイルとは異なる扱いをすることを避けました。

この慣例により、当時の多くのツールは、テキストエディタ、差分ツール、およびその他のテキスト処理ツールを含め、最後の改行を期待しています。 Mac OS XはBSD Unix上に構築され、LinuxはUnix互換になるように開発されたので、どちらのオペレーティングシステムも同じ規約、動作、およびツールを継承しています。

WindowsはUnix互換になるようには開発されていないので、同じ規則はありません。また、ほとんどのWindowsソフトウェアは、末尾の改行なしで問題なく処理されます。

しかし、Gitが最初にLinux用に開発され、Linux、Mac OS X、FreeBSDなどのようなUnix互換システム上に多くのオープンソースソフトウェアが構築されて以来、ほとんどのオープンソースコミュニティとそのツール(プログラミング言語を含む)は続いていますこれらの規約に従うこと。

1971年に理にかなった技術的な理由がありますが、この時代にはそれはほとんど慣例であり、既存のツールとの互換性を維持しています。

19
Nathan Craike

ファイルの終わりに改行がないことを示しているだけです。それは大惨事ではありません。コマンドラインでdiffを見たときにエラーがないことを明確にするためのメッセージにすぎません。

17
JohnD

既存のファイルの末尾に改行文字がまだない新しいテキスト行を追加すると、概念的には変更されていなくても、diffは古い最終行を変更されたものとして表示します。

これは最後に改行を追加する少なくとも1つの正当な理由です。

ファイルに含まれるもの:

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.

言い換えれば、それは概念的に発生したよりも大きいdiffを示しています。これは、}行を削除し、}\n行を追加したことを示しています。これは実際に起こったことですが、概念上のが起こったことではないので、混乱を招く可能性があります。

15
Jaseem

前回の回答では見られないことが1つあります。行末がないという警告は、ファイルの一部が切り捨てられた場合の警告です。データが欠落しているという症状である可能性があります。

6
user34660

この規約が実用化された理由は、UNIXライクなオペレーティングシステムでは改行文字がラインターミネータまたはメッセージ境界(あるいはその両方)として扱われるためです(これはプロセス間のパイプ、ラインバッファリングなどを含みます)。

たとえば、改行文字だけを含むファイルは、1行の空行として扱われるとします。逆に、長さ0バイトのファイルは、実際には行数0の空のファイルです。これはwc -lコマンドで確認できます。

\n文字が単に行末記号ではなく単に行区切り文字である場合、空のテキストファイルと1つの空行を持つテキストファイルを区別する方法が他にないため、この動作はまったく理にかなっています。したがって、有効なテキストファイルは常に改行文字で終わらなければなりません。唯一の例外は、テキストファイルが空(行がない)であることを意図している場合です。

5
Leslie Krause

中心的な問題は、あなたが行を定義していることと、行末文字シーケンスが行の一部であるかどうかです。 UNIXベースのエディタ(VIMなど)またはツール(Gitなど)は行末記号としてEOL文字シーケンスを使用するため、これは行の一部です。 CやPascalでセミコロン(;)を使うのと似ています。 Cでは、セミコロンはステートメントを終了し、Pascalではそれを区切ります。

4
mmcorrelo

ソースファイルはしばしばツール(C、C++:ヘッダファイル、Javascript:bundlers)によって連結されます。改行文字を省略すると、厄介なバグ(あるソースの最後の行が次のソースファイルの最初の行と連結されている)が生じる可能性があります。うまくいけば、すべてのソースコード連結ツールが連結ファイルの間に改行を挿入することを願っていますが、必ずしもそうではないようです。

問題の核心は、ほとんどの言語で改行が意味的な意味を持ち、ファイルの終わりが改行文字の代わりに言語で定義されていることではないということです。ですから、最後のものも含めて、すべてのステートメント/式を改行文字で終わらせるべきです。

3
Doug Coburn

これは実際には問題を引き起こします。なぜなら、行末は何も変更することなく自動的にダーティファイルに変更されるからです。解決のためにこの記事を参照してください。

LFをCRLFに置き換えてgit

2
Brian Blum

元のファイルにはおそらく改行文字がありませんでした。

しかし、Linuxのgeditのようなエディタの中には、ファイルの末尾に改行文字を黙って追加するものがあります。この種のエディタを使用している間は、このメッセージを取り除くことはできません。

私がこの問題を克服しようとしたのは、 ビジュアルスタジオコードエディタでファイルを開くことです

このエディタでは最後の行が明確に表示されているので、必要に応じてその行を削除できます。

1
Berkay92

それが価値があるもののために、私は私がMac上でIntelliJプロジェクトを作成し、それから私のWindowsマシンにプロジェクトを移動したときにこれに遭遇しました。手動ですべてのファイルを開き、IntelliJウィンドウの右下でエンコード設定を変更しなければなりませんでした。この質問を読んだ人なら、たぶんほとんどの人には起こらないでしょうが、それによって数時間の作業が節約できたかもしれません….

0
Lou Morda