Подтвердить что ты не робот

Как нормализовать окончание строк рабочего дерева в Git?

Я клонировал репозиторий, у которого были несогласованные окончания строк. Я добавил .gitattributes, который устанавливает текстовый атрибут для файлов, которые я хочу нормализовать. Теперь, когда я совершаю изменения, я получаю сообщение:

warning: CRLF will be replaced by LF in FILE.
The file will have its original line endings in your working directory.

Как я могу сделать git нормализовать мою рабочую копию файла для меня? Желательно, чтобы git нормализовал все рабочее дерево.

4b9b3361

Ответ 1

С Git client 2.16 и выше теперь есть гораздо более простой способ сделать это. Просто используйте git add --renormalize.

Ответ 2

Для тех, кто использует v2.16 или выше, вы можете просто использовать:

git add --renormalize .  # Update index with renormalized files
git status               # Show the files that will be normalized
git commit -m "Introduce end-of-line normalization"

Эти направления прямо из gitattributes. Для более старых версий документы (до v2.12) дают другой ответ:

rm .git/index     # Remove the index to force git to
git reset         # re-scan the working directory
git status        # Show files that will be normalized
git add -u
git add .gitattributes
git commit -m "Introduce end-of-line normalization"

Сделайте эту последовательность после того, как вы отредактировали .gitattributes.

Обновить

Похоже, у некоторых пользователей возникли проблемы с приведенными выше инструкциями. Обновленные документы для gitattributes (с 2.12 по 2.14) показывают новый набор инструкций (после редактирования файлов .gitattributes):

git read-tree --empty   # Clean index, force re-scan of working directory
git add .
git status        # Show files that will be normalized
git commit -m "Introduce end-of-line normalization"

Спасибо @vossad01 за указание на это.

Кроме того, при любом решении файлы в вашей рабочей копии по-прежнему сохраняют свои старые окончания строк. Если вы хотите обновить их, убедитесь, что ваше рабочее дерево чистое и используйте:

git rm --cached -r .
git reset --hard

Теперь окончания строк будут правильными в вашем рабочем дереве.

Ответ 3

Альтернативный подход (отличается только используемой командой)

Убедитесь, что у вас нет ожидающих изменений в репозитории:

$ git status
$ git stash

Изменить .gitattributes, поэтому интерпретация CRLF будет изменена:

$ echo "*.txt  text" >>.gitattributes
$ git commit -m "Made .txt files a subject to CRLF normalization." -- .gitattributes

Удалите данные из индекса и обновите рабочий каталог:

$ git rm --cached -r .
$ git reset --hard

Просмотрите исправления CRLF, которые Git предлагает:

$ git ls-files --eol
$ git status
$ git diff

Согласиться с решением Git:

$ git add -u
$ git commit -m "Normalized CRLF for .txt files"

Обновить изменения, как если бы был выполнен чистый клон:

$ git rm --cached -r .
$ git reset --hard

Ответ 4

Настройки .gitattributes будут влиять только на новые коммиты. Если этот репозиторий не опубликовал историю (другие не зависят от нее), вам может понадобиться пройти всю историю. В Unix/Linux вы можете использовать dos2unix(1) для исправления всех файлов в сочетании с find(1) и использования перезаписи истории filter-branch (см. обсуждение в книге git) вы можете даже очистить всю историю проекта.

Используйте с максимальной осторожностью, на новом клоне. Свяжитесь с кем-нибудь, у кого может быть клон, и сообщите им, что вы хотите сделать.

Ответ 5

Опция * text = auto в .gitattributes оставляет репозиторий Git в "недопустимом состоянии", если он содержит файлы с окончаниями строк CRLF (Windows), которые теперь помечены как текст (см. Https://marc.info/?l=git&m = 154484903528621 & w = 2). Стандартный параметр перенормировки не работает корректно с фильтрами LFS, поэтому инструкции в других ответах или, например, на https://help.github.com/en/articles/dealing-with-line-endings, работают неправильно, Вместо этого эти шаги работали для нас:

Ситуация:

  • На винде
  • Git-репозиторий содержал файлы с окончаниями строк CR и CRLF
  • Добавлен * text = auto в .gitattributes (поэтому не зависит от того, установил ли пользователь core.crlf = auto в Windows)
  • Также изменил -crlf на -text для отслеживаемых файлов LFS, но не уверен, что это необходимо.

    1. Создайте новую ветвь из ветки с проблемой окончания строки (при условии, что в ней нет незафиксированных изменений): git checkout -b feature/do-stuff-fix-eol
    2. Удалите фильтры LFS из .gitattributes (замените все 'filter = lfs diff = lfs merge = lfs' ничем)
    3. Зафиксировать и нажать: git commit -a -m "Отключить фильтры LFS для исправления EOL"
    4. Переместить в не git папку
    5. Деинсталлируйте LFS глобально: git lfs uninstall
    6. Создайте новый клон репозитория: git clone -b feature/do-stuff-fix-eol [URL удаленного репозитория] fix-eol
    7. Нормализовать окончания строк: git add --renormalize. (обратите внимание на точку, чтобы перенормировать все файлы)
    8. Проверяйте только правильные файлы нормализованных. Он не должен включать файлы, обычно обрабатываемые LFS!
    9. Зафиксировать и нажать (сохранить хеш): git commit -m "Исправить окончания строк"
    10. Переместить в не git папку
    11. Установите LFS глобально: git lfs install
    12. Перейти к исходному хранилищу клона и вытащить
    13. Оформите свою оригинальную ветку: git checkout особенность/делать вещи
    14. Вишня выбирает фиксацию eol и нажимает: git cherry-pick [hash]
    15. Удалить ветку eol и нажать
    16. Удалите клон репозитория eol (или держите его, если вам нужно исправить больше веток)