Какова лучшая стратегия обработки CRLF (возврат каретки, перевод строки) с Git? - PullRequest
573 голосов
/ 05 октября 2008

Я попытался зафиксировать файлы с CRLF-оканчивающимися строками, но это не удалось.

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

Пожалуйста, поделитесь только одним передовым опытом для ответа.

Ответы [ 9 ]

712 голосов
/ 01 июня 2012

Почти через четыре года после того, как я задал этот вопрос, я наконец-то нашел ответ, который меня полностью устраивает !

Подробнее см. В github: справка руководство по Работа с окончаниями строки .

Git позволяет вам установить конечные свойства строки для репо, используя текстовый атрибут в .gitattributes файл. Этот файл передан в репо и отменяет настройку core.autocrlf, позволяя вам обеспечить последовательное поведение для всех пользователи независимо от их настроек git.

и, таким образом

Преимущество этого в том, что ваш конец строки Конфигурация теперь путешествует с вашим хранилищем, и вы не нужно беспокоиться о том, соавторы иметь правильные глобальные настройки.

Вот пример .gitattributes file

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

Существует удобная коллекция готовых к использованию .gitattributes файлов для самых популярных языков программирования. Полезно начать.

После того как вы создали или скорректировали .gitattributes, вы должны выполнить однократную повторную нормализацию концов строк .

Обратите внимание, что приложение GitHub Desktop может предложить и создать файл .gitattributes после открытия репозитория Git вашего проекта в приложении. Чтобы попробовать это, щелкните значок шестеренки (в правом верхнем углу)> Настройки репозитория ...> Концы строк и атрибуты. Вам будет предложено добавить рекомендуемые .gitattributes, и если вы согласитесь, приложение также выполнит нормализацию всех файлов в вашем хранилище.

Наконец, статья о конце вашей линии дает больше информации и объясняет, как развивался Git по актуальным вопросам. Я считаю это обязательным чтением .

Возможно, в вашей команде есть пользователи, которые используют EGit или JGit (такие инструменты, как Eclipse и TeamCity, используют их) для фиксации своих изменений. Тогда вам не повезло, как объяснила @gatinueta в комментариях к этому ответу:

Этот параметр не удовлетворит вас полностью, если в вашей команде есть люди, работающие с Egit или JGit, поскольку эти инструменты будут просто игнорировать .gitattributes и успешно проверять файлы CRLF https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372

Один трюк может заключаться в том, чтобы они зафиксировали свои изменения в другом клиенте, скажем, SourceTree . Тогда наша команда предпочитала этот инструмент Eclipse EGit для многих случаев использования.

Кто сказал, что программное обеспечение легко? : - /

112 голосов
/ 05 октября 2008

Не преобразовывать окончания строки. Это не работа VCS, чтобы интерпретировать данные - просто сохраните и версируйте их. В любом случае любой современный текстовый редактор может читать оба вида концов строк.

80 голосов
/ 11 июля 2009

Вы почти всегда хотите autocrlf=input, если вы действительно не знаете, что делаете.

Некоторый дополнительный контекст ниже:

Это должно быть либо core.autocrlf=true, если хотите DOS окончание или core.autocrlf=input, если вы предпочитаете Unix-новая строка. В обоих случаях ваш Git-репозиторий будет есть только LF, который является правильным. Единственный аргументом для core.autocrlf=false был тот автоматический эвристика может некорректно определять некоторые двоичные файлы как текст и тогда ваша плитка будет повреждена. Так, core.safecrlf опция была введена, чтобы предупредить пользователя, если происходит необратимое изменение. На самом деле, есть два возможности необратимых изменений - смешанные конец строки в текстовом файле, в этой нормализации желательно, чтобы это предупреждение можно было игнорировать, или (очень маловероятно), что Git неправильно обнаружил ваш бинарный файл как текст Тогда вам нужно использовать атрибуты для скажите Git, что этот файл является двоичным.

Приведенный выше абзац изначально был извлечен из потока на gmane.org, но с тех пор он отключился.

57 голосов
/ 26 июня 2012

Две альтернативные стратегии для согласования относительно концов строк в смешанных средах (Microsoft + Linux + Mac):

A. Глобальный за все настройки репозитория

1) Конвертировать все в один формат

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) Установите core.autocrlf в input в Linux / UNIX или true в MS Windows (хранилище или глобальное)

git config --global core.autocrlf input

3) [Необязательно] установите core.safecrlf в true (для остановки) или warn (для пения :), чтобы добавить дополнительное ограждение сравнения, если обратное преобразование новой строки приведет к тому же файлу

git config --global core.safecrlf true


B. Или на каждый репозиторий

1) Конвертировать все в один формат

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) добавить файл .gitattributes в свой репозиторий

echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'

Не беспокойтесь о ваших двоичных файлах - Git должен быть достаточно умён с ними.


Подробнее о переменных safecrlf / autocrlf

10 голосов
/ 05 октября 2008

Попробуйте установить для параметра конфигурации core.autocrlf значение true. Также обратите внимание на параметр core.safecrlf.

На самом деле это звучит так, как будто core.safecrlf уже может быть установлено в вашем хранилище, потому что (выделение мое):

Если это не относится к текущим настройкам core.autocrlf, git отклонит файл .

Если это так, то вы можете проверить, что ваш текстовый редактор настроен на последовательное использование концов строк. Скорее всего, у вас возникнут проблемы, если текстовый файл содержит смесь концов строк LF и CRLF.

Наконец, я чувствую, что рекомендация просто «использовать то, что вам дано» и использовать строки с ограничением LF в Windows, вызовет больше проблем, чем решит. У Git есть вышеупомянутые опции, чтобы попытаться обработать окончания строк разумным способом, поэтому имеет смысл использовать их.

9 голосов
/ 16 марта 2011

Использование core.autocrlf=false остановило пометки всех файлов как обновленных, как только я проверил их в своем проекте Visual Studio 2010 . Два других члена команды разработчиков также используют системы Windows, поэтому смешанная среда не вступила в игру, но настройки по умолчанию, поставляемые с хранилищем, всегда отмечали все файлы как обновленные сразу после клонирования.

Полагаю, суть в том, чтобы найти, какой параметр CRLF подходит для вашей среды. Тем более что во многих других репозиториях на наших блоках Linux установка autocrlf = true дает лучшие результаты.

20 + лет спустя, и мы все еще имеем дело с разницей в конце строк между операционными системами ... печально.

7 голосов
/ 15 февраля 2016

Это две опции для Windows и Visual Studio пользователей, которые совместно используют код с Mac или Linux пользователями. Для подробного объяснения прочитайте руководство gitattributes .

* текст = авто

В файл .gitattributes вашего репо добавьте:

*   text=auto

Это нормализует все файлы с LF окончаниями строк в репо.

И в зависимости от вашей операционной системы (настройка core.eol) файлы в рабочем дереве будут нормализованы до LF для систем на базе Unix или CRLF для систем Windows.

Это конфигурация, которую используют Microsoft .NET репозитариев.

Пример: * * тысяча тридцать-один

Hello\r\nWorld

Будет нормализовано в репо всегда как:

Hello\nWorld

При оформлении заказа рабочее дерево в Windows будет преобразовано в:

Hello\r\nWorld

При оформлении заказа рабочее дерево в Mac останется как:

Hello\nWorld

Примечание. Если в вашем репо уже есть файлы, которые не были нормализованы, git status покажет, что эти файлы полностью изменены, когда вы в следующий раз внесете в них какие-либо изменения, и другим пользователям будет неудобно объединять их изменения позже. См. Обновление хранилища после изменения концов строк для получения дополнительной информации.

core.autocrlf = true

Если text не указано в файле .gitattributes, Git использует переменную конфигурации core.autocrlf для определения необходимости преобразования файла.

Для пользователей Windows git config --global core.autocrlf true - отличный вариант, потому что:

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

Проблема с этим подходом заключается в том, что:

  • Если вы пользователь Windows с autocrlf = input, вы увидите набор файлов с LF окончаниями строк. Не представляет опасности для остальной части команды, потому что ваши коммиты все равно будут нормализованы с LF окончаниями строк.
  • Если вы являетесь пользователем Windows с core.autocrlf = false, вы увидите набор файлов с LF окончаниями строк и можете ввести в репозиторий файлы с CRLF окончаниями строк.
  • Большинство пользователей Mac используют autocrlf = input и могут получать файлы с окончаниями файлов CRLF, вероятно, от пользователей Windows с core.autocrlf = false.
4 голосов
/ 21 сентября 2017

Я потратил часы, чтобы придумать наилучшее возможное использование .gitattributes, чтобы наконец понять, что не могу на это рассчитывать.
К сожалению, пока существуют редакторы на основе JGit (которые не могут правильно обрабатывать .gitattributes), безопасным решением является принудительное использование LF везде, даже на уровне редактора.

Используйте следующие anti-CRLF дезинфицирующие средства.

--- ОБНОВЛЕНИЕ 2 ---

В большинстве случаев сбои клиента git будут работать. Даже если у вас есть только клиенты Windows, только клиенты Linux или оба. Это:

  • windows: core.autocrlf=true означает преобразование строк в CRLF при оформлении заказа и преобразование строк в LF при добавлении файлов.
  • linux: core.autocrlf=input означает, что не следует преобразовывать строки при извлечении (нет необходимости, поскольку файлы должны быть зафиксированы с помощью LF) и преобразовывать строки в LF (при необходимости) при добавлении файлов.

