Какова лучшая стратегия управления CRLF (возврат каретки, линия) с помощью Git?

Я пробовал делать файлы с CRLF-концами, но это не удалось.

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

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

Ответ 1

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

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

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

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

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

Вот пример файла .gitattributes

# 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 repo в приложение. Чтобы попробовать это, щелкните значок шестеренки (в верхнем правом углу) > Настройки репозитория... > Окончания и атрибуты линий. Вам будет предложено добавить рекомендуемый .gitattributes, и, если вы согласитесь, приложение также выполнит нормализацию всех файлов в вашем репозитории.

Наконец, Mind the End of Your Line. дает больше информации и объясняет, как развился git по имеющимся вопросам. Я считаю это необходимым для чтения.

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

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

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

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

Ответ 2

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

Ответ 3

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

Следующий дополнительный контекст ниже:

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

Вышеупомянутый параграф был первоначально вытащен из потока на gmane.org, но с тех пор он спустился.

Ответ 4

Две альтернативные стратегии для согласования о концах строк в смешанных средах (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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

20+ лет спустя, и мы по-прежнему имеем дело с линейным несоответствием между OSes... sad.

Ответ 7

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

* text = авто

В вашем файле repo .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.

Ответ 8

Я потратил часы, чтобы придумать наилучшее возможное использование .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).
  • Если вы нашли такие файлы, выполнив приведенную выше команду, исправьте их. Это включает в себя (по крайней мере, в Linux):
    • изменить файл
    • отменить изменение (файл все еще отображается как измененный)
    • совершить это
  • Используйте только минимум .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

Ответ 9

Это решение обходного пути:

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

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

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

Мое решение:

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

Unix-машины

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

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

    unix2dos $(git lc)
    
  • Необязательно...

    • Создайте git hook для этого действия для автоматизации этого процесса

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

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

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

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

      git c2dos