Какое правило git использует из .gitattributes для определения типа файла и окончания строки? - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь отследить, какое правило используется для файлов в моем репо, когда у меня есть файл .gitattributes. Есть ли команда git, которая сообщает вам, каков тип файла (текст против двоичного кода) и конец строки?

Чтобы понять, о чем я спрашиваю, рассмотрите следующее (усечено) .gitattributes file:

*.bat text eol=crlf
*.dll binary
*.exe binary

WinBin/* text eol=crlf
scripts/* text eol=lf

Как следует обрабатывать следующие файлы и какое правило следует использовать? Ниже приведены мои предположения

test1.bat => Should match *.bat text eol=crlf
WinBin\test1.bat => Should match WinBin/* text eol=crlf
WinBin\test2.exe=> Should match WinBin/* text eol=crlf (but I'd rather it were binary)
scripts\test1.bat => Should match scripts/* text eol=lf

Существует множество ресурсов, описывающих работу конца строки в git и различные проблемы. Ниже приведены некоторые найденные мной

Несколько полезных ссылок

Моя конфигурация

Я нахожусь windows с использованием Git для Windows (GfW) и я использовал git с git bash.exe, а также с Windows cmd.exe; У меня также есть cygwin git.

GitForWindows: git --version => git version 2.26.0.windows.1 (latest)
Cygwin Git: git --version => git version 2.8.3 (pretty out of date)

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Технически, что происходит, так это то, что обработчику атрибутов присваивается имя файла и список правил из всех различных файлов .gitattributes (их может быть больше одного). Для каждого имени файла:

  • Имя подразумевает некоторый каталог, например, когда имя scripts/foo, 1 , файл находится в каталоге scripts, поэтому файл атрибутов из этого каталога (scripts/.gitattributes) имеет приоритет, а .gitattributes из каталога src/ (src/.gitattributes) вообще не применяется.

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

  • Git повторяет этот процесс для всех применимых файлов атрибутов. Так как те, которые имеют более высокий приоритет, применяются , позже , их строки переопределяются. Последние строки таких файлов переопределяют более ранние строки.

В этом случае у вас было две применимые строки в одном файле .gitattributes, которые будут применяться к scripts/test1.bat. Таким образом, для этого файла:

*.bat text eol=crlf
scripts/* text eol=lf

первая строка соответствует и устанавливает eol=crlf, затем более поздняя строка соответствует и устанавливает text и устанавливает eol=lf.

В результате получается, что окончательная группировка атрибутов для этого конкретного файла: text (набор), eol=lf.

Вы не пробовали это в качестве примера, но предположим, что у вас есть файл с именем scripts/a.exe. Есть строка:

*.exe binary

вместе со строкой:

scripts/* text eol=lf

, поэтому комбинация здесь выглядит как binary (установлено), text (установлено) и eol=lf. Однако binary сам по себе является макросом . Вы можете определить свои собственные макросы (хотя только в некоторых файлах атрибутов). В этом случае макрос расширяется до -diff -merge -text.

Каждый - означает unset . Таким образом, наряду с отменой сброса diff и merge, первая соответствующая строка выполняла операцию unset text. Вторая строка соответствия, scripts/*, выполнила операцию set text, которая отменила предыдущую операцию unset text. Конечным результатом является то, что для этого файла установлено text, diff не установлено, merge не установлено и eol установлено в lf.

Обратите внимание, что unset отличается от не указано . Атрибут unspecified foo означает, что ни в одной строке явно не было -foo или foo или foo=value. 2 За исключением предопределенных макросов и имен атрибутов, вызванных в документации имена атрибутов на самом деле не зафиксированы: в будущих версиях Git могут быть добавлены новые, и вы можете устанавливать или отменять или задавать имена атрибутов, которые вы создаете сами, и Git ничего не скажу о них. Запись:

* foo=bar

не имеет никакого эффекта, потому что ничего внутри Git в настоящее время не ищет атрибута foo, но если будущее Git решит использовать foo для обозначения чего-либо, оно может внезапно начаться делать вещи.

Довольно сложно справиться со всем этим, поэтому существует git check-attr. См. phd's answer .


1 Git превращает все обратные косые черты в внутренние. Возможно, вы захотите отдать предпочтение форварду sla sh, потому что, например, \b означает backspace для некоторых команд оболочки; \t означает tab , \r означает возврат каретки и так далее. Если вы используете sh или bash, оболочка будет делать с ними свое дело, поэтому зарезервируйте их для оболочки. Не используйте их в именах путей. Используйте косую черту - в любом случае проще набирать!

2 Если в какой-то предыдущей строке был задан, не задан или задан некоторый атрибут некоторый атрибут foo, a позже строка может отменить это с !foo. Это удаляет все настройки и возвращает foo обратно в неопределенное состояние . Это полностью отличается от -foo, который переводит foo в состояние unset .

(Не каждый атрибут, имеющий значение, фактически использует все эти различия.)

2 голосов
/ 09 апреля 2020

git check-attr - Показать информацию о gitattributes.

Для каждого пути эта команда выведет список, если каждый атрибут не указан, установлен или не установлен как атрибут gitat для этого пути .

Возможно, вам нужна опция -a:

git check-attr -a test1.bat WinBin\test1.bat WinBin\test2.bat scripts\test1.bat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...