Свойство может быть установлено в разных областях. Я бы предложил явно установить в области действия --global, чтобы избежать некоторых проблем IDE, описанных в конце.

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

Также я бы настоятельно не рекомендовал использовать git config --global core.autocrlf false (в случае, если у вас есть клиенты только с Windows) в отличие от того, что предлагается git документация . Установка в false приведет к фиксации файлов с CRLF в репо. Но на самом деле нет причин. Вы никогда не знаете, нужно ли вам делиться проектом с пользователями Linux. Кроме того, это один дополнительный шаг для каждого клиента, который присоединяется к проекту, вместо использования значений по умолчанию.

Теперь для некоторых особых случаев файлов (например, *.bat *.sh), для которых вы хотите, чтобы они были извлечены с помощью LF или CRLF, вы можете использовать .gitattributes

Подводя итог для меня, лучшая практика это:

  • Убедитесь, что каждый недвоичный файл фиксируется с помощью LF в git repo (поведение по умолчанию).
  • Используйте эту команду, чтобы убедиться, что ни один файл не зафиксирован с помощью CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD ( Примечание: на клиентах Windows работает только через git-bash и на клиентах Linux только в том случае, если скомпилировано с использованием --with-libpcre в ./configure).
  • Если вы нашли такие файлы, выполнив приведенную выше команду, исправьте их.
  • Использовать только минимум .gitattributes
  • Поручите пользователям установить для core.autocrlf, описанного выше, его значения по умолчанию.
  • Не рассчитывайте 100% на наличие .gitattributes. git-клиенты IDE могут игнорировать их или обращаться с ними по-разному.

Как уже было сказано, некоторые вещи могут быть добавлены в атрибуты git:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

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

  • -text (например, для файлов *.zip или *.jpg: не будет рассматриваться как текст. Таким образом, преобразование в конце строки не будет предприниматься. Различия могут быть возможны с помощью программ преобразования)
  • text !eol (например, для *.java, *.html: рассматривается как текст, но предпочтение стиля eol не задано. Поэтому используется настройка клиента.)
  • -text -diff -merge (например, для *.hugefile: не обрабатывается как текст. Дифференцирование / объединение невозможно)

--- ПРЕДЫДУЩЕЕ ОБНОВЛЕНИЕ ---

Один болезненный пример клиента, который будет фиксировать файлы неправильно:

netbeans 8.2 (в windows) будет некорректно фиксировать все текстовые файлы с CRLF, если только не имеет явно , устанавливающего core.autocrlf как глобальное . Это противоречит стандартному поведению клиента git и вызывает много проблем позже при обновлении / слиянии. Это то, из-за чего некоторые файлы выглядят по-разному (хотя это не так) даже при возврате .
Такое же поведение в netbeans происходит, даже если вы добавили правильный .gitattributes в свой проект.

Использование следующей команды после фиксации, по крайней мере, поможет вам определить, есть ли у вашего git-репо проблемы с окончанием строки: git grep -I --files-with-matches --perl-regexp '\r' HEAD

4 голосов
/ 20 марта 2013

Это всего лишь решение :

В обычных случаях используйте решения, поставляемые с git. Они прекрасно работают в большинстве случаев. Принудительно использовать LF, если вы делитесь разработкой в ​​системах на базе Windows и Unix, установив .gitattributes .

В моем случае> 10 программистов разрабатывали проект в Windows. Этот проект был проверен с помощью CRLF, и не было возможности принудительно настроить LF.

Некоторые настройки были записаны на моем компьютере без какого-либо влияния на формат LF; таким образом, некоторые файлы глобально менялись на LF при каждом небольшом изменении файла.

Мое решение:

Windows-машины: Пусть все как есть. Ничего не волнует, так как вы являетесь разработчиком окон «одинокий волк» по умолчанию и вам приходится обращаться с этим так: «В широком мире нет другой системы, не так ли?»

Unix-машины

  1. Добавьте следующие строки в раздел конфигурации [alias]. Эта команда выводит список всех измененных (т.е. измененных / новых) файлов:

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
    
  2. Преобразование всех этих измененных файлов в формат dos:

    unix2dos $(git lc)
    
  3. Опционально ...

    1. Создайте git hook для этого действия, чтобы автоматизировать этот процесс

    2. Используйте params, включите его и измените функцию grep, чтобы она соответствовала только определенным именам файлов, например:

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
      
    3. Не стесняйтесь, чтобы сделать его еще более удобным с помощью дополнительного ярлыка:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "
      

      ... и запустите конвертированный материал, набрав

      git c2dos
      
...