Git Line-Ending Conversion

Last update: 2026-04-29 00:23:56 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Git can normalize text to LF at the repository boundary while presenting LF or CRLF in a worktree. A stable .gitattributes policy avoids platform-dependent commits and leaves editors responsible only for the checked-out form.

Distinguish HEAD, Index, and Worktree Bytes #

A tracked path has three relevant representations:

  1. HEAD names the blob stored by the current commit.
  2. The index holds the blob proposed for the next commit.
  3. The worktree holds bytes consumed by editors and build tools.

For normalized text, git add performs a clean conversion from CRLF to LF. Checkout performs a smudge conversion from indexed LF to the selected worktree ending. Existing commits are not rewritten.

sh
git ls-files --eol -- path/to/file
git show HEAD:path/to/file | od -An -t x1
git check-attr -a -- path/to/file

git ls-files --eol reports index, worktree, and effective attribute forms. Inspect those forms before responding to a conversion warning.

Declare Repository Policy with .gitattributes #

Commit attributes because every clone then shares the policy:

gitattributes
*       text=auto
*.sh    text eol=lf
*.py    text eol=lf
*.bat   text eol=crlf
*.png   binary
*.pdf   binary

text=auto lets Git classify unspecified paths. text forces normalization; -text disables it; and binary is a built-in attribute macro for -diff -merge -text. An explicit eol=lf or eol=crlf marks a path as text and controls its checkout form. Mark archives, images, generated binary formats, and signed artifacts as non-text because conversion changes their bytes.

Use Configuration Only as a Fallback #

core.autocrlf and core.eol affect paths whose attributes do not make a more-specific decision:

core.autocrlfClean Into IndexCheckout From Index
falseNo autocrlf conversionNo autocrlf conversion
inputCRLF becomes LFLF remains LF
trueCRLF becomes LFLF becomes CRLF

core.eol selects lf, crlf, or native for normalized text without an explicit eol attribute. core.safecrlf=true rejects irreversible conversions; warn reports them. Neither setting replaces a committed attribute policy.

sh
git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol
git config --show-origin --get core.safecrlf

Renormalize Safely #

After adding or correcting attributes, start from a clean worktree or preserve uncommitted work. Then stage a deliberate normalization and review it:

sh
git add --renormalize .
git diff --cached --check
git diff --cached

Commit line-ending normalization separately from semantic edits because a dedicated commit preserves review, blame, and rollback quality. The operation updates the index; it does not change ignored or untracked files.

Align editor settings with the checked-out policy, especially for files forced to CRLF. Editor configuration affects worktree bytes, whereas .gitattributes defines the version-controlled boundary. Do not repeatedly add and checkout valuable uncommitted files as an experiment; inspect effective attributes and save work first.

Comments

Read or comment on GitHub (sign-in required to comment)