Почему я должен использовать core.autocrlf = true в Git?

296

У меня есть Git-репозиторий, доступ к которому возможен как из Windows, так и из OS X, и я знаю, что он уже содержит некоторые файлы с окончаниями CRLF. Насколько я могу судить, есть два способа справиться с этим:

  1. Набор core.autocrlfдля falseвезде,

  2. Следуйте приведенным здесь инструкциям (отраженным на страницах справки GitHub), чтобы преобразовать репозиторий так, чтобы он содержал только LF-окончания, и после этого установите core.autocrlfего trueв Windows и inputOS X. Проблема заключается в том, что если у меня есть какие-либо двоичные файлы в репозитории который:

    1. неправильно помечены как двоичные в gitattributes, и
    2. случайно содержат как CRLF, так и LF,

    они будут испорчены. Возможно, мой репозиторий содержит такие файлы.

Так почему я не должен просто отключить конвертацию конца строки в Git? В сети много смутных предупреждений о core.autocrlfвыключении, вызывающих проблемы, но очень мало конкретных ; единственное, что я нашел до сих пор, это то, что kdiff3 не может обрабатывать окончания CRLF (для меня это не проблема), и что некоторые текстовые редакторы имеют проблемы с окончанием строки (для меня это тоже не проблема).

Репозиторий является внутренним для моей компании, поэтому мне не нужно беспокоиться о том, чтобы делиться им с людьми с различными настройками autocrlf или требованиями к концу строки.

Есть ли какие-то другие проблемы с тем, чтобы просто оставить окончания строк, как я знаю?

Богатый
источник
1
Поможет ли stackoverflow.com/questions/2333424/… ? У меня есть ссылка на конкретные причины ухода autocrlfна ложь.
VonC
3
@VonC Спасибо, но я уже могу диктовать, что все пользователи в компании установили для <code> autocrlf </ code> значение false и в настоящее время считают, что это лучший вариант. Но я хочу знать, есть ли какие-либо причины, почему я не должен этого делать, потому что я могу найти, что есть много людей (например, GitHub), которые говорят, что autocrlf должен быть установлен, но нет конкретных подробностей относительно того, почему.
Богатый
3
@VonC, т.е. я не ищу причины для установки autocrlfв ложь. Я ищу причины, чтобы установить это на истину.
Богатый
9
Почему бы не использовать autocrlf = input: кажется, что это идеальное решение между двумя крайностями: вы сохраняете свое хранилище в чистоте от CRLF-дерьма, и локально разработчики Windows могут использовать все, что захотят, без того, чтобы в их локальных файлах ничего не происходило автоматически. (Они могут хотеть LF локально по разным причинам, поэтому true, на мой взгляд , это плохо.) Я не вижу никаких минусов в использовании autocrlf = input.
иконоборчество
7
@iconclast, одна из причин, по которой я столкнулся, заключается в том, что вы создаете дистрибутивы, включающие как пакетные файлы Windows, так и сценарии оболочки Unix. Вы хотите использовать правильное окончание строки в каждом случае, и это будет труднее сделать, если Git быстро меняет ситуацию, даже если вы явно указали их так или иначе.
user1809090

Ответы:

227

Единственные конкретные причины , чтобы установить autocrlfна trueследующие:

  • избегайте git statusпоказывать все ваши файлы, так modifiedкак из-за автоматического преобразования EOL, выполняемого при клонировании репозитория EOL Git на основе Unix, в Windows (см., например, выпуск 83 )
  • и ваши инструменты кодирования как-то зависят от нативного стиля EOL, присутствующего в вашем файле:
    • например, генератор кода, жестко запрограммированный для обнаружения нативного EOL
    • другие внешние пакеты (внешние для вашего репо) с регулярным выражением или набором кодов для определения собственного EOL
    • Я считаю, что некоторые плагины Eclipse могут создавать файлы с CRLF независимо от платформы, что может быть проблемой.
    • Вы кодируете с помощью Notepad.exe ( если вы не используете Windows 10 2018.09+, где Notepad учитывает обнаруженный символ EOL ).

Если вы не видите специальное лечение, которое должно иметь дело с нативным EOL, вам лучше уйти autocrlfвfalse ( git config --global core.autocrlf false).

