Почему "git reset HEAD" не отменяет мои незафиксированные, неустановленные изменения?

Я ранее мог отменить изменения через SourceTree, выполнив функцию "Отменить", которая под капотом производит эту команду:

git -c diff.mnemonicprefix=false -c core.quotepath=false reset -q HEAD -- myproj.csproj 
git -c diff.mnemonicprefix=false -c core.quotepath=false checkout HEAD -- myproj.csproj

Вдруг это не сработает. Я делаю сброс, ошибки не возникает, refreesh view, но файлы все еще "изменены". Затем я попытался сделать то же самое в командной строке со следующим, таким же результатом:

c:\myproject> git reset HEAD

Unstaged changes after reset:
M       myproj.csproj

Почему он по-прежнему отображается как неустановленное изменение?

Я проверил, что файл действительно доступен для записи (никакой процесс не удерживает блокировку)

Обновление

git checkout тоже не работал:

C:\myproject>git checkout myproj.csproj

C:\myproject>git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   myproj.csproj
#
no changes added to commit (use "git add" and/or "git commit -a")

Обновление 2 Также попробовали:

  • git checkout --
  • git checkout -- .
  • git checkout HEAD

ни одна из которых не решает мою проблему

update 3 - огромный шаг ближе:

Оказывается, когда я делаю checkout,.csproj действительно возвращается к правильной версии, но в проверенной версии используется другая кодировка строки строки. В то время как для зарегистрированной версии CR-LF (0D-0A) для подачи линии, выписка имеет только LF (0A). Следовательно, git полагает, что файл будет отличаться на каждой отдельной строке. Почему это?

update 4: добавлена ​​вторая строка команд git, выпущенных SourceTree. Я не заметил, что в первый раз, почему я думал, что git reset HEAD сделает все. Это не меняет того факта, что основная проблема по-прежнему связана с CR/LF (я думаю)

Резюме Я не нашел решения проблемы, но я "решил" ее, проверив файл. Мой первоначальный вопрос не содержал информации о том, что SourceTree действительно выдал правильные команды для отката, что я хотел, поэтому большинство ответов здесь затрагивают эту проблему. Реальная проблема пока неясна, но моя основная теория заключается в том, что она связана с CR/LF.

Ответы

Ответ 1

Если вам нужно удалить локальные изменения, выполните следующую команду

git checkout -- file_name

git reset HEAD не удаляет локальные изменения.

Ответ 2

Я подозреваю, что у вас были файлы, сохраненные с концами строк CRLF в вашем репозитории, а затем где-то по пути изменения вашей конфигурации, чтобы git начал нормализовать символы конца строки (либо core.autocrlf был установлен в true, или файл .gitAttributes был добавлен или изменен). Когда я столкнулся с этой проблемой, оказалось, что в мой репо был добавлен файл .gitAttributes, содержащий * text=auto.

(нормализация EOL означает, что git будет писать символы конца строки как LF в своей базе данных, независимо от того, что вы используете в своей рабочей копии).

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

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

Вы должны иметь git нормализовать окончание строки во всех текстовых файлах, поэтому эта проблема не будет всплывать (см. fooobar.com/questions/9565/... для инструкции о том, как это сделать). Если возможно, вы даже можете изменить свою историю, чтобы окончание строк было нормализовано одновременно с изменением настроек .gitAttributes.

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

  • Проверьте прежнюю версию
  • Отключить нормализацию конца строки
  • git reset
  • Повторно включить нормализацию конца строки

Ответ 3

Что вы хотите git reset HEAD --hard. git reset HEAD изменяется только один этап.

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

Ответ 4

Я столкнулся с чем-то похожим. Моя установка использует git на веб-сервере, чтобы вытащить самый последний код. По неизвестной причине он столкнулся с этой проблемой.

# git reset HEAD —hard

Неустановленные изменения после reset:

 'File Name'

Я попробовал все предлагаемые вещи здесь. Ничего не исправлено.

Я исправлю это в этом случае, выполнив

git add 'File Name'

то

git reset --hard HEAD

Который очистил проблему для меня.

Ответ 5

"Почему он по-прежнему отображается как неустановленное изменение?"

Потому что bare git reset HEAD ничего не делает с вашим рабочим деревом. Он только сбрасывает указатель HEAD на имя фиксации (в этом случае no-op, так как вы называете HEAD), и сбрасывает индекс в соответствии с новым HEAD (который, опять же, тот же самый в этом случае), поэтому сеть эффект в основном отбрасывает любые команды git add, git rm и т.д.).

Ответ 6

Я только что застрял в этой ситуации, и единственное, что зафиксировало это, было следующее:

git log

Найти первую фиксацию в репо и получить хэш (в моем случае началось с fdb14f)

Примечание.. Это работает только потому, что репо с проблемой было на сервере Linux, в то время как у меня было "исходное" репо "на моем ящике Windows, в котором содержалась последняя фиксация, которая исправила проблему CRLF.

git reset --hard fdb14f
git pull origin master

После того, как вы пробовали всевозможные разные вещи, это, наконец, позволило мне обойти эту проблему. Я исправил проблему CRLF в самом последнем коммите, но ничто другое, что я пробовал, не позволит мне обойти эти файлы.