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

Я хотел бы удалить все изменения в моей рабочей копии.
Бег 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")

25 ответов

Решение

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

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

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

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

git config --global core.autocrlf false

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

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

Git manpages говорят это:

Преобразование 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/.

Установка: 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

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

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

Вид беспокойства. Теперь я не буду прятаться в будущем.

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

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

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

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

$ git log

Я заметил, что новая ветвь, созданная мной из "Develop" ранее сегодня, отображалась в первом сообщении "commit", на которое ссылались в конце "HEAD -> Develop, origin/development, origin / HEAD, The-branch-i-создал Раньше сегодня

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

$ 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 checkout -f

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

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

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

У меня была старая избыточная ветка с разными окончаниями строк. Переключение на это заставило меня немного застрять, пока я не применил --force.

      git checkout mainbranch --force

Вслед за быстрым git branch -D brokenbranch.

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

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

Наша проблема заключалась в том, что у нас не было принудительного применения конечных линий, а в репозитории была смесь 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 когда в вим. (Обратите внимание, что я установил https://github.com/itchyny/lightline.vim что позволило мне увидеть формат файла в строке состояния VIM)

  6. совершено. Все отсортировано!

Эта проблема также может возникать, когда участник репо работает на компьютере с Linux или когда меняются окна с 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

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

Кроме того, некоторые программы, такие как bash (в linux), требуют, чтобы файлы.sh заканчивались LF.

Чтобы убедиться в этом, вы можете использовать gitattributes. Он работает на уровне хранилища независимо от значения autcrlf.

Например, вы можете иметь.gitattributes как это: * text=auto

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

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

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

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

мерзавец добавить.

git commit -m "Случайный коммит"

git reset --hard HEAD ~ 1

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

Я не смог:

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 и peform git status снова он все еще показывает мне файл в "неотслеживаемом".

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

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

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

git checkout <file>

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

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

git add -A
git reset --hard

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

Как заявляет HankCa, следуя инструкциям на 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

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

.gitattributes с

      test_file_with_crlf text eol=crlf 

не очень хорошо сочетается с файлом, который на самом деле является CRLF в репо (вероятно, проверен с помощью core.autocrlf=false)

Решение:

  1. Повторно добавьте файл с помощью autorcrlf=input (см. git add--renormalize)
  2. Постарайтесь ни над чем не работать до этого коммита.

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

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

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

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

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

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

Одно предложенное решение здесь не сработало, я обнаружил, что файл на самом деле был ссылкой на некоторые специальные символы:

% ls -l StoreLogo.png
lrwxrwxrwx 1 janus janus 8 Feb 21 10:37 StoreLogo.png -> ''$'\211''PNG'$'\r\n\032\n'

% git status    
Changes not staged for commit:
    modified:   StoreLogo.png

% git rm --cached -r StoreLogo.png
rm 'src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png'

% git reset StoreLogo.png         
Unstaged changes after reset:
M   src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png

% git status                      
Changes not staged for commit:
    modified:   StoreLogo.png

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

git reset --hard
git pull origin
git merge
Другие вопросы по тегам