Обратите внимание, что этот конфиг будет локальным (поскольку конфиг не перемещается из репо в репо)

Если вам нужна одинаковая конфигурация для всех пользователей, клонирующих этот репозиторий, проверьте « Какова лучшая CRLFстратегия обработки с помощью git? », Используя textатрибут в .gitattributesфайле .

Пример:

*.vcproj    text eol=crlf
*.sh        text eol=lf

Примечание: начиная с git 2.8 (март 2016 г.), маркеры слияния больше не будут вводить смешанный конец строки (LF) в файле CRLF.
Смотрите « Заставьте Git использовать CRLF на его строках слияния« <<<<<<< HEAD » »

VonC
источник
5
@VonC Спасибо! Это помогает мне чувствовать себя более уверенно, что это безопасно для меня autocrlf=false. Из интереса, знаете ли вы, почему git по-прежнему выполняет преобразование eol, даже если для autocrlf установлено значение false?
Богатый
14
@VonC: я не думаю, что этот ответ правильный. Использование core.autocrlf = true в Windows работает должным образом. Все файлы из репозитория (в этом сценарии должны быть окончания строк LF) преобразуются в окончания строк CRLF при оформлении заказа на ПК с Windows. Все файлы преобразуются обратно в LF-окончания строк при фиксации с ПК с Windows. Чтобы попасть в беду, сначала нужно оформить заказ на ПК с Windows с неправильной настройкой core.autocrlf (что слишком просто сделать).
Майкл Мэддокс
3
@Michael Так что в этом случае единственная причина, по которой я не буду использовать core.autocrlf=falseв моем сценарии, заключается в том, что у меня есть какой-нибудь инструмент / редактор, который может запутаться в конце строки?
Рич
49
Я бы определенно использовал false, я никогда не был большим поклонником автоматических или волшебных вещей, происходящих на заднем плане. Просто используйте \nи UTF-8везде, и вы будете в порядке. Если какой-то чокнутый не понимает, что существуют соглашения и правила, и забывает использовать UTF-8или \n, то кто-то конвертирует их вручную и шлепает себя по лицу.
Башня
5
@ Pauld'Aoust Я бы все же предпочел указать тип файла, для которого требуется этот CRLF, через core.eolатрибуты в .gitattributesфайле, а не использовать этот глобальный core.autocrlfпараметр, который применяется без разбора ко всем файлам.
VonC
40

Я являюсь разработчиком .NET и уже много лет использую Git и Visual Studio. Я настоятельно рекомендую установить окончание строк на true. И сделайте это как можно раньше при жизни вашего репозитория.

При этом я НЕНАВИЖУ, что Git меняет окончание моей строки. Источник контроля должен только сохранять и извлекать работу, которую я делаю, он не должен изменять ее. Когда-либо. Но это так.

Что произойдет, если у каждого разработчика не будет установлено значение true, если ОДИН разработчик в конечном итоге установит значение true. Это приведет к изменению конца строк всех ваших файлов на LF в вашем репо. А когда пользователи установят false, проверьте их, Visual Studio предупредит вас и попросит изменить их. У вас 2 вещи произойдут очень быстро. Во-первых, вы будете получать все больше и больше таких предупреждений: чем больше ваша команда, тем больше вы получаете. Второе, и самое худшее, это то, что он покажет, что каждая строка каждого измененного файла была изменена (потому что окончание каждой строки будет меняться настоящим парнем). В конце концов вы больше не сможете надежно отслеживать изменения в своем репо. Гораздо проще и чище заставить всех держаться правды, чем пытаться всех обмануть. Как бы ужасно ни было жить с тем фактом, что ваш надежный источник контроля делает то, что не должен. Когда-либо.

