Как преобразования конца строки работают с git core.autocrlf между различными операционными системами - PullRequest
197 голосов
/ 08 июля 2010

Я прочитал много разных вопросов и ответов по переполнению стека, а также git документацию о том, как работает параметр core.autocrlf .

Это мое понимание того, что я прочитал:

Клиенты Unix и Mac OSX (pre-OSX использует CR) используют LF-окончания строк.
Клиенты Windows используют окончания строки CRLF.

Когда для core.autocrlf на клиенте установлено значение true, репозиторий git всегда сохраняет файлы в формате окончания строки LF, а окончания строк в файлах на клиенте конвертируются туда-обратно при извлечении / подтверждении для клиентов (т. Е. Windows) которые используют не LF окончания строк, независимо от того, в каком формате файлы окончаний строк находятся на клиенте (это не согласуется с определением Тима Клема - см. обновление ниже).

Вот матрица, которая пытается документировать то же самое для настроек 'input' и 'false' в core.autocrlf с вопросительными знаками, где я не уверен в поведении конвертации, заканчивающемся строкой.

Мои вопросы:

  1. Какими должны быть знаки вопроса?
  2. Корректна ли эта матрица для "не вопросительных знаков"?

Я обновлю вопросительные знаки из ответов, поскольку консенсус, кажется, сформирован.

                       core.autocrlf value
            true            input              false
----------------------------------------------------------
commit   |  convert           ?                  ?
new      |  to LF      (convert to LF?)   (no conversion?)

commit   |  convert to        ?                 no 
existing |  LF         (convert to LF?)     conversion

checkout |  convert to        ?                 no
existing |  CRLF       (no conversion?)     conversion

Я на самом деле не ищу мнения о плюсах и минусах различных настроек. Я просто ищу данные, которые дают понять, как git будет работать с каждой из трех настроек.

-

Обновление 04/17/2012 : После прочтения статьи Тима Клема , связанной JJD в комментариях, я изменил некоторые значения в «неизвестных» значениях в приведенная выше таблица, а также изменение «извлечение существующего | 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 будет гарантировать, что они были заменены LFs, когда вы написали в базу данных объекта.

Статья Тима отличная, единственное, о чем я могу подумать, что она отсутствует, это то, что он предполагает, что репозиторий имеет формат LF, что не всегда верно, особенно для проектов только для Windows.

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

Ответы [ 7 ]

117 голосов
/ 13 декабря 2010

Лучшее объяснение того, как работает core.autocrlf, можно найти на справочной странице gitattributes , в разделе атрибута text.

Так выглядит core.autocrlf в настоящее время.(или хотя бы начиная с v1.7.2 из того, что я знаю):

  • core.autocrlf = true
    1. Текстовые файлы, извлеченные из хранилища, которые имеют только LF символов, нормализованыCRLF в вашем рабочем дереве;файлы, которые содержат CRLF в хранилище, не будут затронуты
    2. Текстовые файлы, содержащие только LF символов в хранилище, нормализуются от CRLF до LF при фиксации обратно в хранилище.Файлы, содержащие CRLF в хранилище, будут сохранены без изменений.
  • core.autocrlf = input
    1. Текстовые файлы, извлеченные из хранилища, сохранят оригинальные символы EOL в вашем хранилище.рабочее дерево.
    2. Текстовые файлы в рабочем дереве с символами CRLF нормализуются до LF при фиксации обратно в хранилище.
  • core.autocrlf = false
    1. core.eol диктует символы EOL в текстовых файлах вашего рабочего дерева.
    2. core.eol = native по умолчанию, что означает, что Windows EOL равны CRLF, а * nix EOL * LF в рабочих деревьях..
    3. Настройки репозитория gitattributes определяют нормализацию символов EOL для коммитов в репозиторий (по умолчанию нормализация к LF символам).

У меня естьтолько недавно исследовал эту проблему, и я также нахожу ситуацию очень запутанной.Параметр core.eol определенно помог понять, как символы EOL обрабатываются в git.

