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


472

行うとき git diffと、「ファイルの終わりに改行はありません」と表示されます

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

メッセージの意味は何ですか?それは私たちに伝えようとしていることは何ですか?


11
おそらく、改行なしで終了するファイルがあり、別の行を追加した場合、gitは前の最後の行が変更されたことを示す必要があります。これは、行の一部として改行文字が含まれているためです。
nafg 2014

回答:


458

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

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

メッセージが表示されるのは、最後に改行があるファイルとない行の違いを区別する方法がないためです。とにかく、Diffは改行を出力する必要があります。そうしないと、結果の読み取りや自動処理が難しくなります。

ファイル形式で許可されている場合は、常に改行を最後の文字として配置するのが適切なスタイルであることに注意してください。さらに、たとえば、CおよびC ++ヘッダーファイルの場合、言語標準で必要です。


136
好奇心から、常に最後の文字として改行を入れるのが良いスタイルだと考えられる理由を説明できますか?編集:このディスカッションが見つかりました。
Paul Bellora、

84
@PaulBellora歴史的には、それは標準のC言語による決定だったstackoverflow.com/a/729725/233098多くのUnixツールが必要とするか、または適切な表示のためにそれを期待しているため、実際にstackoverflow.com/a/729795/233098。哲学的には、テキストファイルの各行は「行末」文字で終了するため、最後の行も例外ではありません。別の方法で考えて、逆を探りましょう。「行末」ではなく「行頭」マーカーがあった場合、最初の行の「行頭」文字を省略しますか?
Joe、

29
@ジョーそれはあまり意味がありません。改行は新しいライン、ライン間の分離はなく、行末IE。行頭文字は必要ないため、ありません。同じ理由で行末文字はありません。
acjay 2014

6
@acjay私は、「行間のセパレータ」と「行末」の間には本質的に優れていると主張します。どちらのビューも本質的に正しいか間違っているかではなく、それを見る1つの方法にすぎません。私は、我々はすでにそのようにやっていることから、ポイント・オブ・ビュー、歴史的に実用的だ使い続けるとそれが示唆されていない、あなたがそれを受け入れたときにメイクセンスを。一貫性は重要です。「行の間のセパレーター」という視点の名目でそれを壊す必要はありません。
Joe

17
@WORMSS「私にとって新しい」は「新しいコンベンション」と同じではありません。これは、他の種類のプログラミング規約を発見するのと同じです。あなたはそれと一緒に行きます。あなた逸脱することができますが、あなたは自分を孤立させるだけです。(または、この場合、実際に壊れたツールです。)Railsの慣習、つまりPEP8を発見した他の人々の数、および反対にコードを記述したにもかかわらず、コミュニティが譲ったために全体としてどの程度一貫性が保たれているかを考えてください。
Joe

100

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

ここにあり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行目の編集と新しい追加が表示されます。


4
catの結果は問題ありませんが、wcパラメーター "-l、--lines"が間違っています。マニュアルでも「改行数を印刷する」とあり、「行数を印刷する」とは記載されていません。
信じられないほどのJan

そして、最近のutil linux(util-linux 2.34)でこれ(wcとcat)を再現することもできません。
wget

1
@wget私はutil-linux 2.34を使用しており、この回答が現在の動作であることを確認できます。私の推測では、編集者が「\ n」文字を追加しました。
stephanos

29

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

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

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

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

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


23

末尾にaがない既存のファイルの末尾に新しいテキスト行を追加するとnewline character、概念的に変更されていなくても、差分は古い最後の行を変更されたものとして表示します。

これは、少なくとも1つの 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。これは実際には何が起こったのかですが、概念的に起こったのではなく、混乱を招く可能性があります。


2
同じことを別の方向に書くこともできます。既存のファイルの最後に改行がすでにある新しい行を削除すると、概念的にそうでない場合、差分は古い最後の行も変更されたものとして表示します。最後に改行を削除する少なくとも1つの正当な理由。
gentiane

3
@gentiane「新しい行」(新しい行)と「新しい行」(行の終わりを区切る1文字または2文字)を
混同している

@minexewいいえ、ゲンティアンは違います。「改行」が「改行」と同じであることに気付かないかもしれません。
信じられないほどのJan

3
@TheincredibleJan答えでの使用方法では、2つの用語には明確な意味があります。あなたが賢い人になろうとしているのか、何が起こっているのか誤解しているだけなのか、私にはわかりません。
minexew

18

ファイルの終わりに改行がないことを示しているだけです。これは致命的な問題ではなく、コマンドラインでdiffを確認したときに存在しないことを明確にするための単なるメッセージです。


10

この規則が採用された理由は、UNIXライクなオペレーティングシステムでは、改行文字がラインターミネーターやメッセージ境界として処理されるためです(これには、プロセス間のパイプ、ラインバッファリングなどが含まれます)。

たとえば、改行文字のみを含むファイルが単一の空行として扱われることを考慮してください。逆に、長さがゼロバイトのファイルは、実際にはゼロ行の空のファイルです。wc -lコマンドで確認できます。

\n文字が行ターミネータではなく単に行セパレータである場合、空のテキストファイルと1つの空の行があるテキストファイルを区別する他の方法がないため、この動作は完全に妥当です。したがって、有効なテキストファイルは常に改行文字で終わる必要があります。唯一の例外は、テキストファイルを空にする(行がない)場合です。


1
なぜ-2に反対投票されるのですか?他の回答が述べていることの確認(つまり、標準のUNIXベースのツールは改行を行のターミネータとして想定している)だけでなく、空のファイルと1つの空の行を区別する方法がないことも指摘しました。 。「メッセージの重要性は何か、それは何を伝えようとしているのか?」という最初の質問に明確に答えました。
レスリークラウゼ2018

私はあなたに反対票を投じませんでしたが、この応答は改行が改行文字だけであるときにのみ適用されるという点で、Unix型システムに固有であるようです。ここでそれが当てはまるかどうかは明らかではありません。また、ファイルが空の行のみで構成されている場合、警告は役に立たないようです。しかし、人々は説明なしで反対票を投じることが多いため、Stackoverflowは避けます。
user34660

9

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


一般的に良い点ですが、この特定の質問の文脈では意味がありません。
cst1992

@ cst1992 Stackoverflowの回答は可能な限り役立つと考えられています。つまり、すべての可能性に当てはまるはずです。質問は短く、私が提案した可能性を除外する場所はわかりません。
user34660

7

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



3

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

問題の核心は-ほとんどの言語で、改行には意味的な意味があり、ファイルの終わりは改行文字の言語定義の代替ではありません。したがって、最後の文字を含め、すべてのステートメント/式を改行文字で終了する必要があります。


1
C / C ++では、プロジェクト全体を1行で記述できます。改行は必要ありません。
信じられないほどのJan

あなたは可能性があり、あなたが使用していない場合は... 1行にあなたの全体のプロジェクトを作成し//、コードの途中でスタイルのコメントを。
Doug Coburn

2

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

ただし、geditなどの一部のエディター Linuxのは、ファイルの最後に改行を静かに追加します。この種のエディタを使用している間は、このメッセージを取り除くことはできません。

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

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


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.