Изменить конфигурацию git в конце строки

Итак, сейчас я работаю над проектом с другим колледжем, и он использует Mac, а я использую Windows, поэтому у нас проблемы с EOL (конец строки) наших файлов. Мы решили, что хотим, чтобы все файлы были LF. Для него это не проблема, потому что он использует Mac, но я должен изменить все свои файлы с CRLF на LF, что я уже сделал, также я установил конфиг, чтобы каждый раз, когда я добавляю новый файл, он запускался как LF. Проблема в том, что когда я хочу зафиксировать изменения в нашем репо, мне выдается это предупреждение.

The file will have its original line endings in your working directory warning: LF will be replaced by 
CRLF in tsconfig.build.json.

Чего я хочу добиться? Я хочу отключить эту «автоматическую» замену на github. Я не хочу, чтобы мои файлы были заменены на CRLF, я хочу, чтобы все мои файлы всегда были LF. Какие-либо предложения?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 869
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала несколько важных замечаний по терминологии: GitHub никогда ничего не заменяет. Они буквально не могут. Не беспокойтесь о GitHub здесь; они не имеют значения. Не беспокойтесь о своем собственном Git, который, если не считать того, что он начинается с тех же трех букв, имеет очень мало общего с GitHub. GitHub — это хостинг-провайдер, где вы можете хранить и получать доступ к репозиториям Git. Git — это программное обеспечение, реализующее систему контроля версий.

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

я хочу, чтобы все мои файлы всегда были LF.

Вы упомянули код Visual Studio, у которого также может быть свой метод работы с вашими файлами. Вы можете изучить это и настроить, если это соответствует вашим целям. Этот ответ касается только самого Git.

Что поставить .gitattributes

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

<pattern> text eol=lf

Часть pattern здесь может включать такие вещи, как *.json или *.sh, или даже просто * (что соответствует всем именам файлов).

Если у вас нет файла .gitattributes, просто создайте его. Убедитесь, что он содержит обычный текст, желательно простой ASCII или UTF-8 без маркеров порядка следования байтов.

Что означает эта строка * text eol=lf

Как отмечалось выше, первая часть — это шаблон: это набор файлов, к которым применяется остальная часть строки. Вы можете перечислить более одного шаблона или один и тот же шаблон более одного раза, включив несколько строк. Последний совпадающий шаблон обычно переопределяет предыдущие.1

Часть text сообщает Git, что этот файл является текстовым, то есть редактируемым материалом, состоящим из строк, в отличие от двоичных файлов, которые Git не может предположить, что они содержат текст. Это включает преобразование конца строки в файле.2

eol=lf сообщает Git, как должны выглядеть концы строк. lf здесь означает использование окончаний перевода строки, в отличие от окончаний строк CRLF, которые часто предпочитают или требуют программы Windows.

Другое значение, которое вы можете установить для eol, это eol=crlf, но, учитывая ваше заявление выше, вам это не нужно.


1Вот так это работает и в .gitignore. Но в файлах .gitattributes это может быть сложно, так как каждая строка может устанавливать разные вещи. Например, вы можете написать:

* text
*.bin -text

-text переопределяет text, поэтому последняя строка имеет приоритет, но только для файлов, имя которых заканчивается на .bin. Но вы также можете написать:

* text zorg
*.bin -text

то вы установили атрибут zorg для всех файлов, включая файлы *.bin. -text сбрасывает text для *.bin, но оставляет zorg установленным.

2Технически, вы можете полностью исключить часть text, если используете часть eol=lf. Установка eol на некоторое значение подразумевает установку text. Документация gitattributes использует text eol=lf в примере, так что это кажется обязательным.


Не используйте core.autocrlf

Очень старые версии Git использовали core.autocrlf, core.eol и другие подобные настройки core, чтобы делать подобные вещи. Наряду с этим вы можете — но не должны — использовать text=auto в строке .gitattributes. Это говорит Git угадать, содержит ли файл текст и, следовательно, строки, окончания строк которых могут быть изменены, или двоичные файлы (и, следовательно, не следует путать их окончания строк, поскольку они просто случайно напоминают окончания строк, но на самом деле являются ценными двоичными файлами). данные).

Предупреждение, которое вы видите, связано с этим. Если Git планирует возиться с каким-то файлом, и то, как Git планирует возиться с файлом, выглядит немного подозрительно для Git, Git предупреждает вас об этом.

Основной механизм

