Как конверсии завершения строк работают с git core.autocrlf между различными операционными системами

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

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

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

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

Вот матрица, которая пытается документировать то же самое для "ввода" и "ложных" настроек core.autocrlf с вопросительными знаками, где я не уверен в поведении преобразования конца строки.

Мои вопросы:

  • Какими должны быть вопросительные знаки?
  • Является ли эта матрица правильной для "знаков без вопроса"?

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

                       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 в комментариях, Я изменил некоторые значения в "неизвестных" значениях в приведенной выше таблице, а также изменил "checkout existing | 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 = input

Это означает, что git обработает все текстовые файлы и убедитесь, что CRLF заменяется LF при записи этого файла на объект база данных. Однако он не будет делать обратного. Когда вы читаете файлы вернуться из базы данных объектов и записать их в рабочий в каталоге они все равно будут иметь LF, чтобы обозначить конец строки. Эта обычно используется в Unix/Linux/OS X, чтобы предотвратить CRLF от записывается в репозиторий. Идея состоит в том, что если вы вставили код из веб-браузера и случайно получил CRLF в один из ваших файлы, git, убедитесь, что они были заменены LF, когда вы написали к базе данных объектов.

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

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

Ответы

Ответ 1

Лучшее объяснение того, как работает core.autocrlf, находится на gitattributes man страницы, в разделе атрибута 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 EOL CRLF и * nix EOL являются LF в рабочих деревьях.
    • Настройки репозитория gitattributes определяют нормализацию символа EOL для фиксации в репозитории (по умолчанию нормализуется символ LF).

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

Ответ 2

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

  • В репо могут быть разные файлы с разными EOL
  • Некоторые файлы в репо могут иметь смешанный 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 правых столбца) существует только один случай, когда преобразование происходит, когда:

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

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

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

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

Ответ 3

Все изменится на фронте преобразования "eol", с предстоящий Git 1.7.2:

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

Это замена для "Добавить" core.eol "config variable" commit, который в настоящее время находится в 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:

См. commit 817a0c7 (23 февраля 2016 г.), commit 6e336a5, commit df747b8, commit df747b8 (10 февраля 2016 г.), commit df747b8, commit df747b8 (10 февраля 2016 г.) и commit 4b4024f, commit bb211b4, commit 92cce13, зафиксировать 320d39c, commit 4b4024f, commit bb211b4, commit 92cce13, зафиксировать 320d39c (05 февраля 2016 г.) Torsten Bögershausen (tboegi).
(слияние Юнио С Хамано - gitster - в commit c6b94eb, 26 февраля 2016 г.)

convert.c: refactor 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.

Ответ 4

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

core.autocrlf=true и core.safecrlf = true

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

core.autocrlf=false

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

core.autocrlf=input

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

Ответ 5

Значение

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

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║     false    ║     input    ║     true     ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║   git commit  ║ LF => LF     ║ LF => LF     ║ LF => CRLF   ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => LF   ║ CRLF => CRLF ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║  git checkout ║ LF => LF     ║ LF => LF     ║ LF => CRLF   ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝

Ответ 6

Проделали некоторые тесты как на Linux, так и на окнах. Я использую тестовый файл, содержащий строки, заканчивающиеся на 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