DevToolBox

改行コードCRLFとLFの違いと統一方法

改行コードは LF(\n・0x0A)CRLF(\r\n・0x0D 0x0A)の2種類が現役です。 Unix/Mac/Gitの内部表現はLF、WindowsはCRLFが標準。混在するとdiffが全行差分になる・シェルスクリプトが動かないなどの実害が出ます。

LF (\n) is the Unix/Git standard; CRLF (\r\n) is the Windows standard. This guide covers the real-world breakage and how to normalize line endings with .gitattributes.

TL;DR

1. 何が起きるか / What breaks

症状 / Symptom原因 / Cause
1文字も変えていないのにdiffが全行差分になるエディタが保存時に改行コードを変換した
bad interpreter: /bin/bash^MCRLFのシェルスクリプト。shebang行末の\rがパス扱いされる
ESLintの linebreak-style で大量エラールールはLF想定、ファイルがCRLF(またはその逆)
Dockerにコピーしたスクリプトだけ動かないWindowsで編集したCRLFファイルをLinuxコンテナで実行
ファイルのハッシュ値が環境で変わる改行1バイト差でもハッシュは別物になる

「同じに見えるのに違う」状態の確認には差分チェッカー\r がどこにあるかの特定にはUnicode Inspectorが使えます (どちらもブラウザ内で完結し、コードを外部送信しません)。

2. 現在の改行コードを確認する / How to check

3. Gitでの統一方法 / Normalizing with Git

推奨: リポジトリに .gitattributes を置く。全員の個人設定に関係なく同じ挙動になります。

# .gitattributes
# テキストファイルはコミット時にLFへ正規化(チェックアウトはOS依存)
* text=auto

# 常にLFでチェックアウトしたいもの(シェルスクリプト等)
*.sh text eol=lf

# 常にCRLFが必要なもの(バッチファイル)
*.bat text eol=crlf

# バイナリは変換しない
*.png binary

追加したら既存ファイルを一括で正規化します。

git add --renormalize .
git commit -m "normalize line endings"

個人設定の core.autocrlf を使う場合の挙動は次のとおりです。

設定 / Settingコミット時 / On commitチェックアウト時 / On checkout想定 / For
trueLFに変換CRLFに変換Windows(CRLF前提のツールを使う)
inputLFに変換変換しないMac/Linux、WindowsでもLF統一なら可
false(既定)変換しない変換しない.gitattributesで管理する場合

4. エディタ側の統一 / Editor configuration

# .editorconfig (主要エディタが標準対応)
root = true

[*]
end_of_line = lf

[*.bat]
end_of_line = crlf

VS Codeなら "files.eol": "\n" でも新規ファイルをLFにできますが、 チームで共有できる .editorconfig の方が確実です。

5. English summary

LF (0x0A) is the Unix and Git-internal standard; CRLF (0x0D 0x0A) is the Windows standard. Mixed endings cause whole-file diffs, ESLint linebreak-style noise, differing hashes, and the classicbad interpreter: /bin/bash^M failure when a CRLF script runs on Linux. Check the current state with the VS Code status bar or git ls-files --eol. The robust fix is a committed .gitattributes with * text=auto (plus eol=lf for shell scripts), followed by git add --renormalize .. Per-usercore.autocrlf works but depends on every member configuring it correctly, so prefer the repository-level approach.

関連ツール / Related tools

関連ガイド / Related guides