Чому я повинен використовувати core.autocrlf = true у Git?


295

У мене є сховище Git, до якого можна отримати доступ як з Windows, так і з ОС X, і я знаю, що він містить деякі файли із закінченнями рядків CRLF. Наскільки я можу сказати, з цим вирішити два способи:

  1. Набір core.autocrlfдля falseвсюди,

  2. Виконайте тут інструкції (наголошуються на довідкових сторінках GitHub), щоб конвертувати сховище, щоб він містив лише закінчення рядків LF, а потім встановлено core.autocrlfв trueWindows та inputOS X. Проблема з цим полягає в тому, що якщо у мене є будь-які бінарні файли у сховищі що:

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

    вони будуть зіпсовані. Можливо, моє сховище містить такі файли.

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

Репозиторій є внутрішнім для моєї компанії, і тому мені не потрібно переживати, щоб ділитися ним з людьми з різними налаштуваннями автопосилання або вимогами до закінчення рядків.

Чи є якісь інші проблеми з тим, щоб просто залишити закінчення рядків як - це я не знаю?


1
Чи допоможе stackoverflow.com/questions/2333424/… ? Я маю посилання на конкретні причини відмови autocrlfвід помилки.
VonC

3
@VonC Дякую, але я вже в змозі продиктувати, що всі користувачі компанії встановлюють <code> autocrlf </code> на false, і в даний час вважають, що це найкращий варіант. Але я хочу знати, чи є якісь причини, чому я не повинен цього робити, тому що я можу знайти багато людей (наприклад, GitHub), які кажуть, що слід встановити autocrlf , але немає конкретної конкретики того, чому.
Багатий

3
@VonC, тобто я не шукаю причин встановити autocrlfзначення false. Я шукаю причини, щоб встановити це як істинне.
Багатий

9
Чому б не використати autocrlf = input: це, здається, є ідеальним дозволом між двома крайнощами: ви зберігаєте репо в чистоті від лайнів CRLF, і локально розробники Windows можуть використовувати все, що завгодно, без того, щоб їх локальні файли автоматично зробили щось магічне. (Вони можуть захотіти на місцевому рівні з різних причин, тому 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 " "


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. Моя рішуча рекомендація - встановити закінчення рядків на істинні. І робіть це якомога раніше, протягом життя вашого сховища.

Коли це було сказано, Я НЕЮ Я, що Git змінює мої закінчення рядка. Елемент керування джерелом повинен зберігати та відновлювати роботу, яку я виконую, він НЕ повинен змінювати її. Колись. Але це робить.

Що станеться, якщо у вас не буде встановлено значення кожного істинного розробника, якщо ОДИН розробник врешті-решт встановить значення true. Це почне змінювати закінчення рядків усіх ваших файлів на LF у вашому репо. І коли користувачі встановлять помилкові перевірки, випуск Visual Studio попередить вас і попросить змінити їх. У вас буде 2 речі, які відбудуться дуже швидко. По-перше, ви отримаєте все більше і більше цих попереджень, чим більше буде ваша команда, тим більше ви отримаєте. Друга, і гірша річ, що це покаже, що кожен рядок кожного зміненого файлу був змінений (адже закінчення рядків кожного рядка буде змінено справжнім хлопцем). Зрештою, ви більше не зможете надійно відслідковувати зміни у вашому репо. Набагато простіше і чіткіше зробити так, щоб всі трималися правдивими, ніж намагатися не допустити до помилок. Настільки жахливо, як жити з тим фактом, що ваш контрольований джерело контролю робить щось, чого не повинен. Колись.


Моя компанія є достатньо малою, що ми можемо з легкістю призначити, що помилка використовується скрізь, і я б подумав, що більші компанії можуть це зробити за допомогою політики, але я думаю, що це є законною причиною використання "справжнього", тому я підтримую заяву все одно. Дякую!
Багатий

1
Проблема, пов’язана з цим політикою (примусовий файл), полягає в тому, що на машині Windows ви можете мати локальний, глобальний та прихований конфігураційний файл (ProgramData / Git / Confg). Ви можете примусово застосувати локальний, перевіривши його в репо-репортаж, але глобальні та приховані файли мають перевагу. Також можливо, щоб локальні та глобальні (або приховані) були різними. Якщо вони є, вони будуть конфліктувати один з одним на машині SAME, викликаючи помилки закінчення рядка там, де їх немає. Це біль відстежити. :(
JGTaylor

7
саме те, що я думаю. це не робота управління джерелом возитися з кодовими файлами, як заманеться. закінчення рядків повинні бути просто питаннями інструментів редагування, не більше того.
Tuncay Göncüoğlu

6
Якщо ваш проект призначений лише для Windows, тоді проблем немає. Однак якщо ви або ваші колеги працюєте на платформі * nix, тоді ваша «настійна рекомендація» спричинить проблеми. Спробуйте запустити скрипт bash, perl або python із закінченням shebang, \r\nі ви побачите.
phuclv

6
Ситуація, яку ви описали як не проблема GIT, встановіть для параметра FALSE так, як зазвичай це має бути, і його немає. Встановити, це проблема в командній роботі. Що означає "зрештою один розробник встановлює true"? Чому б ви дозволили їм це в першу чергу? коли ви налаштовуєте їх для доступу до git repo, то так само, як ви не дозволяєте забруднювати певні ділянки різними лангами (тому кожен, хто працює над цим, може читати його), або так само, як ви зберігаєте гілки / злиття / повторні бази / тощо вздовж обраних політики, вони повинні отримати чітке правило: встановити правильний crlf.
quetzalcoatl

12

Оновлення 2 :

Здається, що в Xcode 9 є "особливість", коли він буде ігнорувати поточні закінчення файлу файлу, а замість цього просто використовувати налаштування для закінчення рядка за замовчуванням під час вставлення рядків у файл, в результаті чого утворюються файли зі змішаними закінченнями рядків.

Я майже впевнений, що ця помилка не існувала в Xcode 7; не впевнений у Xcode 8. Хороша новина полягає в тому, що він, мабуть, фіксований у Xcode 10.

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

Оновлення :

Примітка: Як було відзначено 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
Примітка. Коли Visual Studio стикається з таким файлом, він пропонує нормалізувати закінчення рядків для вас. Вибір або закінчення рядків Windows або вибору не нормалізувати закінчення рядків працює добре (оскільки VS все ще відображає його правильно, лінії-порушники будуть видалені після вирішення конфлікту).
Багатий

2
На жаль, управління корпоративними версіями нацисти не погоджуються з цим (НЧ щодо маркерів конфлікту злиття) не є проблемою.
Ілля Г

1
Я погоджуюся, що ПН щодо маркерів конфлікту злиття не повинно бути проблемою. Ці лінії ні в якому разі не повинні бути передані репо.
пограбувати

1
Примітка: починаючи з git 2.8 (березень 2016 року), маркери злиття насправді закінчуються рядком CRLF. Див stackoverflow.com/a/35474954/6309
VonC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.