56 голосов
/ 26 декабря 2012

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

  1. В репо могут быть разные файлы с разными EOL
  2. Некоторые файлы в репо могут иметь смешанную EOL, например, комбинация CRLF и LF в одном файле.

То, как это происходит, здесь не проблема, но это случается.

Я провел несколько тестов конвертации в Windows для различных режимов и их комбинаций.
Вот что я получил в слегка измененной таблице:

                 | Resulting conversion when       | Resulting conversion when 
                 | committing files with various   | checking out FROM repo - 
                 | EOLs INTO repo and              | with mixed files in it and
                 |  core.autocrlf value:           | core.autocrlf value:           
--------------------------------------------------------------------------------
File             | true       | input      | false | true       | input | false
--------------------------------------------------------------------------------
Windows-CRLF     | CRLF -> LF | CRLF -> LF | as-is | as-is      | as-is | as-is
Unix -LF         | as-is      | as-is      | as-is | LF -> CRLF | as-is | as-is
Mac  -CR         | as-is      | as-is      | as-is | as-is      | as-is | as-is
Mixed-CRLF+LF    | as-is      | as-is      | as-is | as-is      | as-is | as-is
Mixed-CRLF+LF+CR | as-is      | as-is      | as-is | as-is      | as-is | as-is

Как видите, есть 2 случая, когда преобразование происходит при фиксации (3 левых столбца). В остальных случаях файлы фиксируются как есть.

При оформлении заказа (3 правых столбца) конверсия происходит только в одном случае:

  1. core.autocrlf - это true и
  2. файл в репо имеет LF EOL.

Самое удивительное для меня, и я подозреваю, что причина многих проблем с EOL заключается в том, что не существует конфигурации, в которой смешанный EOL, такой как CRLF + LF, нормализуется.

Также обратите внимание, что "старые" EOL для Mac CR также никогда не конвертируются.
Это означает, что если плохо написанный сценарий преобразования EOL пытается преобразовать смешанный конечный файл с CRLF s + LF s, просто преобразовав LF s в CRLF s, то он оставит файл в смешанном режиме с "одинокими" CR с, где CRLF был преобразован в CRCRLF.
Git не будет ничего конвертировать, даже в режиме true, и EOL havoc продолжается. Это на самом деле произошло со мной и испортило мои файлы очень сильно, поскольку некоторые редакторы и компиляторы (например, VS2010) не любят Mac EOL.

Полагаю, что единственный способ действительно решить эти проблемы - это иногда нормализовать весь репозиторий, проверяя все файлы в режиме input или false, выполняя надлежащую нормализацию и повторно фиксируя измененные файлы (если есть). В Windows предположительно возобновите работу с core.autocrlf true.

38 голосов
/ 09 июля 2010

Что-то скоро изменится на фронте «eol преобразование», с предстоящим Git 1.7.2 :

Новый параметр конфигурации core.eol добавляется / развивается :

Это замена для коммита 'Add "core.eol" config variable ", который в настоящее время находится в pu (последний в моей серии).
Вместо того, чтобы подразумевать, что "core.autocrlf=true" является заменой для "* text=auto", явно указывает на тот факт, что autocrlf предназначен только для пользователей, которые хотят работать с CRLF в их рабочем каталоге.в репозитории, который не имеет нормализации текстового файла .
Когда он включен, "core.eol" игнорируется.

