Как преобразования конца строки работают с git core.autocrlf между различными операционными системами
Я прочитал много разных вопросов и ответов по переполнению стека, а также git документацию о том, как работает параметр core.autocrlf.
Это мое понимание того, что я прочитал:
Клиенты Unix и Mac OSX (pre-OSX использует CR) используют LF-окончания строк.
Клиенты Windows используют окончания строки CRLF.
Когда для core.autocrlf на клиенте установлено значение true, репозиторий git всегда сохраняет файлы в формате окончания строки LF, а окончания строк в файлах на клиенте конвертируются туда-сюда при извлечении / подтверждении для клиентов (т. Е. Windows), которые используют не -LF окончания строк, независимо от формата файлов окончаний строк на клиенте (это не согласуется с определением Тима Клема - см. Обновление ниже).
Вот матрица, которая пытается документировать то же самое для настроек "input" и "false" в core.autocrlf с вопросительными знаками, где я не уверен в поведении конвертации, заканчивающемся строкой.
Мои вопросы:
- Какими должны быть знаки вопроса?
- Правильна ли эта матрица для "не вопросительных знаков"?
Я обновлю вопросительные знаки из ответов, поскольку консенсус, кажется, сформирован.
значение core.autocrlf верный ввод ложный -------------------------------------------------- -------- совершать | перерабатывать?? новый | в LF (преобразовать в LF?) (без преобразования?) совершать | преобразовать в? нет существующий | LF (конвертировать в LF?) Конвертация оформить заказ | преобразовать в? нет существующий | CRLF (без конвертации?) Конвертация
Я на самом деле не ищу мнения о плюсах и минусах различных настроек. Я просто ищу данные, которые проясняют, как ожидать, что git будет работать с каждой из трех настроек.
-
Обновление 17.04.2012: После прочтения статьи Тима Клема, связанной JJD в комментариях, я изменил некоторые значения в "неизвестных" значениях в приведенной выше таблице, а также изменил "checkout существующие | true для преобразования". в CRLF вместо конвертации в клиента ". Вот определения, которые он дает, которые более понятны, чем все, что я видел в других местах:
core.autocrlf = false
Это значение по умолчанию, но большинству людей рекомендуется изменить это немедленно. Результатом использования false является то, что Git никогда не связывается с окончаниями строк в вашем файле. Вы можете проверить файлы с помощью LF, CRLF или CR, или какой-то случайной комбинации этих трех, и Git это не волнует. Это может затруднить чтение различий и затруднить их объединение. Большинство людей, работающих в мире Unix/Linux, используют это значение, потому что у них нет проблем с CRLF, и им не нужно, чтобы Git выполнял дополнительную работу всякий раз, когда файлы записываются в базу данных объектов или записываются в рабочий каталог.
core.autocrlf = true
Это означает, что Git обработает все текстовые файлы и удостоверится, что CRLF заменяется на LF при записи этого файла в базу данных объектов, и превратит все LF обратно в CRLF при записи в рабочий каталог. Это рекомендуемый параметр в Windows, поскольку он гарантирует, что ваш репозиторий можно будет использовать на других платформах, сохраняя CRLF в вашем рабочем каталоге.
core.autocrlf = вход
Это означает, что Git обработает все текстовые файлы и убедится, что CRLF заменяется на LF при записи этого файла в объектную базу данных. Это не будет, однако, делать обратное. Когда вы читаете файлы обратно из базы данных объектов и записываете их в рабочий каталог, они все равно будут иметь LF для обозначения конца строки. Этот параметр обычно используется в Unix/Linux/OS X для предотвращения записи CRLF в репозиторий. Идея заключалась в том, что если вы вставили код из веб-браузера и случайно поместили CRLF в один из ваших файлов, Git удостоверится, что они будут заменены на LF при записи в базу данных объектов.
Статья Тима отличная, единственное, о чем я могу подумать, что она отсутствует, это то, что он предполагает, что репозиторий имеет формат LF, что не всегда верно, особенно для проектов только для Windows.
Сравнение статьи Тима с ответом jmlane, получившим наибольшее количество голосов на сегодняшний день, показывает идеальное согласие с истинными и исходными настройками и несогласие с ложными настройками.
8 ответов
Лучшее объяснение того, как core.autocrlf
Работы можно найти на странице руководства gitattributes, в text
раздел атрибутов.
Вот как core.autocrlf
кажется, работает в настоящее время (или, по крайней мере, начиная с v1.7.2, насколько я знаю):
core.autocrlf = true
- Текстовые файлы извлечены из хранилища, которые имеют только
LF
символы нормализуются кCRLF
в вашем рабочем дереве; файлы, которые содержатCRLF
в хранилище не тронут - Текстовые файлы, которые имеют только
LF
символы в репозитории, нормализованы отCRLF
вLF
когда передано обратно в хранилище. Файлы, которые содержатCRLF
в хранилище будет совершено нетронутым.
- Текстовые файлы извлечены из хранилища, которые имеют только
core.autocrlf = input
- Текстовые файлы, извлеченные из хранилища, сохранят оригинальные символы EOL в вашем рабочем дереве.
- Текстовые файлы в вашем рабочем дереве с
CRLF
символы нормализуются кLF
когда передано обратно в хранилище.
core.autocrlf = false
core.eol
диктует символы EOL в текстовых файлах вашего рабочего дерева.core.eol = native
по умолчанию это означает, что Windows EOLsCRLF
и *nix EOLsLF
в рабочих деревьях.- вместилище
gitattributes
Настройки определяют нормализацию символов EOL для коммитов в репозиторий (по умолчанию нормализацияLF
персонажи).
Я только недавно исследовал эту проблему, и я также нахожу ситуацию очень запутанной. core.eol
Настройка определенно помогла выяснить, как символы EOL обрабатываются в git.
Проблема EOL в проектах на смешанных платформах уже давно делает мою жизнь несчастной. Проблемы обычно возникают, когда в репозитории уже есть файлы с разными и смешанными EOL. Это означает, что:
- В репо могут быть разные файлы с разными EOL
- Некоторые файлы в репо могут иметь смешанную EOL, например, комбинацию
CRLF
а такжеLF
в том же файле.
Как это происходит, проблема не в этом, но это случается.
Я провел несколько тестов конвертации в Windows для различных режимов и их комбинаций.
Вот что я получил в слегка измененной таблице:
| Результирующее преобразование, когда | Результирующее преобразование, когда | фиксация файлов с различными | проверка ОТ РЕПО - | EOLS INTO РЕПО и | со смешанными файлами в нем и | Значение core.autocrlf: | Значение core.autocrlf: -------------------------------------------------------------------------------- Файл | правда | вход | ложь | правда | вход | ложный -------------------------------------------------------------------------------- Windows-CRLF | CRLF -> LF | CRLF -> LF | как есть | как есть | как есть | как есть Unix -LF | как есть | как есть | как есть | LF -> CRLF | как есть | как есть Mac -CR | как есть | как есть | как есть | как есть | как есть | как есть Смешанный-CRLF+LF | как есть | как есть | как есть | как есть | как есть | как есть Смешанный-CRLF+LF+CR | как есть | как есть | как есть | как есть | как есть | как есть
Как вы можете видеть, есть 2 случая, когда преобразование происходит при фиксации (3 левых столбца). В остальных случаях файлы фиксируются как есть.
После оформления заказа (3 правых столбца) конверсия происходит только в одном случае, когда:
core.autocrlf
являетсяtrue
а также- файл в репо имеет
LF
EOL.
Самое удивительное для меня, и я подозреваю, что причина многих проблем с EOL заключается в том, что не существует конфигурации, в которой смешанный EOL подобен CRLF
+LF
нормализоваться.
Обратите внимание, что "старые" Mac EOLs CR
только и никогда не обращайся.
Это означает, что если плохо написанный сценарий преобразования EOL пытается преобразовать смешанный конечный файл с CRLF
s+LF
с, просто конвертируя LF
с CRLF
с, то он оставит файл в смешанном режиме с "одиноким" CR
где бы ни CRLF
был преобразован в CRCRLF
,
Git не будет ничего конвертировать, даже в true
режим, и EOL хаос продолжается. Это на самом деле произошло со мной и испортило мои файлы очень сильно, поскольку некоторые редакторы и компиляторы (например, VS2010) не любят Mac EOL.
Я думаю, что единственный способ по-настоящему справиться с этими проблемами - иногда нормализовать весь репо, проверяя все файлы в input
или же false
режим, выполняющий правильную нормализацию и повторно фиксирующий измененные файлы (если есть). В Windows предположительно возобновить работу с core.autocrlf true
,
core.autocrlf
значение не зависит от типа ОС, но от Windows значение по умолчанию true
а для линукса - input
, Я исследовал 3 возможных значения для случаев фиксации и извлечения, и вот таблица:
╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║ false ║ input ║ true ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ git commit ║ LF => LF ║ LF => LF ║ LF => LF ║
║ ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => LF ║ CRLF => LF ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ git checkout ║ LF => LF ║ LF => LF ║ LF => CRLF ║
║ ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
Ситуация "Eol Conversion" скоро изменится с выходом Git 1.7.2:
Новый конфиг core.eol
добавляется / развивается:
Это замена для "Добавить"
core.eol
"config variable" commit, который в данный момент находится вpu
(последний в моей серии).
Вместо того чтобы подразумевать, что "core.autocrlf=true
"это замена"* text=auto
", это делает явным тот факт, чтоautocrlf
только для пользователей, которые хотят работать с CRLF в своем рабочем каталоге в хранилище, которое не имеет нормализации текстовых файлов.
Когда он включен, "core.eol" игнорируется.Введите новую переменную конфигурации "
core.eol
msgstr ", который позволяет пользователю указать, какие окончания строки использовать для нормализованных в конце строки файлов в рабочем каталоге.
По умолчанию "native
", что означает CRLF в Windows и LF везде. Обратите внимание, что"core.autocrlf
"переопределяетcore.eol
,
Это означает, что:[core] autocrlf = true
помещает CRLF в рабочий каталог, даже если
core.eol
установлен на "lf
".core.eol:
Устанавливает тип окончания строки для использования в рабочем каталоге для файлов, которые имеют
text
набор свойств.
Альтернативами являются 'lf', 'crlf' и 'native', которые используют окончание собственной строки платформы.
Значением по умолчанию являетсяnative
,
Другие эволюции рассматриваются:
Для 1.8 я бы подумал сделать
core.autocrlf
просто включите нормализацию и оставьте решение об окончании строки рабочего каталога на core.eol, но это нарушит настройки людей.
Git 2.8 (март 2016) улучшает способ core.autocrlf
влияет на eol:
См. Коммит 817a0c7 (23 февраля 2016 г.), коммит 6e336a5, коммит df747b8, коммит df747b8 (10 фев 2016 г.), коммит df747b8, коммит df747b8 (10 фев 2016 г.) и коммит 4b4024f, коммит bb211b4, коммит 92cce13, коммит 320d39c, коммит 4b40 коммит bb211b4, коммит 92cce13, коммит 320d39c (05 февраля 2016 г.) от Torsten Bögershausen ( tboegi
)
(Объединено Юнио С Хамано - gitster
- в коммите c6b94eb, 26 февраля 2016 г.)
convert.c
: рефакторингcrlf_action
Рефакторинг определения и использования
crlf_action
,
Сегодня, когда нетcrlf
атрибут установлен в файле,crlf_action
установлен вCRLF_GUESS
, использованиеCRLF_UNDEFINED
вместо этого и искать "text
" или же "eol
" как прежде.Замени старое
CRLF_GUESS
использование:
CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT
Проясните, что к чему, определив:
- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
and core.eol is evaluated and one of CRLF_BINARY,
CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY : No processing of line endings.
- CRLF_TEXT : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true (no attributes)
Как torek добавляет в комментариях:
все эти переводы (любое преобразование EOL из
eol=
или жеautocrlf
настройки иclean
"фильтры" запускаются, когда файлы перемещаются из рабочего дерева в индекс, т. е. во времяgit add
а не вgit commit
время.
(Обратите внимание, чтоgit commit -a
или же--only
или же--include
добавьте файлы в индекс в то время.)
Подробнее об этом см. "В чем разница между autocrlf и eol ".
Вот мое понимание этого до сих пор, на случай, если это кому-то поможет.
core.autocrlf=true
а также core.safecrlf = true
У вас есть репозиторий, в котором все окончания строк одинаковы, но вы работаете на разных платформах. Git позаботится о том, чтобы окончания строк были преобразованы в значения по умолчанию для вашей платформы. Почему это важно? Допустим, вы создаете новый файл. Текстовый редактор на вашей платформе будет использовать окончания строк по умолчанию. Когда вы включаете его, если для core.autocrlf не установлено значение true, вы вводите несоответствие конца строки для кого-то на платформе, которая по умолчанию имеет другое окончание строки. Я тоже всегда устанавливаю safecrlf, потому что хотел бы знать, что операция crlf обратима. С этими двумя настройками git изменяет ваши файлы, но проверяет, что изменения обратимы.
core.autocrlf=false
У вас есть репозиторий, в котором уже зарегистрированы смешанные окончания строк, и исправление неправильных окончаний строк может привести к поломке других вещей. В этом случае лучше не указывать git преобразовывать окончания строк, потому что тогда это усугубит проблему, для решения которой оно было разработано - облегчить чтение различий и объединить менее болезненные. С этим параметром git не изменяет ваши файлы.
core.autocrlf=input
Я не использую это, потому что причина этого состоит в том, чтобы покрыть случай использования, когда вы создали файл с окончаниями строк CRLF на платформе, по умолчанию заканчивающимися на концах строк LF. Вместо этого я предпочитаю, чтобы мой текстовый редактор всегда сохранял новые файлы со значениями конца строки на платформе.
Нет, ответ @jmlane неправильный.
За Checkin (git add, git commit)
:
- если
text
свойствоSet, Set value to 'auto'
, преобразование происходит, если файл был зафиксирован с помощью CRLF - если
text
свойствоUnset
: ничего не происходитCheckout
- если
text
свойствоUnspecified
, конверсия зависит отcore.autocrlf
- если
autocrlf = input or autocrlf = true
преобразование происходит только тогда, когда файл в хранилище имеет значение "LF", если это был "CRLF", ничего не произойдет. - если
autocrlf = false
, Ничего не произошло
- если
За Checkout
:
- если
text
свойствоUnset
: Ничего не произошло. - если
text
свойствоSet, Set value to 'auto
: это зависит отcore.autocrlf
,core.eol
,- core.autocrlf = input: ничего не происходит
- core.autocrlf = true: преобразование происходит только тогда, когда файл в хранилище имеет значение "LF", "LF" -> "CRLF"
- core.autocrlf = false: преобразование происходит только тогда, когда файл в хранилище имеет значение "LF", "LF" ->
core.eol
- если
text
свойствоUnspecified
, это зависит отcore.autocrlf
,- такой же как
2.1
- такой же как
2.2
- Ничего, ничего не происходит, core.eol не эффективен, когда
text
свойствоUnspecified
- такой же как
Поведение по умолчанию
Таким образом, поведение по умолчанию text
свойство Unspecified
а также core.autocrlf = false
:
- для регистрации ничего не происходит
- для оформления заказа ничего не происходит
Выводы
- если
text
свойство установлено, поведение при регистрации зависит от самого себя, а не от autocrlf - autocrlf или core.eol для поведения извлечения, и autocrlf > core.eol
Провел несколько тестов как на Linux, так и на Windows. Я использую тестовый файл, содержащий строки, оканчивающиеся на LF, а также строки, оканчивающиеся на CRLF.
Файл зафиксирован, удален и затем извлечен. Значение core.autocrlf устанавливается перед фиксацией, а также перед извлечением. Результат ниже.
commit core.autocrlf false, remove, checkout core.autocrlf false: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf input: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf true : LF=>LF CRLF=>CRLF
commit core.autocrlf input, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
commit core.autocrlf true, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
Заявление
core.autocrlf=true
ведущий к
CRLF -> LF
на фиксации все неправильно! Не все так просто, как вы увидите ...
В документах говорится, что этот параметр соответствует ... «in and be set to in git config» ... что именно означает?
Это означает, что если для файла не установлен текстовый атрибут, а если есть, то теперь это зависит от того, является ли фиксируемый файл новым (в этом случае да, он будет нормализован до LF в базе данных репозитория git), или был ли это уже существующий файл, который вы редактировали и сейчас фиксируете (в этом случае НИЧЕГО не произойдет ... если вы не запустите
git add --renormalize .
в этом случае он будет нормализован в базе данных репозитория git).
Видите ли ... весь механизм происходит только с файлом, для которого a не поместил вариант текстового атрибута:
text
,
-text
,.
Итак, на что вам действительно стоит обратить внимание, так это на использование
.gitattributes
с настройкой по умолчанию для всех ваших файлов:
* -text
# followed by specialization
который по умолчанию для всех (кроме специализаций) будет как есть, полностью переопределив или используя значение по умолчанию:
* text=auto
# followed by specialization
Это означает, что все файлы (кроме специализаций), которые git автоматически определяет как небинарные (текстовые) и которые есть в базе данных git [см. примечание 1.], будут получать каждый раз:
•
core.autocrlf
является
true
, или
• является
crlf
, или
•
core.eol
является
native
(по умолчанию), и вы используете платформу Windows.
Во всех остальных случаях вы получите.
Какие специализации я имею в виду? Например, имея
.bat
файлы быть
CRLF
а также
.sh
файлы быть
LF
либо через:
*.sh text eol=lf
# *.bat
*.[bB][aA][tT] text eol=crlf
или
# *.sh are committed correctly as-is (LF)
*.sh -text
# *.bat are committed correctly as-is (CRLF)
*.[bB][aA][tT] -text
Так что да ... все не так просто.
[примечание 1]:
это будет иметь место для всех файлов, соответствующих
text=auto
атрибут (т.е. не имеющий какой-либо другой специализации), поскольку я предполагаю, что ваше репо было правильно нормализовано, когда
.gitattribute
был создан