Может наступить время — а может быть, оно уже наступило, — когда вы захотите увидеть, что находится в самом репозитории, а не в файлах, с которыми вы работаете. Вы можете задаться вопросом, что означает это утверждение. В конце концов, разве репозиторий не является набором файлов, с которыми вы работаете? Но ответ: нет, это не так!

Git — это все о коммитах. То, что содержит и использует репозиторий Git, — это, по крайней мере, большая часть коммитов. Хотя коммит содержит файлы, коммит сам по себе не является ни файлом, ни содержащимися в нем файлами. Коммит — это отдельная вещь. Это что-то реальное, и это единица — ну, в основном единица — которую ваш Git передает другим Git, и наоборот.

Каждый коммит имеет уникальный номер. Это не уникальный номер в вашем репозитории, а глобальный или универсальный уникальный номер: UUID или GUID. Чтобы убедиться, что каждый идентификатор действительно уникален для каждого конкретного коммита, Git назначает коммитам очень длинные и случайные хэш-идентификаторы. По сути, это настоящие имена каждого коммита. Ваш Git объединяется с каким-то другим Git, и они обмениваются коммитами, используя эти идентификаторы. Если у вашего Git есть какой-то идентификатор, которого нет у них, это означает, что у вашего Git есть какой-то коммит, которого нет у них, и наоборот.

Этот идентификатор на самом деле является криптографической контрольной суммой всех данных, которые входят в фиксацию. По этой причине никакая часть любого коммита не может быть изменена после того, как коммит сделан. Вот почему вам не нужно беспокоиться о GitHub. Вы делаете коммиты на своем компьютере, и с этого момента ничто — даже сам Git — не может их изменить. Они полностью, полностью доступны только для чтения. Любые окончания строк внутри любого файла внутри любого коммита остаются такими навсегда — вместе с остальной частью этой строки и всеми другими строками в этом файле. Файлы внутри каждого коммита замораживаются навсегда.

Итак, коммит содержит файлы — на самом деле это его основные данные — вместе с некоторыми другими метаданными, которые мы не будем рассматривать в этом ответе. Файлы в коммите заморожены на все время вместе с метаданными. Они также хранятся в дедуплицированном формате, который может прочитать только сам Git. Эти два фактора делают файлы совершенно бесполезными для выполнения какой-либо реальной работы, потому что:

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

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

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

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

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

Механизм для этого работает на всем файле. Когда вы используете git add — что вы должны сделать, если вы обновили какой-то файл3 — Git в это время выполнит преобразование окончания строки и сожмет файл в замороженный формат, готовый к фиксации. 4 Точно так же, когда вы используете git checkout чтобы переключиться с одного коммита на другой, Git должен удалить из вашего рабочего дерева любой файл, который отличается (или полностью исчез!) в новом коммите, на который вы переключаетесь, и заменить его файлом, взятым из этого коммита. . Затем он расширяет зафиксированный файл до пригодного для использования в вашем рабочем дереве и при этом может заменять окончания строк только LF на окончания строк CRLF.

Особенно сложная часть этого, как отмечено в сноске 4, заключается в том, что Git усердно работает, чтобы не возиться с файлами, которые не изменились. Все это предполагает, что любая настройка eol=, которая могла применяться раньше, все еще применяется сейчас. Итак, иногда, когда вы меняете параметр eol=, вам нужно стереть индекс Git, чтобы сделать его недействительным, или коснуться всех ваших файлов в вашем рабочем дереве, или использовать git add --renormalize, если ваш Git достаточно новый, чтобы иметь опцию «перенормировать».

На практике это сводится к тому, что если вы измените настройку eol=, вы можете запустить git add --renormalize --all или что-то подобное. Если у вас его нет, есть несколько довольно уродливых обходных путей, но, вероятно, лучше всего обновить версию Git.


3Хотя вы можете использовать git commit -a или git commit --include и список имен файлов, внутри это работает, более или менее, для запуска git add на этих файлах. Там много чего более или менее, но этот ответ не будет вдаваться в эти детали.

4Механизм для этого включает в себя то, что Git по-разному называет индексом, или промежуточной областью, или — редко в наши дни — кешем. Все эти три термина относятся к одному и тому же. Аспект кеша этой штуки пытается отслеживать, какие файлы вы, возможно, действительно изменили в своем рабочем дереве, а какие вы точно не изменили в своем рабочем дереве. Это позволяет Git не трогать эти файлы, когда вы переходите от коммита к коммиту, ускоряя работу Git. Это также позволяет git add пропускать добавление некоторых файлов, ускоряя работу Git.

Это было огромное количество деталей! Большое спасибо за подробный ответ.

Randomh3r0 30.06.2022 16:33

Другие вопросы по теме