ファイルの末尾には改行を入れましょう

2025-07-29
@obikosato

これ

a

GitHub上のプルリクとかで見かけるやつ

2025-07-29 | devds勉強会 | @obikosato

これ

a

GitHub上のプルリクとかで見かけるやつ

2025-07-29 | devds勉強会 | @obikosato

⚠️ 末尾に改行がない↓

✅ 末尾に改行がある↓

2025-07-29 | devds勉強会 | @obikosato

末尾に改行がないと何が問題?

POSIXでは「行=改行で終わる」と定義されています。

POSIX標準の定義より

  • : 「改行で終わる」
  • テキストファイル: 「行の集合」

UNIX系ツールの多くがこれに基づいており、「行は改行で終わる」ことを前提に動作します。
末尾に改行がないと、意図しない挙動を引き起こすことがあります。

2025-07-29 | devds勉強会 | @obikosato

例:wc -l で行数が正しくカウントされない

$ cat a.csv
aaa,bbb
ccc,ddd%
$ wc -l a.csv
       1

本来は2行のはずが、1行としてカウントされる。

2025-07-29 | devds勉強会 | @obikosato

例:cat でファイルがちゃんと結合されない

$ cat a.csv
aaa,bbb
ccc,ddd%
$ cat a.csv a.csv
aaa,bbb
ccc,dddaaa,bbb
ccc,ddd%

末尾に改行がないため、2つ目のファイルの内容が1行目にくっついてしまう。

2025-07-29 | devds勉強会 | @obikosato

Gitでも差分がおかしくなってしまう😭

2025-07-29 | devds勉強会 | @obikosato

⚠️ 末尾に改行がない↓

✅ 末尾に改行がある↓

2025-07-29 | devds勉強会 | @obikosato

⚠️ 末尾に改行がない↓

✅ 末尾に改行がある↓

2025-07-29 | devds勉強会 | @obikosato

末尾改行警察オビコフ

2025-07-29 | devds勉強会 | @obikosato

末尾に改行が入らない原因

エディタ、AI

Vimはデフォルトで自動で末尾に改行を入れてくれるけど、
VSCodeはデフォルトでは末尾に改行を入れてくれない。

Claude CodeなどのAIツールも指示しないと末尾に改行を入れてくれないことがある。

2025-07-29 | devds勉強会 | @obikosato

自動的にファイルの末尾に改行が入るようにしましょう🙏

2025-07-29 | devds勉強会 | @obikosato

VSCodeのsettings.json

{
  "files.insertFinalNewline": true, // ファイルの末尾に改行を入れる
  "files.trimFinalNewlines": true // ファイルの末尾の改行が複数あったら1つにまとめる
}

.editorconfig

[*]
insert_final_newline = true # ファイルの末尾に改行を入れる

AI

AI(Claude Codeなど)は末尾改行が苦手なようなので、明示的に指示しましょう。
お手元のAIにもよろしくお伝えください。

2025-07-29 | devds勉強会 | @obikosato

プロジェクト内で強制する

2025-07-29 | devds勉強会 | @obikosato

GitHub Actionsでeditorconfig-checkerを使う

.editorconfigのルールに合っていない場合は失敗(エラー)として検知されます。

name: EditorConfig Checker

on:
  pull_request:
    branches:
      - main

jobs:
  editorconfig:
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v4
      - uses: editorconfig-checker/action-editorconfig-checker@main
      - run: editorconfig-checker
2025-07-29 | devds勉強会 | @obikosato

実際の設定例

EditorConfig + GitHub Actions + ブランチ保護ルールの
具体的な設定手順をこちらにまとめました。

https://github.com/obikosato/ci-sample/blob/main/protect-main-with-editorconfig.md

  • GitHub Actionsで.editorconfigチェックを設定
  • チェック結果をプルリクエストで必須化
  • mainブランチでチェック必須にして保護設定

これにより、末尾改行のないファイルはmainブランチにマージできなくなります。

2025-07-29 | devds勉強会 | @obikosato

まとめ

  • ファイルの末尾に改行を入れましょう🙏
  • 自動的(強制的)に改行が入るように設定しましょう🤝
  • みんなで習慣化しましょう👮
2025-07-29 | devds勉強会 | @obikosato

参考

2025-07-29 | devds勉強会 | @obikosato

付録・補足用スライド

(おまけ)リポジトリ内の末尾改行のないファイルを検出してみよう👮‍♂️

適当なリポジトリのルートで実行してみましょう。(UNIX互換シェル環境で)

git ls-files -z | while IFS= read -r -d '' file; do
  file --mime "${file}" | grep -q -e "charset=binary" -e "image/svg+xml" || 
  tail -c1 "${file}" | read -r _ || 
  echo "Missing newline: ${file}"
done
2025-07-29 | devds勉強会 | @obikosato

POSIX標準

3.387 Text File

A file that contains characters organized into zero or more lines. The lines do not contain NUL characters and none can exceed {LINE_MAX} bytes in length, including the <newline> character. ...

3.185 Line

A sequence of zero or more non-<newline> characters plus a terminating <newline> character.

テキストファイルは行か行の集合であり、行はnewlineで終わる。

2025-07-29 | devds勉強会 | @obikosato

改行コード問題

今回は触れなかったですが、改行コード(LF/CRLF)も問題になることがあります。
GitはLFを推奨していますが、WindowsではCRLFがデフォルトです。
Gitの設定や、.editorconfigでLFに統一する設定があります。

2025-07-29 | devds勉強会 | @obikosato

git diff

git diffでは⛔️の代わりに、「\ No newline at end of file」が出ます。

 aaa,bbb
-ccc,ddd
\ No newline at end of file
+aaa2,bbb2
+ccc,ddd
+ccc2,ddd2
2025-07-29 | devds勉強会 | @obikosato

「プログラムが動くなら末尾改行なんていらなくない?」への回答

考えてみてください。FormatterやLinterはなぜ入れるんでしょう?

  • コードの読みやすさ
  • 差分を減らすための整形
  • チームでの一貫性
  • 機械でチェックできることを自動化する

LinterやFormatterが怒るのは 「動かないから」じゃなくて「壊れやすくなるから」 です。

安全なコードを書くためのルールを守ることは、開発者としての責任です。

2025-07-29 | devds勉強会 | @obikosato