git status показывает изменения, git checkout — <file> не удаляет их

StackOverflow https://stackoverflow.com/questions/2016404

Вопрос

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

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout -- Rhino.Etl.Core/Enumerables/CachingEnumerable.cs

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout `git ls-files -m`

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git reset --hard HEAD
HEAD is now at 6c857e7 boo libraries updated to 2.0.9.2 and rhino.dsl.dll updated.

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")
Это было полезно?

Решение

Существует множество проблем, которые могут вызвать такое поведение:

Нормализация окончания строки

У меня тоже были подобные проблемы.Все сводится к тому, что git автоматически преобразует crlf в lf.Обычно это вызвано смешанными окончаниями строк в одном файле.Файл нормализуется в индексе, но когда git затем снова денормализует его, чтобы сравнить с файлом в рабочем дереве, результат получается другим.

Но если вы хотите исправить это, вам следует отключить ядро.autocrlf, измените все окончания строк на lf, а затем включите его снова.Или вы можете полностью отключить его, выполнив:

git config --global core.autocrlf false

Вместо того , чтобы ядро.autocrlf, вы также можете рассмотреть возможность использования .gitattribute Файлы.Таким образом, вы можете убедиться, что все, использующие репозиторий, используют одни и те же правила нормализации, предотвращая попадание смешанных окончаний строк в репозиторий.

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

Мерзавец справочные страницы скажи это:

Преобразование CRLF имеет небольшую вероятность повреждения данных.autocrlf=true преобразует CRLF в LF во время фиксации и LF в CRLF во время проверки.Файл который содержит смесь LF и CRLF до фиксации не может быть воссоздан заново с помощью git.Для текстовых файлов это правильная вещь, которую нужно сделать:он исправляет окончания строк таким образом, что у нас есть только строка LF окончания в репозитории.Но для двоичных файлов, которые случайно классифицируются как текстовые, преобразование может повредить данные.

Файловые системы без учета регистра

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

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

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

У меня была эта проблема в Windows, но я не был готов рассмотреть последствия использования config --global core.autocrlf false Я также не был готов отказаться от других частных веток и вкусностей в моем запасе и начать с нового клона.Мне просто нужно кое-что сделать.Сейчас же.

У меня это сработало, исходя из идеи, что вы позволяете git полностью переписать ваш рабочий каталог:

git rm --cached -r .
git reset --hard

(Обратите внимание, что запуск просто git reset --hard был недостаточно хорош, как и обычный rm на файлах, предшествующих reset как предложено в комментариях к первоначальному вопросу)

Еще одно решение, которое может сработать для людей, поскольку ни один из вариантов текста не сработал для меня:

  1. Заменить содержимое .gitattributes с помощью одной строки: * binary.Это говорит git обрабатывать каждый файл как двоичный, с которым он ничего не может сделать.
  2. Убедитесь, что сообщение о файлах-нарушителях исчезло;если это не так, вы можете git checkout -- <files> чтобы восстановить их в версии репозитория
  3. git checkout -- .gitattributes чтобы восстановить .gitattributes файл в исходное состояние
  4. Убедитесь, что файлы по-прежнему не помечены как измененные.

Для будущих людей, столкнувшихся с этой проблемой:Изменение режима файла также может иметь те же симптомы. git config core.filemode false я это исправлю.

Это сводило меня с ума, особенно то, что я не мог исправить это без какого-либо из решений, найденных в Интернете.Вот как я решил эту проблему.Не могу взять кредиты здесь, так как это работа коллеги :)

Источник проблемы:Моя первоначальная установка git была без автоматического преобразования строк в Windows.Это привело к тому, что моя первоначальная фиксация в GLFW была без надлежащего окончания строки.

Примечание:Это всего лишь локальное решение.Следующий парень, клонирующий репозиторий все равно застрянет с этой проблемой.Постоянное решение может быть найдено здесь: https://help.github.com/articles/dealing-with-line-endings/#re-normalizing-a-repository.

Настройка:Xubuntu 12.04 Репозиторий Git с проектом glfw

Проблема:Не удалось сбросить файлы glfw.Они всегда отображаются как измененные, независимо от того, что я пробовал.

Решаемая:

edit .gitattributes

Comment out the line:    # text=auto

Save the file

