Какова лучшая стратегия обработки CRLF (возврат каретки, перевод строки) с Git?
-
05-07-2019 - |
Вопрос
Я пытался зафиксировать файлы со строками, заканчивающимися CRLF, но это не удалось.
Я провел целый рабочий день на своем компьютере с Windows, пробуя разные стратегии, и мне почти захотелось прекратить попытки использовать Git и вместо этого попробовать Меркуриальный.
Пожалуйста, поделитесь только одним передовым опытом в каждом ответе.
Решение
Спустя почти четыре года после того, как я задал этот вопрос, я наконец-то нашел ответ, который меня полностью устраивает !
Подробности см. в руководстве github: help по Работа с окончаниями строк .
Git позволяет вам установить конечные свойства строки для Сделайте репо напрямую, используя текстовый атрибут в Файл
.gitattributes
. Этот файл передан в репозиторий и переопределяет настройкуcore.autocrlf
, позволяя вам обеспечить последовательное поведение для всех пользователи независимо от их настроек git.
И, таким образом,
Преимущество этого в том, что ваш конец строки Конфигурация теперь путешествует с вашим хранилищем, и вы не нужно беспокоиться о том, соавторы иметь правильные глобальные настройки.
Вот пример файла .gitattributes
# Auto detect text files and perform LF normalization
* text=auto
*.cs text diff=csharp
*.java text diff=java
*.html text diff=html
*.css text
*.js text
*.sql text
*.csproj text merge=union
*.sln text merge=union eol=crlf
*.docx diff=astextplain
*.DOCX diff=astextplain
# absolute paths are ok, as are globs
/**/postinst* text eol=lf
# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf
Существует удобная коллекция готовых к использованию файлов .gitattributes для самых популярных языков программирования. Это полезно для начала.
После того как вы создали или настроили свои .gitattributes
, вы должны выполнить раз и навсегда повторная нормализация окончаний строк .
Обратите внимание, что приложение GitHub Desktop может предложить и создать .gitattributes
. файл после открытия репозитория Git вашего проекта в приложении. Чтобы попробовать это, нажмите значок шестеренки (в верхнем правом углу) > Настройки репозитория ... > Концы строк и атрибуты. Вам будет предложено добавить рекомендуемые .gitattributes
, и, если вы согласитесь, приложение также выполнит нормализацию всех файлов в вашем хранилище.
Наконец, статья «Следите за своей линией» дает больше информации и объясняет, как развивался Git по актуальным вопросам. Я считаю это обязательным чтением .
Возможно, в вашей команде есть пользователи, которые используют EGit или JGit (такие инструменты, как Eclipse и TeamCity, используют их) для фиксации своих изменений. Тогда вам не повезло, как объясняет @gatinueta в комментариях к этому ответу:
Этот параметр не удовлетворит вас полностью, если в вашей команде есть люди, работающие с Egit или JGit, поскольку эти инструменты будут просто игнорировать .gitattributes и успешно проверять файлы CRLF https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372
Один из приемов может заключаться в том, чтобы они зафиксировали свои изменения в другом клиенте, например, SourceTree . Тогда наша команда предпочитала этот инструмент Eclipse EGit для многих случаев использования.
Кто сказал, что программное обеспечение легко? : - /
Другие советы
Не конвертируйте окончания строк. Это не работа VCS, чтобы интерпретировать данные - просто сохраните и версируйте их. В любом случае любой современный текстовый редактор может читать оба вида концов строк.
Вы почти всегда хотите autocrlf=input
если только вы действительно не знаете, что делаете.
Некоторый дополнительный контекст ниже:
Это должно быть либо
core.autocrlf=true
Если вам нравится окончание DOS илиcore.autocrlf=input
Если вы предпочитаете Unix-Newlines.В обоих случаях ваш репозиторий GIT будет иметь только LF, и это правильное.Единственный аргумент дляcore.autocrlf=false
Была ли эта автоматическая эвристика может неправильно обнаружить какой -то бинарный в виде текста, а затем ваша плитка будет повреждена.Так,core.safecrlf
Была введена опция, чтобы предупредить пользователя, если произойдет неровное изменение.Фактически, существует две возможности непрерывных изменений-в конечном итоге в текстовом файле смешанной линии, в этой нормализации желательно, поэтому это предупреждение можно игнорировать или (очень маловероятно), что GIT неправильно обнаружил ваш бинарный файл как текст.Затем вам нужно использовать атрибуты, чтобы сказать GIT, что этот файл является двоичным.
Приведенный выше абзац изначально был взят из темы на gmane.org, но с тех пор удален.
Две альтернативные стратегии будьте последовательны об окончании строк в смешанных средах (Microsoft + Linux + Mac):
А.Глобальный за настройку всех репозиториев
1) Конвертировать все в одном формате
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) Установить core.autocrlf
к input
в Linux/UNIX или true
в MS Windows (репозиторий или глобально)
git config --global core.autocrlf input
3) [Дополнительно] установлен core.safecrlf
к true
(чтобы остановиться) или warn
(петь :), чтобы добавить дополнительную защиту, сравнивая, приведет ли обратное преобразование новой строки к тому же файлу
git config --global core.safecrlf true
Б.Или за настройку репозитория
1) Конвертировать все в одном формате
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) добавить .gitattributes
файл в свой репозиторий
echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'
Не беспокойтесь о своих двоичных файлах — Git должен быть достаточно умен в их отношении.
Попробуйте установить для параметра конфигурации core.autocrlf
значение true
. Также обратите внимание на параметр core.safecrlf
.
На самом деле это звучит так, как будто core.safecrlf
уже задан в вашем хранилище, потому что (выделение мое):
Если это не относится к текущим настройкам core.autocrlf, git отклонит файл .
Если это так, то вы можете проверить, что ваш текстовый редактор настроен на последовательное использование концов строк. Скорее всего, вы столкнетесь с проблемами, если текстовый файл будет содержать сочетания концов строк LF и CRLF.
Наконец, я чувствую, что рекомендация просто "использовать то, что вам дано" и использование LF-терминалов в Windows вызовет больше проблем, чем решит. У Git есть вышеупомянутые опции, чтобы попытаться обработать окончания строк разумным способом, поэтому имеет смысл использовать их.
Использование core.autocrlf = false
остановило пометки всех файлов как обновленных, как только я проверил их в моем Визуальный проект & nbsp; Studio & nbsp; 2010 . Два других члена команды разработчиков также используют системы Windows, поэтому смешанная среда не вступила в игру, но настройки по умолчанию, поставляемые с хранилищем, всегда отмечали все файлы как обновленные сразу после клонирования.
Я предполагаю, что суть в том, чтобы найти, какой параметр CRLF подходит для вашей среды. Тем более что во многих других репозиториях на наших блоках Linux установка autocrlf = true
дает лучшие результаты.
Спустя 20 с лишним лет, и мы до сих пор имеем дело с разницей в конце строк между ОС ... sad.
Это два варианта Окна и Визуальная Студия пользователи, которые делятся кодом с Мак или Линукс пользователи.Для более подробного объяснения прочтите руководство по gitattributes.
* текст = авто
В вашем репо .gitattributes
добавить файл:
* text=auto
Это нормализует все файлы с LF
окончания строк в репо.
И в зависимости от вашей операционной системы (core.eol
настройки), файлы в рабочем дереве будут нормализованы до LF
для систем на базе Unix или CRLF
для систем Windows.
Это конфигурация, которая Майкрософт .NET использование репозиториев.
Пример:
Hello\r\nWorld
Будет нормализовано в репо всегда как:
Hello\nWorld
При оформлении заказа рабочее дерево в Windows будет преобразовано в:
Hello\r\nWorld
При оформлении заказа рабочее дерево на Mac останется таким:
Hello\nWorld
Примечание:Если ваш репозиторий уже содержит ненормализованные файлы,
git status
отобразит эти файлы как полностью измененные при следующем внесении в них каких-либо изменений, и другим пользователям может быть сложно объединить свои изменения позже.Видеть обновление репозитория после изменения окончания строк Чтобы получить больше информации.
core.autocrlf = правда
Если text
не указано в .gitattributes
файл, Git использует core.autocrlf
переменная конфигурации, определяющая, следует ли конвертировать файл.
Для пользователей Windows: git config --global core.autocrlf true
отличный вариант, потому что:
- Файлы нормализованы до
LF
окончания строк только при добавлении в репо.Если в репозитории есть файлы, не нормализованные, этот параметр их не затронет. - Все текстовые файлы конвертируются в
CRLF
окончания строк в рабочем каталоге.
Проблема с этим подходом заключается в том, что:
- Если вы пользователь Windows с
autocrlf = input
, вы увидите кучу файлов сLF
окончания строк.Не представляет опасности для остальной команды, поскольку ваши коммиты все равно будут нормализованы с помощьюLF
окончания строк. - Если вы пользователь Windows с
core.autocrlf = false
, вы увидите кучу файлов сLF
окончания строк, и вы можете добавлять файлы сCRLF
заканчивается строка в репо. - Большинство пользователей Mac используют
autocrlf = input
и может получить файлы сCRLF
окончания файлов, вероятно, от пользователей Windows сcore.autocrlf = false
.
Это всего лишь обходной путь решение:
В обычных случаях используйте решения, поставляемые с git.В большинстве случаев они отлично работают.Принудительно использовать LF, если вы разделяете разработку в системах на базе Windows и Unix, установив .gitattributes.
В моем случае проект в Windows разрабатывал >10 программистов.Этот проект был проверен CRLF и не было возможности принудительно перейти на LF.
Некоторые настройки были записаны на моей машине без какого-либо влияния на формат LF;таким образом, некоторые файлы глобально менялись на LF при каждом небольшом изменении файла.
Мое решение:
Windows-машины:Пусть все как есть.Не беспокойтесь ни о чем, поскольку вы являетесь разработчиком Windows по умолчанию «одинокий волк», и вам приходится действовать следующим образом:«В мире нет другой системы, не так ли?»
Unix-машины
Добавьте следующие строки в конфигурацию
[alias]
раздел.Эта команда выводит список всех изменений (т.измененные/новые) файлы:lc = "!f() { git status --porcelain \ | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \ | cut -c 4- ; }; f "
Преобразуйте все эти измененный файлы в формат DOS:
unix2dos $(git lc)
Необязательно ...
Создать git крюк для этого действия, чтобы автоматизировать этот процесс
Используйте параметры, включите их и измените
grep
функция для сопоставления только определенных имен файлов, например:... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
Не стесняйтесь сделать это еще удобнее, используя дополнительный ярлык:
c2dos = "!f() { unix2dos $(git lc) ; }; f "
...и запустите преобразованный материал, набрав
git c2dos
Я потратил часы, чтобы придумать наилучшее использование .gitattributes
, наконец осознать, что я не могу на это рассчитывать.
К сожалению, пока существуют редакторы на основе JGit (которые не могут обрабатывать .gitattributes
правильно), безопасное решение — принудительно использовать LF везде, даже на уровне редактора.
Используйте следующее anti-CRLF
дезинфицирующие средства.
клиенты Windows/Linux:
core.autocrlf=input
преданный идее
.gitattributes
:* text=auto eol=lf
преданный идее
.editorconfig
(http://editorconfig.org/), который представляет собой своего рода стандартизированный формат в сочетании с плагинами редактора:
--- ОБНОВЛЕНИЕ 2 ---
В большинстве случаев будут работать настройки клиента git.Даже если у вас есть только клиенты только для Windows, только клиенты для Linux или и то, и другое.Это:
- окна:
core.autocrlf=true
означает преобразование строк в CRLF при оформлении заказа и преобразование строк в LF при добавлении файлов. - Linux:
core.autocrlf=input
означает, что не конвертируйте строки при оформлении заказа (в этом нет необходимости, поскольку ожидается, что файлы будут зафиксированы с помощью LF) и преобразуйте строки в LF (если необходимо) при добавлении файлов.
Свойство может быть установлено в различных областях.Я бы предложил явно указать в --global
область видимости, чтобы избежать некоторых проблем IDE, описанных в конце.
git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf
Также я бы настоятельно обескураживать с использованием git config --global core.autocrlf false
(если у вас есть клиенты только для Windows), в отличие от того, что предлагается Git-документация.Установка значения false приведет к фиксации файлов с CRLF в репозитории.Но на самом деле нет никакой причины.Никогда не знаешь, понадобится ли вам поделиться проектом с пользователями Linux.Кроме того, для каждого клиента, присоединяющегося к проекту, делается один дополнительный шаг вместо использования настроек по умолчанию.
Теперь о некоторых особых случаях файлов (например. *.bat
*.sh
), которые вы хотите, чтобы они были извлечены с помощью LF или с помощью CRLF, вы можете использовать .gitattributes
Подводя итог, для меня лучшая практика является:
- Убедитесь, что каждый недвоичный файл зафиксирован с помощью LF в репозитории git (поведение по умолчанию).
- Используйте эту команду, чтобы убедиться, что файлы не зафиксированы с помощью CRLF:
git grep -I --files-with-matches --perl-regexp '\r' HEAD
(Примечание: на клиентах Windows работает только черезgit-bash
и на клиентах Linux, только если они скомпилированы с использованием--with-libpcre
в./configure
). - Если вы обнаружите такие файлы, выполнив приведенную выше команду, исправьте их.
- Используйте только минимум
.gitattributes
- Попросите пользователей установить
core.autocrlf
описанное выше, к значениям по умолчанию. - Не стоит рассчитывать на 100% наличие
.gitattributes
.git-клиенты IDE могут игнорировать их или относиться к ним по-другому.
Как уже говорилось, некоторые вещи можно добавить в атрибуты git:
# Always checkout with LF
*.sh text eol=lf
# Always checkout with CRLF
*.bat text eol=crlf
Я думаю, что есть другие безопасные варианты .gitattributes
вместо использования автоматического обнаружения двоичных файлов:
-text
(например, для*.zip
или*.jpg
файлы:Не будет рассматриваться как текст.Таким образом, попытки преобразования конца строки выполняться не будут.Разница может быть возможна через программы конвертации)text !eol
(например.для*.java
,*.html
:Рассматривается как текст, но предпочтения стиля eol не заданы.Поэтому используются настройки клиента.)-text -diff -merge
(например, для*.hugefile
:Не рассматривается как текст.Никакие различия/слияния невозможны)
--- ПРЕДЫДУЩЕЕ ОБНОВЛЕНИЕ ---
Один болезненный пример клиента, который неправильно фиксирует файлы:
нетбинс 8.2 (в Windows) ошибочно зафиксирует все текстовые файлы с CRLF, если только у вас есть явно набор core.autocrlf
как глобальный.Это противоречит стандартному поведению клиента git и позже вызывает множество проблем при обновлении/слиянии.Это то, что заставляет некоторых файлы выглядят по-другому (хотя это не так) даже когда ты вернешься.
Такое же поведение в netbeans происходит, даже если вы добавили правильные .gitattributes
в ваш проект.
Использование следующей команды после фиксации, по крайней мере, поможет вам заранее обнаружить, есть ли в вашем репозитории git проблемы с окончанием строк: git grep -I --files-with-matches --perl-regexp '\r' HEAD