Невозможно проверить файл формата linux из windows - PullRequest
1 голос
/ 05 мая 2020

Шаг 1: Запуск dos2unix file*

      Result : files converted to linux format on two files.

Шаг 2: запуск git status

       Result : Two files with changes in shown.

Шаг 3: Запуск git add .

Примечание: после этого git начинает игнорировать изменения lf и crlf.

 Result : warning: LF will be replaced by CRLF in file1.sh.The file will have its original line endings in your working directory warning: LF will be replaced by CRLF in file2.sh.The file will have its original line endings in your working directory

Шаг 4: Выполнить git status

  Result : Your branch is up to date. Noting to commit

Шаг 5: Повторить шаг 1 и шаг 2.

  Result : same as step 4

Шаг 6: Попробуйте после запуска git config core.autocrlf false

 Result: Problem is not resolved.

Ниже показан снимок шагов.

enter image description here

1 Ответ

2 голосов
/ 05 мая 2020

Вам ничего не нужно делать.

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

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

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

Но поскольку эти копии файлов буквально не могут быть изменены, а не могут могут использоваться любой другой программой на вашем компьютере, отличной от Git, они не годятся для работы. Они полезны только как заархивированные коммиты. Поэтому, когда вы используете git checkout (или git switch в Git 2.23 или новее), вы выбираете одну фиксацию, которую хотите «проверить». Git копирует все файлы из этого коммита, превращая их из специальных, предназначенных только для чтения, Git замороженных файлов в обычные повседневные файлы для чтения / записи в обычном файловом формате вашего компьютера.

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

Вот почему используются две копии каждого файла: есть замороженная в папке текущая фиксация , и в вашем рабочем дереве есть фиксация нормального формата. Но как насчет третьей копии? Эта копия находится в том, что Git называет своим индексом или промежуточной областью (два термина для одного и того же). Этот вид находится между замороженной копией HEAD -commit и копией рабочего дерева.

Давайте нарисуем простую иллюстрацию трех копий, предполагая, что у вас есть только два файла с именами README.md и main.py:

   HEAD         index       work-tree
---------     ---------     ---------
README.md     README.md     README.md
main.py       main.py       main.py

Все три копии, скажем, main.py совпадают - ну, вроде как - в начале, сразу после вашего начального git checkout. HEAD, тот, что находится в текущем коммите, заморожен: его буквально нельзя изменить. Копия рабочего дерева принадлежит вам, и вы можете делать с ней все, что хотите.

Промежуточная копия - это та, которую Git вставит в следующий коммит, который вы делаете. Прямо сейчас он соответствует двум другим. Но что, если вы поменяете main.py? Давайте добавим номер версии к каждому файлу:

   HEAD         index       work-tree
---------     ---------     ---------
README.md(1)  README.md(1)  README.md(1)
main.py(1)    main.py(1)    main.py(2)

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

Если вы хотите изменить main.py на go в следующий commit, теперь вы должны запустить git add main.py. Это копирует файл main.py в индекс Git, заменяя существующим. Новая копия находится в замороженном Git формате , но еще не заморожена:

   HEAD         index       work-tree
---------     ---------     ---------
README.md(1)  README.md(1)  README.md(1)
main.py(1)    main.py(2)    main.py(2)

... но теперь, после git add, копия в индекс отличается от копии HEAD (и такой же, как копия рабочего дерева). Если вы запустите git commit сейчас, Git сделает новую замороженную фиксацию из индексных копий каждого файла.

Обратите внимание, что копии - это index → ​​work-tree и work-tree → index

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

  • index → ​​work-tree: de-compress

Между тем, ваш более поздний git add должен скопировать файл вашего рабочего дерева в индекс:

  • work-tree → index: сжать в фиксированный формат

Что если, пока Git делает эти копии, мы дадим Git возможность превращать Unix / Linux окончания строк в стиле LF в Windows -стильные окончания строк CRLF? Тогда нам просто нужно это:

  • index → ​​work-tree: de-compress и Windows -ify
  • work-tree → index: de- Windows -ify и повторно сжать

и это то, что делает Git, когда вы говорите ему манипулировать окончаниями строк.


1 На самом деле, это даже проще , поскольку индекс содержит не настоящую копию файла, а скорее ссылку на внутренний Git объект blob . Но вам не нужно об этом беспокоиться - во всяком случае, если вы не углубитесь в детали использования git ls-files --stage и git update-index.


Что вы сделали

Вы началось и до сих пор выполнялось некоторое количество коммитов с core.autocrlf, установленным на true. Это говорит Git: не связываться с окончанием моей строки . Изменяемые Git файлы по умолчанию являются теми, которые, по его мнению, являются правильными, чтобы сделать это с ними. (Обычно разумнее использовать .gitattributes, чтобы указать Git, какими файлами следует управлять подобным образом, вместо того, чтобы позволять Git угадывать, но в большинстве случаев догадки Git довольно хороши.)

Поскольку Git уже выполняет ту же самую работу по окончанию строки Windows, более ранние файлы, зафиксированные на Windows, уже имеют окончание строк в стиле Linux только LF. Индексные копии, которые всегда буквально совпадают с зафиксированными копиями изначально, также имеют окончания строк в стиле Linux только LF.

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

Когда вы скажете Git , не связывайтесь с окончанием моей строки на все , затем имеет значение, имеют ли ваши файлы рабочего дерева окончания строк CRLF или только LF, потому что тогда git add скопирует все, что у вас есть в вашем work-tree в индекс Git, не вмешиваясь в окончание строк. Установка core.autocrlf в false и отсутствие каких-либо более явных настроек в .gitattributes делает это, поэтому now становится важным убедиться, что ваши файлы рабочего дерева имеют окончания, которые вы хотите иметь в new копирует вас git add, а затем git commit.

Вы запускали dos2unix на двух файлах рабочего дерева. Это берет их окончания строк в стиле CR-LF Windows, если у них изначально были эти окончания строк (они, вероятно, так и есть), и превращает их в окончания строк LF-ony. Затем вы запустили git add. Шаг git add на этот раз не де- Windows -измерил окончания строк, но повторно сжал файлы. В результате получился ... тот же файл, который уже был в индексе для каждого файла, потому что копии индекса всегда были в стиле Unix / Linux.

Обратите внимание, что теперь это очень важно , какие окончания строк вы вставляете в каждый файл, потому что с выключенным core.autocrlf и отсутствием .gitattributes записей вы сказали Git: передать все содержимое файла: не связываться с окончания строк.

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

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