Проблемы с git reset --hard после добавления .gitattribute - локальные изменения, которых там быть не должно

windows git gitattributes

2228 просмотра

1 ответ

13627 Репутация автора

Я наблюдал проблемы с CRLF после объединения пакетов от моего коллеги. Иногда строки с LF смешивались с источниками, вероятно, с теми, которые были объединены. Поэтому мы решили добавить .gitattributesфайл со следующим содержимым (комментарии удалены):

*.cpp text
*.h text
*.inc text
*.cfg text
*.dic text

*.sln text eol=crlf
*.vcxproj text eol=crlf
*.filters text eol=crlf
*.user text eol=crlf
*.rc text eol=crlf
*.rc2 text eol=crlf

Сейчас я наблюдаю странное поведение. Я могу видеть много modified: ...файлов (то есть неустановленных), которых там быть не должно. Я пытался git reset --hard, но файлы все еще имеют тот же статус. Я попытался снова клонировать хранилище - тот же результат.

Я git version 1.7.11.msysgit.0установил из Git-1.7.11-preview20120620.exeзагруженной в качестве текущей версии для Windows.

Что еще я должен попробовать?

Спасибо петя

Автор: pepr Источник Размещён: 07.09.2012 12:41

Ответы (1)


14 плюса

3584 Репутация автора

Решение

Причина

Именно * text=autoустановка .gitattributesвызывает эту проблему. Вы можете удалить его и жить долго и счастливо, но в вашем репо могут быть файлы с кодировками строк, отличными от репо по умолчанию, или даже файлы с несколькими разными кодировками окончания строк (т.е. и LF, и CRLF, и даже CR!).

Почему это происходит (детали)

Когда git проверяет файл как есть, он изменяет окончания строк после добавления / принятия . Файл на самом деле еще не изменен, но git уже считает его измененным, потому что это произойдет из-за настроек репо.

Каким-то образом это работает немного странно с git. Например, git reset --hardиногда работает, а иногда нет, возможно, в зависимости от ваших настроек. Или, если вы зайдете в свой файл .gitattributesи отметите расширение как двоичное, измененный файл волшебным образом исчезнет:

*.ext binary

Эффект сохраняется даже после того, как вы удалите двоичную маркировку, даже после git reset --hardповторного выполнения, поэтому это может быть ошибка git или проблема с кэшированием git. Выполнение git -rmфайла, а затем git reset --hardвосстановление восстанавливает измененную маркировку.

Как это исправить

Здесь мы предполагаем, что вы хотите сохранить * text=autoнастройки, так что git предупреждает вас о несовместимых концах строк в различных текстовых файлах сейчас и в будущем. Если это так, выберите свой метод:

Вариант 0 : Временно обмануть мерзавца из маркировки файлов как измененных

  1. Редактировать .gitattributes, комментировать * text=auto, сохранять
  2. git status (этот шаг необходим для изменения записей git в .gitattributes)
  3. git reset --hard(это восстановит, * text=autoа также сбросит все изменения в вашем рабочем каталоге, если вы их сделали).

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

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

Вариант 1 : простое исправление для конечного пользователя

Если у вас есть только несколько файлов, Убедитесь , что ваш .gitattributesи core.autocrlfустанавливаются по своему вкусу, а затем просто сделать , git add/commitи вы не должны видеть эту проблему снова. Файлы будут преобразованы в желаемые окончания строк и сохранены в вашем репо, как указано в вашей конфигурации. Этот коммит будет сохранен в вашем репо как "весь файл изменился", потому что в каждой строке будут изменены окончания строк. Для нескольких файлов в репо большего размера или с открытым исходным кодом это нормально. Обязательно объединяйте или выбирайте вишню, которые фиксируются во всех ваших ветках, так как проблема будет существовать во всех ветках, в которых были эти файлы, до тех пор, пока вы не исправите это. Кстати, здесь вы можете использовать вариант 0. т. Е. Если вы переключаетесь на нефиксированную ветвь и жалуетесь, запустите вариант 0, а затем исправьте (слияние или выбор вишни).

ВАЖНО: если вы идете этим путем Варианта 1, убедитесь, что преобразовали измененные файлы должным образом. git может делать это не для вас так, как вы ожидаете, поэтому сделайте это самостоятельно перед фиксацией, то есть используйте это: Преобразование форматирования новой строки из Mac в Windows . Причина, по которой git может запутаться, заключается в том, что я видел файлы, имеющие все три CR, Форматирование строк LF и CRLF заканчивается в них. Разбейте их в своем предпочтительном формате перед фиксацией.

Вариант 2. Усовершенствованная механика: исправление переписывания git-истории:

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

В моем случае я выбрал вариант 2, так как имел дело с множеством проблем с окончанием файла во многих ветвях. Но затем у меня появилось несколько неожиданных расширений, которые я не нормализовал, а просто сделал Вариант 1, так как пропустил только 5-6 файлов.

Автор: Dennis Размещён: 28.02.2014 03:19
Вопросы из категории :
32x32