restore .gitattributes:   git checkout .gitattributes

У меня был файл .bat с такой же проблемой (не удалось избавиться от него в неотслеживаемых файлах).git checkout - не сработало, как и ни одно из предложений на этой странице.Единственное, что у меня сработало, это сделать:

git stash save --keep-index

А затем удалить тайник:

git stash drop

Получил одну и ту же проблему дважды!Оба раза, когда я вносил какие-то изменения, я сохранял их, а затем пытался вставить обратно.Не удалось опубликовать изменения, так как у меня есть много файлов, которые были изменены - но это НЕ ТАК!Они СОВЕРШЕННО одинаковые.

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

git rm --cached -r .
git reset --hard

Теперь я изменил почти все файлы в моем репозитории.

При изменении файла он сообщает, что я удалил все строки, а затем добавил их снова.

Немного тревожно.Теперь я буду избегать припрятывания в будущем..

Единственное решение - это клонировать новый репозиторий и начать все сначала.(Сделал это в прошлый раз)

Я смог исправить это, только временно удалив файл .gitattributes моего репозитория (который определял * text=auto и *.c text).

Я побежал git status после удаления и внесения изменений они исчезли.Они не вернулись даже после того, как .gitattributes был возвращен на место.

Попробуйте сделать

проверка git -f

Это должно очистить все изменения в текущем рабочем локальном репозитории

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

Также некоторые программы, такие как bash (в Linux), требуют этого .файлы sh завершаются по LF.

Чтобы убедиться, что это произойдет, вы можете использовать gitattributes .Это работает на уровне репозитория независимо от того, каково значение autcrlf .

Например, у вас может быть .gitattributes , подобный этому:* текст=авто

Вы также можете быть более конкретны в отношении типа файла / расширения, если это имело значение в вашем случае.

Затем autocrlf может локально преобразовывать окончания строк для программ Windows.

В смешанном проекте C # / C ++ / Java / Ruby / R, Windows / Linux это работает хорошо.Пока никаких проблем.

У меня тоже были те же симптомы, но вызваны они были чем-то другим.

Я был не в состоянии:

git checkout app.js //did nothing
git rm app.js //did nothing
rm -rf app.js //did nothing

даже на git rm --cached app.js он помечается как удаленный и в неотслеживаемых файлах, которые я мог видеть app.js.Но когда я попытался rm -rf app.js и придавать форму git status опять же, он по-прежнему показывает мне файл в формате "неотслеживаемый".

После пары попыток с коллегой мы выяснили, что это было вызвано Grunt!

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

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

Пример этой проблемы и как ее проверить:

git diff styleguide/filename

diff --git a/filename b/filename
old mode 100644
new mode 100755

Чтобы избежать этого, вам следует убедиться, что вы правильно настроили git, используя

git config --global core.filemode false

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

Наша проблема заключалась в том, что у нас не было принудительного исполнения для конечных строк, а в репозитории была смесь DOS / Unix.Еще хуже было то, что на самом деле это было репо с открытым исходным кодом в этой позиции, и мы разветвляли его.Теми, кто является основным владельцем репозитория операционной системы, было принято решение изменить все конечные строки на Unix, и был сделан коммит, который включал .gitattributes чтобы обеспечить соблюдение окончаний строк.

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

Во время моего исследования этого вопроса я наткнулся - https://help.github.com/articles/dealing-with-line-endings/ - Если я снова столкнусь с этой проблемой, я бы сначала начал с того, что попробовал это.


