- Андрей Куманяев/
- Git: руководства и команды/
- Git и CRLF/LF: решение проблемы переносов строк в Windows/
Git и CRLF/LF: решение проблемы переносов строк в Windows
Проблема CRLF/LF — одна из самых распространённых при работе с Git на Windows. Windows использует CRLF (\r\n) для переносов строк, а Linux/macOS — LF (\n). Git может автоматически конвертировать — но важно правильно настроить.
Что такое CRLF и LF #
LF (Line Feed, \n, 0x0A):
- Используется в Linux, macOS, Unix
- Один символ для переноса строки
CRLF (Carriage Return + Line Feed, \r\n, 0x0D 0x0A):
- Используется в Windows
- Два символа для переноса строки
Проблема:
- Разработчик на Windows сохраняет файл с CRLF
- Git видит что файл изменился (хотя код не менялся)
- Разработчик на Linux получает файл с CRLF — некоторые инструменты не понимают
Настройка core.autocrlf #
core.autocrlf управляет автоматической конвертацией:
# Для Windows: конвертировать в LF при коммите, CRLF при checkout
git config --global core.autocrlf true
# Для Linux/macOS: конвертировать CRLF в LF при коммите (только)
git config --global core.autocrlf input
# Отключить автоконвертацию (не рекомендуется)
git config --global core.autocrlf false
Поведение:
core.autocrlf=true (Windows):
commit: CRLF → LF (нормализация перед сохранением)
checkout: LF → CRLF (Windows получает привычные окончания)
core.autocrlf=input (Linux/macOS):
commit: CRLF → LF (исправление ошибок)
checkout: без изменений
core.autocrlf=false:
commit: без изменений
checkout: без изменений
.gitattributes — лучший способ #
.gitattributes — более надёжный способ, работает для всей команды независимо от локальных настроек:
# Создать .gitattributes в корне репозитория
cat > .gitattributes << 'EOF'
# Нормализовать все текстовые файлы в LF
* text=auto
# Явно указать текстовые файлы
*.js text eol=lf
*.ts text eol=lf
*.jsx text eol=lf
*.tsx text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.html text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
# Бинарные файлы — без конвертации
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.zip binary
*.tar.gz binary
*.pdf binary
*.exe binary
*.dll binary
# Файлы специфичные для Windows (CRLF)
*.bat text eol=crlf
*.cmd text eol=crlf
EOF
git add .gitattributes
git commit -m "Add .gitattributes for consistent line endings"
Исправление файлов с неправильными окончаниями #
Если в репозитории уже есть файлы с CRLF:
# Проверить какие файлы содержат CRLF
file * | grep CRLF
# или
grep -rl $'\r' . --include="*.js"
# Конвертировать файлы в LF
# Способ 1: dos2unix (установить отдельно)
dos2unix src/*.js
# Способ 2: через Git (после настройки .gitattributes)
git rm --cached -r .
git reset --hard
# Способ 3: sed
sed -i 's/\r//' filename.js
# После конвертации зафиксировать
git add .
git commit -m "Normalize line endings to LF"
Предупреждение “CRLF will be replaced by LF” #
Распространённое предупреждение при git add на Windows:
warning: CRLF will be replaced by LF in filename.js.
The file will have its original line endings in your working directory.
Это нормальное поведение при core.autocrlf=true — Git уведомляет что конвертирует файл перед сохранением в репозиторий. Можно подавить:
# Подавить предупреждение
git config --global core.safecrlf false
# Или сделать предупреждение ошибкой (строгий режим)
git config --global core.safecrlf true
Настройка для VS Code #
VS Code позволяет настроить окончания строк для конкретного проекта:
// .vscode/settings.json
{
"files.eol": "\n",
"files.encoding": "utf8"
}
Это не заменяет .gitattributes, но устанавливает поведение редактора по умолчанию.
Проверка окончаний строк файла #
# Показать скрытые символы (включая \r)
cat -A filename.txt
# Строки с CRLF заканчиваются на ^M$
# Строки с LF заканчиваются на $
# Через hexdump
hexdump -C filename.txt | grep "0d 0a"
# 0d = \r (CR), 0a = \n (LF)
# file утилита
file filename.txt
# ASCII text — Unix LF
# ASCII text, with CRLF line terminators — Windows CRLF
Рекомендуемая конфигурация #
# Windows разработчик:
git config --global core.autocrlf true
# Linux/macOS разработчик:
git config --global core.autocrlf input
# Для всей команды (лучший вариант):
# Создать .gitattributes в репозитории:
echo "* text=auto eol=lf" > .gitattributes
git add .gitattributes
git commit -m "Enforce LF line endings"
Часто задаваемые вопросы #
Почему git status показывает изменения когда файл не менялся? Скорее всего окончания строк изменились. Проверьте core.autocrlf и file для анализа типа окончаний.
Какой стандарт выбрать — LF или CRLF? В большинстве проектов — LF. Все современные редакторы на Windows (VS Code, Notepad++) прекрасно понимают LF. CRLF только для .bat/.cmd файлов.
Почему .gitattributes лучше core.autocrlf? .gitattributes хранится в репозитории и применяется для всей команды независимо от локальных настроек. core.autocrlf — локальная настройка, каждый разработчик должен настроить сам.
Как исправить репозиторий с перемешанными LF/CRLF? Добавьте .gitattributes, потом git rm --cached -r . && git reset --hard — перечитает все файлы с учётом новых правил. Зафиксируйте в коммит.
Заключение #
Проблема CRLF/LF в Git решается через .gitattributes (* text=auto eol=lf) — лучший и надёжный способ для команды. На Windows также используйте core.autocrlf true. В VS Code настройте files.eol: "\n". Исправление уже испорченных файлов: dos2unix или пересоздание индекса через git rm --cached -r .. Подробнее о настройке Git — настройка пользователя Git.