Можно ли зафиксировать файл, который не соответствует поведению окончания строки, указанному в .gitattributes?

Если в указанный каталог добавляется файл .gitattributes со следующим содержимым:

*.txt    text

Есть ли способ, которым новый файл или ранее нормализованный файл (например, все окончания строк LF) можно было бы зафиксировать в этом каталоге и не нормализовать? То есть, есть ли какой-нибудь способ, чтобы новые окончания строк CRLF могли быть введены в репозиторий после включения .gitattributes с указанным режимом text?

Перефразируя еще раз, является ли этот файл .gitattributes абсолютно надежным способом предотвращения фиксации новых строк CRLF в файлах *.txt в каталоге, содержащем файл .gitattributes? Я хочу убедить своих коллег, что файла .gitattributes вполне достаточно и что дальнейшие меры по исключению CRLF (например, перехватчик на стороне сервера) не нужны.

Ответ должен либо подтвердить, что невозможно переопределить поведение конца строки, заданное .gitattributes, либо предоставить контрпример, объясняющий, как можно обойти файл .gitattributes и проникнуть в некоторые окончания строки CRLF.


person kostmo    schedule 18.06.2013    source источник
comment
Примечание для себя: вот еще один случай попытки не обойти правила gitattributes eol: stackoverflow.com/q/17123998/6309   -  person VonC    schedule 18.06.2013


Ответы (2)


Нелегко через gitattributes, так как отрицательный шаблон запрещен.

На самом деле в эти дни (март 2013 г.) предлагается патч для Сделать !pattern в .gitattributes нефатальным.

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

И зарезервируйте более подробные text правила в .gitattributes каталогах со смешанным содержимым.


kostmo упоминает в комментариях ошибка 421364 EGit:

Пока это не реализовано, я рекомендую эту настройку:

  1. Для каждого проекта Eclipse перейдите к Properties > Resource и измените «New text file line delimiter» на Other: Unix. Зафиксируйте получившиеся .settings/org.eclipse.core.runtime.prefs файлов.
  2. Не настраивайте никаких .gitattributes или "core.autocrlf" для Git.
    Это означает, что файлы будут иметь те же окончания строк в рабочем каталоге, что и в репозитории. Git и EGit не будут преобразовывать содержимое файлов.

С 1. все новые файлы, созданные в Eclipse, будут иметь правильное (LF) окончание строки, даже если они созданы пользователем в Windows.

Для файлов, которые уже есть в вашем репозитории с CRLF, вы можете исправить их и зафиксировать результат. Я рекомендую использовать dos2unix или fromdos в командной строке.

Примечание: эта проблема (ошибка 421364) была обнаружена только что (25 марта) , 2014) был переквалифицирован как дубликат ошибки 342372 пользователем Ларс Фогель.

Итак, поддержка .gitattributes в JGit "назначена", но ее реализация все еще продолжается.

Реализация пересматривается (январь 2015 г.):

  • "отзыв 1614" Добавить базовую поддержку .gitattributes

Основные классы для разбора и обработки .gitattributes файлов, включая поддержку чтения атрибутов в WorkTreeIterator и dirCacheIterator.

  • "review 35377" Добавляет вычисление атрибутов git в обход дерева

Добавляет функцию getAttributes в обход дерева.
Вычисление атрибутов должно выполняться TreeWalk, так как ему нужны как WorkingTreeIterator, так и DirCacheIterator.


Обновление за август 2018 г.: упомянутая выше ошибка (ошибка 342372) зависит от ошибка JGit 537410, которая только что была устранена.
"< strong>JGit rebase и stash не сохраняют окончание строки"

Проблема в том, что ResolveMerger во время processEntry() не запоминает CheckoutMetadata (в котором JGit хранит фильтры и атрибуты eol) для файлов, а затем проверяет их в checkout(), игнорируя любые атрибуты или фильтры.

У ResolveMerger.cleanUp() та же проблема.

Коммит JGit 4027c5c (из отзыв 127290) должен это исправить.
Спасибо Томасу Вольфу активный участник JGit.

Это дает надежду на EGit:

EGit, как правило, оставляет JGit всю эту обработку eol при подготовке/объединении/проверке.
Единственные места, где EGit должен заботиться об этом, — это фреймворк сравнения, когда он сам должен читать записи индекса, и там он уже правильно обрабатывает CheckoutMetadata.

person VonC    schedule 18.06.2013
comment
Итак, перефразируя мой вопрос, является ли приведенный выше файл .gitattributes абсолютно надежным способом предотвращения фиксации новых строк CRLF в файлах *.txt в каталоге, содержащем файл .gitattributes? Я хочу убедить своих коллег, что файла .gitattributes достаточно и что дальнейшие меры по исключению CRLF (например, перехватчик на стороне сервера) не нужны. - person kostmo; 18.06.2013
comment
@kostmo да, пока вы сохраняете конфигурацию с core.autocrlf по false (stackoverflow.com/a/2016763/6309): вы можно определить правила eol в .gitattributes: см. stackoverflow.com/a/12702862/6309 - person VonC; 18.06.2013
comment
Вы хотите сказать, что если бы core.autocrlf было true, пользователь мог бы создать фиксацию, которая не соответствует настройке .gitattributes? - person kostmo; 18.06.2013
comment
Нет: правила gitattributes имеют приоритет над глобальной конфигурацией, такой как core.autocrlf: см. git-scm.com/docs/ gitattributes: переменная конфигурации core.eol определяет, какие окончания строк Git будет использовать для нормализованных файлов в вашем рабочем каталоге; по умолчанию используется родное окончание строки для вашей платформы или CRLF, если установлено core.autocrlf. ... Если атрибут text не указан, Git использует переменную конфигурации core.autocrlf, чтобы определить, следует ли преобразовать файл. - person VonC; 18.06.2013
comment
Каким-то образом некоторые CRLF попали в наш репозиторий через некоторое время после того, как файлы-нарушители были установлены в текстовом формате в файле .gitattributes и нормализованы окончания строк во всех этих файлах. Я подозреваю, что JGit/EGit (встроенный Git-клиент Eclipse) не соблюдает те же правила, что и родной Git-клиент командной строки. Поскольку принудительное выполнение осуществляется только на стороне клиента, кажется, что в конце концов можно обойти .gitattributes нормализацию. - person kostmo; 24.12.2013
comment
Вот ошибка EGit, направленная на поддержку окончания .gitattributes строки. - person kostmo; 28.12.2013
comment
@kostmo интересно, спасибо. Я включил эту ссылку в ответ для большей наглядности. - person VonC; 28.12.2013

Перефразируя еще раз, является ли этот файл .gitattributes абсолютно надежным способом

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

Я хочу убедить своих коллег, что файла .gitattributes вполне достаточно и что дальнейшие меры по исключению CRLF (например, хук на стороне сервера) не нужны.

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

git update-index --cacheinfo \
        100644,`git hash-object -w --no-filters path/to/file`,path/to/file

Из документов git hash-object

--no-filters
Хешируйте содержимое как есть, игнорируя любой входной фильтр, который был бы выбран механизмом атрибутов, включая преобразование конца строки. Если файл читается со стандартного ввода, это всегда подразумевается, если только не указана опция --path.

person jthill    schedule 09.01.2015