Вот что я сделал:

  1. Изначально я выполнил слияние, прежде чем понял, что у меня возникла эта проблема, и мне пришлось прервать это - git reset --hard HEAD (Я столкнулся с конфликтом слияния.Как я могу прервать слияние?)

  2. Я открыл файлы, о которых идет речь, в VIM и перешел на Unix (:set ff=unix).Такой инструмент, как dos2unix конечно, можно было бы использовать вместо

  3. преданный

  4. объединил master в (у ведущего есть изменения DOS-2-Unix)

    git checkout old-code-branch; git merge master

  5. Разрешенные конфликты и файлы снова были DOS, так что пришлось :set ff=unix когда в VIM.(Обратите внимание, что я установил https://github.com/itchyny/lightline.vim что позволило мне увидеть, каков формат файла в строке состояния VIM)

  6. преданный.Все улажено!

Я зафиксировал все изменения, а затем сделал и отменил их при фиксации.Это сработало для меня

git добавить .

git commit -m "Случайная фиксация"

сброс git -hard HEAD~ 1

Если вы клонируете репозиторий и сразу видите ожидающие изменения, значит, репозиторий находится в несогласованном состоянии.Пожалуйста, НЕ комментируйте * text=auto из .gitattributes файл.Это было сделано специально, потому что владелец репозитория хочет, чтобы все файлы хранились последовательно с окончаниями строк LF.

Как заявил Ханкка, следуя инструкциям по https://help.github.com/articles/dealing-with-line-endings/ это способ решить проблему.Простая кнопка:

git clone git@host:repo-name
git checkout -b normalize-line-endings
git add .
git commit -m "Normalize line endings"
git push
git push -u origin normalize-line-endings

Затем объедините (или отправьте запрос) ветку владельцу репозитория.

Проблема, с которой я столкнулся, заключается в том, что Windows не заботится о заглавных буквах имени файла, но git заботится.Таким образом, git сохранил версию файла в нижнем и верхнем регистре, но смог извлечь только одну.

Больше ничего на этой странице не работало.Наконец-то у меня это сработало.Не показывает неотслеживаемых или зафиксированных файлов.

git add -A
git reset --hard

Для меня проблема заключалась в том, что Visual Studio была открыта при выполнении команды

git checkout <file>

После закрытия Visual Studio команда сработала, и я, наконец, смог применить свою работу из стека.Поэтому проверьте все приложения, которые могут вносить изменения в ваш код, например SourceTree, SmartGit, NotePad, NotePad ++ и другие редакторы.

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

git reset --hard
git pull origin
git merge

Я сталкивался с этой проблемой несколько раз раньше.В настоящее время я разрабатываю на компьютере с Windows 10, предоставленном моим работодателем.Сегодня это конкретное поведение git было вызвано тем, что я создал новую ветку из моей ветки "develop".По какой-то причине, после того, как я снова переключился на ветку "разработка", некоторые, казалось бы, случайные файлы сохранились и отображались как "измененные" в "git status".

Кроме того, в тот момент я не мог оформить заказ в другой ветке, поэтому застрял на своей ветке "разработка".

Это то, что я сделал:

$ git log

Я заметил, что новая ветка, которую я создал из "develop" ранее сегодня, отображалась в первом сообщении "commit", на которое ссылались в конце "HEAD -> develop, origin/ разработка, происхождение / ГОЛОВА, -Ветка-которую-я-создал-ранее-сегодня".

Поскольку на самом деле мне это было не нужно, я удалил его:

$ git branch -d The-branch-i-created-earlier-today

Измененные файлы все еще отображались, так что я сделал:

$ git stash

Это решило мою проблему:

$ git status
On branch develop
Your branch is up to date with 'origin/develop'.

nothing to commit, working tree clean

Конечно $ git stash list покажет сохраненные изменения, и поскольку у меня их было немного, и ни один из моих сохранений мне не был нужен, я сделал $ git stash clear чтобы УДАЛИТЬ ВСЕ ТАЙНИКИ.

ПРИМЕЧАНИЕ:Я не пробовал делать то, что кто-то предлагал здесь до меня:

$ git rm --cached -r .
$ git reset --hard

Возможно, это тоже сработало, я обязательно попробую это в следующий раз, когда столкнусь с этой проблемой.

Я решил это, отредактировав файл .git / config, добавив:

[branch "name_branch"]
    remote = origin
    merge = refs/heads/name_branch

Затем я зашел в .git / refs / heads / name_branch и поместил идентификатор последнего коммитаenter code here

Я решил это таким образом:

  1. Скопируйте содержимое нужного вам правильного кода
  2. Удалите файл, вызывающий проблему (тот, который вы не можете устранить), со своего диска.теперь вы должны найти обе версии одного и того же файла, помеченные как удаленные.
  3. Зафиксируйте удаление файлов.
  4. Создайте файл еще раз с тем же именем и вставьте правильный код, который вы скопировали на шаге 1
  5. зафиксируйте создание нового файла.

Это то, что сработало для меня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top