JGTaylor
источник
Моя компания настолько мала, что мы можем легко установить, что ложь используется повсеместно, и я бы подумал, что более крупные компании могут сделать это с помощью политики, но я думаю, что это законная причина для использования «истины», так что я голосую тем не мение. Спасибо!
Богатые
1
Проблема, связанная с выполнением этого с помощью политики (принудительного использования файла), заключается в том, что на компьютере с Windows вы можете иметь локальный, глобальный и скрытый файл конфигурации (ProgramData / Git / Confg). Вы можете принудительно установить локальный, отметив его в репозитории, но глобальные И скрытые файлы имеют приоритет. Также возможно, чтобы локальный и глобальный (или скрытый) отличались. Если они есть, они будут конфликтовать друг с другом на том же компьютере, вызывая ошибки окончания строки, где их нет. Это боль, чтобы выследить. :(
JGTaylor
7
именно то, что я думаю. работа с исходным кодом не должна связываться с файлами кода, как им заблагорассудится. Концы строк должны быть просто заботой об инструментах редактирования, не более того.
Tuncay Göncüoğlu
6
Если ваш проект только для Windows, то проблем нет. Однако, если вы или ваши коллеги работаете на платформе * nix, тогда ваша «сильная рекомендация» вызовет проблемы. Попробуйте запустить скрипт bash, perl или python, заканчивая символом shebang, \r\nи вы увидите.
phuclv
6
Ситуация, которую вы описали как не проблема GIT, установите значение FALSE, как обычно, и оно исчезло. Инстад, это проблема в командной работе. Что значит «в конечном итоге один разработчик устанавливает true»? Почему вы позволите им это в первую очередь? когда вы настраиваете их для доступа к git-репо, то точно так же, как вы не разрешаете загрязнять определенные области разными языками (так что любой, кто работает над этим, может его прочитать), или как вы держите ветки / слияния / ребазы / и т. д. вдоль выбранного политика, они должны получить четкое правило: установить правильный crlf.
Кетцалькоатль
12

Обновление 2 :

Xcode 9, кажется, имеет «особенность», в которой он будет игнорировать текущие окончания строки файла, и вместо этого просто использовать настройку окончания строки по умолчанию при вставке строк в файл, что приводит к файлам со смешанными окончаниями строк.

Я почти уверен, что этой ошибки не было в Xcode 7; не уверен насчет Xcode 8. Хорошей новостью является то, что, похоже, это исправлено в Xcode 10.

За то время, что она существовала, эта ошибка вызывала небольшое количество веселья в кодовой базе, на которую я ссылаюсь в этом вопросе (который используется по сей день autocrlf=false), и привела ко многим сообщениям коммита «EOL» и, в конечном итоге, к моему написанию git- pre-commitхука для проверки для / предотвращения введения смешанных концов строки.

Обновить :

Примечание: Как было отмечено VonC, начиная с Git 2.8, маркеры слияния будет не вводить Unix-стиль завершений строк в файл для Windows-стиле .

оригинал :

Один небольшой сбой, который я заметил в этой настройке, заключается в том, что когда возникают конфликты слияния, строки, добавляемые git для обозначения различий, не имеют конца строки в Windows, даже когда остальная часть файла есть, и вы можете получить с файлом со смешанными окончаниями строк, например:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

Это не вызывает у нас никаких проблем (я полагаю, что любой инструмент, который может обрабатывать оба типа окончания строки, будет также иметь дело со смешанными окончаниями строки - конечно, все, что мы используем), но это то, о чем нужно знать.

Еще одна вещь, * обнаруженная нами, заключается в том, что при использовании git diffдля просмотра изменений в файле, имеющем окончания строк в Windows, добавленные строки отображают возврат каретки, таким образом:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

* Это на самом деле не заслуживает термина «проблема».

Богатый
источник
2
NB Когда Visual Studio встречает такой файл, он предлагает нормализовать окончания строк для вас. Выбор конца строки Windows или выбор не нормализации конца строки работает нормально (поскольку VS по-прежнему отображает его правильно, ошибочные строки будут удалены после разрешения конфликта).
Богатое
2
К сожалению, нацисты корпоративного контроля версий с этим не согласны (LF на маркерах конфликта слияния) не является проблемой.
Илья Г
1
Я согласен, что LF на маркерах конфликта слияния не должен быть проблемой. Эти строки не должны быть привязаны к репо в любом случае.
ограбить
1
Примечание: начиная с git 2.8 (март 2016 г.), маркеры слияния будут фактически заканчиваться строкой CRLF. См stackoverflow.com/a/35474954/6309
VonC