Сила LF eol в репозитории git и рабочая копия
У меня есть репозиторий git, размещенный в github. Многие из файлов были первоначально разработаны в Windows, и я не слишком осторожно относился к окончанию строк. Когда я выполнил начальную фиксацию, у меня также не было никакой конфигурации git, чтобы обеспечить правильные окончания строк. Результатом является то, что у меня есть несколько файлов с концами строк CRLF в моем репозитории github.
Сейчас я частично разрабатываю Linux, и я бы хотел очистить концы строк. Как я могу гарантировать, что файлы правильно сохранены с LF на github и имеют LF в моей рабочей копии?
Я установил файл .gitattributes
, содержащий text eol=LF
; это верно? С помощью этого совершенного и нажатого я могу просто rm
локальное репо и повторное клонирование из github, чтобы получить желаемый эффект?
Ответы
Ответ 1
Без небольшой информации о том, какие файлы находятся в вашем репозитории (чистый исходный код, изображения, исполняемые файлы,...), немного сложно ответить на вопрос:)
Кроме того, я буду считать, что вы готовы по умолчанию использовать LF в качестве окончаний строки в вашем рабочем каталоге, потому что вы готовы убедиться, что текстовые файлы имеют окончания строки LF в вашем репозитории .git, если вы работаете Windows или Linux. Действительно лучше безопасно, чем жаль....
Тем не менее, есть лучшая альтернатива: Воспользуйтесь концами строк LF в вашем рабочем столе Linux, окончаниями строк CRLF в конце концов Windows Workdir и 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
должен по-прежнему считать рабочий диск чистым.
Ответ 2
Чтобы заставить конец строки 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:
git add . -u
git commit -m "Saving files before refreshing line endings"
git rm --cached -r . # Remove every file from Git 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.
См. также: @Charles Bailey post.
Кроме того, если вы хотите исключить любые файлы, которые не обрабатываются как текст, отключите их текстовый атрибут, например.
manual.pdf -text
Или пометить его явно как двоичный:
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
Чтобы увидеть более продвинутый файл нормализации Git, отметьте .gitattributes
в Ядро Drupal:
# 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
См. также:
Ответ 3
Начиная с 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 index.
git reset --hard # Rewrite git index to pick up all the new line endings.
Источник: Ответа на этот вопрос kenorb.