Force LF eol в git-репо и рабочей копии - PullRequest
146 голосов
/ 02 апреля 2012

У меня есть git-репозиторий, размещенный на github.Многие из файлов были изначально разработаны для Windows, и я не слишком заботился об окончании строк.Когда я выполнил начальную фиксацию, у меня также не было никакой конфигурации git для обеспечения правильного окончания строк.В результате у меня есть несколько файлов с окончаниями строк CRLF в моем репозитории github.

Сейчас я частично занимаюсь разработкой для Linux, и я хотел бы очистить окончания строк.Как я могу убедиться, что файлы правильно хранятся с помощью LF на github и имеют LF в моей рабочей копии?

Я настроил .gitattributes файл, содержащий text eol=LF;это верно?С этим совершенным и выдвинутым, могу ли я просто rm мой локальный репо и повторно клонировать из github, чтобы получить желаемый эффект?

Ответы [ 3 ]

204 голосов
/ 02 апреля 2012

Без небольшого количества информации о том, какие файлы находятся в вашем хранилище (чистый исходный код, изображения, исполняемые файлы, ...), довольно сложно ответить на вопрос:)

Кроме того, я буду считать, что вы по умолчанию хотите использовать LF в качестве окончания строк в вашем рабочем каталоге, потому что вы хотите убедиться, что текстовые файлы имеют окончания LF в вашем .git-хранилище, где бы вы ни работали Windows или Linux. Действительно лучше, чем потом сожалеть ....

Тем не менее, есть лучшая альтернатива: используйте концы строк LF в вашем рабочем каталоге Linux, окончания строк CRLF в вашем рабочем каталоге Windows и окончания строк LF в вашем хранилище.

Поскольку вы частично работаете в Linux и Windows, убедитесь, что для core.eol установлено значение native, а для core.autocrlf установлено значение true.

Затем замените содержимое вашего .gitattributes файла следующим

* text=auto

Это позволит Git обрабатывать автоматическое преобразование концов строк для вас при фиксации и проверке. Двоичные файлы не будут изменены, файлы, определенные как текстовые, будут видеть окончание строк, преобразованное на лету.

Однако, поскольку вы знаете содержимое своего хранилища, вы можете помочь Git и помочь ему обнаружить текстовые файлы из двоичных файлов.

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

* text=auto
*.txt text
*.c text
*.h text
*.jpg binary

Это гарантирует, что файлы с расширением c, h или txt будут храниться с LF-окончаниями в вашем репо и будут иметь собственные окончания в рабочем каталоге. Файлы JPEG не будут затронуты. Все остальные получат выгоду от той же автоматической фильтрации, как показано выше.

Чтобы получить более глубокое понимание внутренних деталей всего этого, я бы посоветовал вам погрузиться в этот очень хороший пост "Помните конец своей строки" от Тима Клема, Githubber.

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

ОБНОВЛЕНИЕ к ответу с учетом следующего комментария

Я фактически не хочу CRLF в моих каталогах Windows, потому что моя среда Linux на самом деле представляет собой VirtualBox, совместно использующий каталог Windows

Имеет смысл. Спасибо за разъяснения. В этом конкретном контексте самого файла .gitattributes будет недостаточно.

Запустите следующие команды для вашего хранилища

$ git config core.eol lf
$ git config core.autocrlf input

Поскольку ваш репозиторий является общим для вашей среды Linux и Windows, это обновит локальный конфигурационный файл для обеих сред. core.eol гарантирует, что текстовые файлы будут иметь LF-окончания строк при оформлении заказа. core.autocrlf обеспечит потенциал CRLF в текстовых файлах (например, в результате операции копирования / вставки) будет преобразован в LF в вашем хранилище.

При желании вы можете помочь Git определить, что является текстовым файлом, создав файл .gitattributes, содержащий нечто похожее на следующее:

# Autodetect text files
* text=auto

# ...Unless the name matches the following
# overriding patterns

# Definitively text files 
*.txt text
*.c text
*.h text

# Ensure those won't be messed up with
*.jpg binary
*.data binary

Если вы решили создать файл .gitattributes, передайте его .

Наконец, убедитесь, что git status упоминает "ничего не фиксировать (очистка рабочего каталога)" , затем выполните следующую операцию

$ git checkout-index --force --all

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

Как только это будет сделано, каждый текстовый файл в вашем рабочем каталоге будет иметь LF-окончания, и git status все равно будет считать рабочий каталог чистым.

86 голосов
/ 09 февраля 2017

Начиная с git 2.10, нет необходимости перечислять каждый текстовый файл отдельно.Git 2.10 исправил поведение text = auto вместе с eol = lf . Источник .

.gitattributes файл в корне вашего git-репозитория:

* text=auto eol=lf

Добавить и зафиксировать его.

После этого вы можетевыполните следующие шаги и все файлы теперь нормализованы:

git rm --cached -r .  # Remove every file from git's index.
git reset --hard      # Rewrite git's index to pick up all the new line endings.

Источник: Ответ от kenorb .

22 голосов
/ 15 января 2016

Чтобы принудительно завершить LF-строки для всех текстовых файлов, вы можете создать файл .gitattributes на верхнем уровне вашего хранилища со следующими строками (измените по желанию):

# Ensure all C and PHP files use LF.
*.c         eol=lf
*.php       eol=lf

, который гарантирует, что все файлы, которые Git считает текстовыми, имеют нормализованные (LF) окончания строк в репозитории (обычно core.eol контролирует конфигурацию, какой у вас есть по умолчанию).

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

$ echo "* text=auto" >> .gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

или согласно GitHub docs :

git add . -u
git commit -m "Saving files before refreshing line endings"
git rm --cached -r . # Remove every file from Git's index.
git reset --hard # Rewrite the Git index to pick up all the new line endings.
git add . # Add all your changed files back, and prepare them for a commit.
git commit -m "Normalize all the line endings" # Commit the changes to your repository.

См. Также: @ Пост Чарльза Бейли .

Кроме того, если вы хотите исключить какие-либо файлы, которые не рассматриваются как текст, отмените их атрибут текста, например,

manual.pdf      -text

Или явно пометить его как двоичный:

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

Чтобы увидеть более продвинутый файл нормализации git, отметьте .gitattributes в Drupal core :

# Drupal git normalization
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see https://www.drupal.org/node/1542048

# Normally these settings would be done with macro attributes for improved
# readability and easier maintenance. However macros can only be defined at the
# repository root directory. Drupal avoids making any assumptions about where it
# is installed.

# Define text file attributes.
# - Treat them as text.
# - Ensure no CRLF line-endings, neither on checkout nor on checkin.
# - Detect whitespace errors.
#   - Exposed by default in `git diff --color` on the CLI.
#   - Validate with `git diff --check`.
#   - Deny applying with `git apply --whitespace=error-all`.
#   - Fix automatically with `git apply --whitespace=fix`.

*.config  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.css     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.dist    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.engine  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.html    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html
*.inc     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.js      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.json    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.lock    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.module  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.php     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.po      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.script  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.sh      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.sql     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.svg     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.theme   text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.twig    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.txt     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.xml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.yml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

# Define binary file attributes.
# - Do not treat them as text.
# - Include binary diff in patches instead of "binary files differ."
*.eot     -text diff
*.exe     -text diff
*.gif     -text diff
*.gz      -text diff
*.ico     -text diff
*.jpeg    -text diff
*.jpg     -text diff
*.otf     -text diff
*.phar    -text diff
*.png     -text diff
*.svgz    -text diff
*.ttf     -text diff
*.woff    -text diff
*.woff2   -text diff

Смотри также:

...