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

StackOverflow https://stackoverflow.com/questions/170961

Вопрос

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

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

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

Это было полезно?

Решение

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

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

  

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

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

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

  

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

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

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

Другие советы

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

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

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

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

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

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

А.Глобальный за настройку всех репозиториев

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


Б.Или за настройку репозитория

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

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

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

  

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

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

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

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

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

Спустя 20 с лишним лет, и мы до сих пор имеем дело с разницей в конце строк между ОС ... sad.

Это два варианта Окна и Визуальная Студия пользователи, которые делятся кодом с Мак или Линукс пользователи.Для более подробного объяснения прочтите руководство по gitattributes.

* текст = авто

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

*   text=auto

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

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

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

Пример:

Hello\r\nWorld

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

Hello\nWorld

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

Hello\r\nWorld

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

Hello\nWorld

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

core.autocrlf = правда

Если 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.

Это всего лишь обходной путь решение:

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

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

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

Мое решение:

Windows-машины:Пусть все как есть.Не беспокойтесь ни о чем, поскольку вы являетесь разработчиком 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 крюк для этого действия, чтобы автоматизировать этот процесс

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

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

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

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

      git c2dos
      

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top