Какова лучшая стратегия управления 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):
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
Ответ 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
.
клиенты Windows/Linux: core.autocrlf=input
совершено .gitattributes
: * text=auto eol=lf
совершенный .editorconfig
(http://editorconfig.org/), который является своего рода стандартным форматом в сочетании с плагинами редактора:
--- ОБНОВЛЕНИЕ 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