Введите новую переменную конфигурации "core.eol", котораяпозволяет пользователю указать, какие окончания строк использовать для нормализованных в конце строк файлов в рабочем каталоге.
По умолчанию используется значение "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 , commit df747b8 (10 февраля 2016 г.), commit df747b8 , commit df747b8 (10 февраля 2016 г.),d commit 4b4024f , commit bb211b4 , commit 92cce13 , commit 320d39c , commit 4b4024f , commitbb211b4 , коммит 92cce13 , коммит 320d39c (05 февраля 2016) Торстен Бёгерсхаузен (tboegi) .
(объединено Junio ​​C Hamano - 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 ".

27 голосов
/ 22 декабря 2016
Значение

core.autocrlf не зависит от типа ОС, но для Windows значение по умолчанию равно true, а для Linux - input. Я исследовал 3 возможных значения для случаев фиксации и извлечения, и вот итоговая таблица:

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║     false    ║     input    ║     true     ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║               ║ LF   => LF   ║ LF   => LF   ║ LF   => LF   ║
║ git commit    ║ CR   => CR   ║ CR   => CR   ║ CR   => CR   ║
║               ║ CRLF => CRLF ║ CRLF => LF   ║ CRLF => LF   ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║               ║ LF   => LF   ║ LF   => LF   ║ LF   => CRLF ║
║ git checkout  ║ CR   => CR   ║ CR   => CR   ║ CR   => CR   ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
6 голосов
/ 21 января 2014

Вот мое понимание этого до сих пор, на случай, если это кому-нибудь поможет.

core.autocrlf=true и core.safecrlf = true

У вас есть хранилище , в котором все окончания строкто же самое , но вы работаете на разных платформах.Git позаботится о том, чтобы окончания строк были преобразованы в значения по умолчанию для вашей платформы.Почему это важно?Допустим, вы создаете новый файл.Текстовый редактор на вашей платформе будет использовать окончания строк по умолчанию.Когда вы включаете его, если для core.autocrlf не установлено значение true, вы вводите несоответствие конца строки для кого-то на платформе, которая по умолчанию имеет другое окончание строки.Я тоже всегда устанавливаю safecrlf, потому что хотел бы знать, что операция crlf обратима.С этими двумя настройками git изменяет ваши файлы, но он проверяет, что изменения являются обратимыми .

core.autocrlf=false

У вас есть репозиторий, который ужесмешанные окончания строк проверены и исправление неправильных окончаний строк может привести к поломке.В этом случае лучше не указывать git преобразовывать окончания строк, потому что тогда это усугубит проблему, для решения которой оно было разработано - облегчить чтение различий и объединить менее болезненные.С этим параметром git не изменяет ваши файлы .

core.autocrlf=input

Я не использую это, потому что причина этого состоит в том, чтобы покрыть случай использования, когда вы создали файл с окончаниями строки CRLF на платформе, по умолчанию равной строке LFокончания.Вместо этого я предпочитаю, чтобы мой текстовый редактор всегда сохранял новые файлы со значениями конца строки на платформе.

2 голосов
/ 23 февраля 2017

Сделал несколько тестов как на 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  
1 голос
/ 08 марта 2018

Нет, ответ @jmlane неверен.

Для Checkin (git add, git commit):

  1. Если свойство text равно Set, Set value to 'auto', преобразование происходит, если файл былпередано с помощью CRLF
  2. , если свойство text равно Unset: ничего не происходит, enen для Checkout
  3. , если свойство text равно Unspecified, преобразование зависит от core.autocrlf
    1. , если autocrlf = input or autocrlf = true, преобразование происходит только тогда, когда файл в хранилище имеет значение «LF», если это был «CRLF», ничего не произойдет.
    2. , если autocrlf = false,ничего не происходит

Для Checkout:

  1. если свойство text равно Unset: ничего не происходит.
  2. если text свойство Set, Set value to 'auto: зависит от core.autocrlf, core.eol.
    1. core.autocrlf = ввод: ничего не происходит
    2. core.autocrlf = true: преобразование происходит только в том случае, если файл в хранилище имеет значение «LF», «LF» -> «CRLF»
    3. core.autocrlf = false: преобразование происходит только тогда, когда файл в хранилище имеет значение «LF», «LF» -> core.eol
  3. , если textсвойство Unspecified, зависит от core.autocrlf.
    1. совпадает с 2.1
    2. совпадает с 2.2
    3. Нет, ничего не происходит, core.eol не работает, если свойство text имеет значение Unspecified

Поведение по умолчанию

Поэтому поведение по умолчанию text, свойство Unspecified и core.autocrlf = false:

  1. для проверки ничего не происходит
  2. для проверки ничего не происходит

Выводы

  1. Если установлено свойство text, поведение регистрации зависит от самого себя,не включено в autocrlf
  2. autocrlf или core.eol для поведения извлечения, а autocrlf> core.eol
...