Неустановленные изменения, оставшиеся после сброса git --hard

275

После git reset --hard, git statusдает мне файлы в Changes not staged for commit:разделе.

Я также попытался git reset ., git checkout -- .и git checkout-index -f -a, но безрезультатно.

Итак, как я могу избавиться от этих неустановленных изменений?

Кажется, это касается только файлов проекта Visual Studio. Weird. Смотрите эту пасту: http://pastebin.com/eFZwPn9Z . Что особенного в этих файлах, это то, что в .gitattributes у меня есть:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

Кроме того, autocrlfустановлено в false в моем глобальном .gitconfig. Может ли это быть как-то актуально?

Norswap
источник
Применяли ли вы эти команды из корня хранилища? Уведомление .обозначает текущий каталог, а не корневой каталог
Александр
1
Я сделал их из корневого хранилища действительно.
Norswap
Какая у вас gitверсия? Или вы делаете глупую ошибку, или у вас есть старая версия, которая глючит?
Шахбаз
Это мерзавец 1.7.4. Это может быть ошибкой, но команды кажутся достаточно простыми, и я не смог обнаружить ошибку.
Norswap
Для записи я попытался использовать последнюю версию msysgit (1.7.11), но проблема сохраняется.
Norswap

Ответы:

361

У меня была такая же проблема, и она была связана с .gitattributesфайлом. Однако тип файла, который вызвал проблему, не был указан в .gitattributes.

Я смог решить проблему, просто запустив

git rm .gitattributes
git add -A
git reset --hard
GameScripting
источник
7
Это директива * text = auto в файле gitattributes. Он автоматически меняет окончания файлов, поэтому файлы будут автоматически помечены как «измененные» при проверке статуса.
Коди Джанго
3
Это работает, но я не совсем понимаю, почему. Кто-нибудь хочет объяснить каждую команду?
Эдвин Стотелер
18
@NLwino, git rm .gitattributesудаляет .gitattributes из индекса. git add -Aдобавляет все (включая удаление .gitattributes) к индексу, который должен быть только удалением .gitattributes, если это действительно было проблемой. git reset --hardсбрасывает все незафиксированные изменения, которые включают удаление .gitattributes. По сути, это игнорирует .gitattributes (и * text=autoдирективу) для одного коммита, удаляя его, затем сбрасывая индекс, пока он удаляется, и, следовательно, возвращая его обратно, но после того, как вы уже сбросили другие файлы, поэтому они не были изменены снова.
облачные работы
4
@ GameScripting, это решение не работает для меня. Не существует такого файла как .gitattributes: «fatal: pathspec '.gitattributes' не соответствует ни одному файлу»
Pacerier
4
Я делаю так, и это говорит fatal: pathspec '.gitattributes' did not match any files . Что я делаю не так?
Мед
136

ПОСТАНОВИЛИ !!!

Я решил эту проблему, используя следующие шаги

1) Удалить все файлы из индекса Git.

git rm --cached -r .

2) Перепишите индекс Git, чтобы подобрать все новые окончания строки.

git reset --hard

Решение было частью шагов, описанных на сайте git https://help.github.com/articles/dealing-with-line-endings/

Яцек Шибиш
источник
5
Это работает, когда ничего не делает! Мы перепробовали все в этой и многих других темах - это большая команда разработчиков, поэтому привлечение всех к одной и той же работе было кошмаром, но это решает проблему.
tkersh
Интересно ... Я использовал "git rm --chached <one_specific_file> вместо того, чтобы удалять все." Git status "сообщил, что файл удален и не отслежен. Затем" git reset --hard "исправит этот файл и все другие файлы, которые сообщалось, что «Изменения не были сделаны». (Перед использованием git rm я изо всех сил пытался сбросить
настройки
Вы знаете, он удаляет весь ваш кеш. В крупных проектах это может тратить много времени.
Охар
Это жестоко. Вы могли бы сделать то же самое, удалив каталог репо и повторно клонировав.
ingyhere
4
Учтите, что вы работаете в Windows и не учитывает регистр. Если вы также работаете с разработчиками, которые работают с чувствительными к регистру файловыми системами, такими как Mac или Linux, они могут фиксировать теги, ветви или даже файлы в разных случаях. В этом случае ваш индекс покажет существующие файлы, которые будут перезаписаны ОС при извлечении. Единственный способ исправить это - установить политику именования на вашем Git-сервере (ловушки) или заранее выявлять ошибки.
ingyhere
97

Git не будет сбрасывать файлы, которых нет в хранилище. Так что вы можете:

$ git add .
$ git reset --hard

Это внесет все изменения, которые заставят Git узнать об этих файлах, а затем сбросить их.

Если это не сработает, вы можете попытаться спрятать ваши изменения:

$ git stash
$ git stash drop
YuriAlbuquerque
источник
4
Файлы уже были отслежены. В любом случае пробовал, и это тоже не работает. Должно быть, что-то действительно не так с моим репо, но я понятия не имею, что. Что касается мерзавца, см. Мой ответ Шахбазу.
Norswap
Что происходит, когда вы делаете git-статус?
ЮрийАльбукерке
1
Я думал о решении. Сделайте коммит и интерактивный перебаз, чтобы стереть этот коммит.
ЮрийАльбукерке
Я попробовал это однажды, и это сработало, но позже я сделал еще одну попытку и придумал удивительный результат, обрисованный в общих чертах в редактировании моего ответа.
Norswap
@YuriAlbuquerque, Git не совсем понимает POLA . Разве весь смысл в том, git reset --hardчтобы « сбросить и промежуточную область, и рабочий каталог, чтобы они соответствовали »? Если файл не подготовлен, очевидно, что мы захотим удалить его, когда сделаем это reset --hard.
Pacerier
71

Если вы используете Git для Windows, это, вероятно, ваша проблема

У меня была та же проблема, и тайник, полный сброс, очистка или даже все они оставляли изменения позади. Проблема оказалась в том, что режим x file не был правильно установлен git. Это «известная проблема» с git для windows. Локальные изменения отображаются в gitk и git status как старый режим 100755, новый режим 100644, без каких-либо реальных различий в файлах.

Исправление - игнорировать режим файла:

git config core.filemode false

Больше информации здесь

vezenkov
источник
2
Это работало, когда даже когда rm -rf *; git checkout HEAD .не. Уф!
форумчан
Сработало у меня, пока сбой тайника / hard reset / rm .attributes все не удался.
Каке
Это также работало для меня, когда у меня были проблемы с работой с git repo в Linux, которая была размещена на Mac
prmph
работал для меня - попробовал все остальное, и да, старый режим против нового режима был проблемой (заметил, что у меня было другое число, но файлы те же)
Taehoon A Kim
Жизнь и экономия времени.
Йогеш Патил
31

Хорошо, я вроде решил проблему.

Казалось, что .gitattributesфайл, содержащий:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

заставил файлы проекта казаться неустановленными. Я не знаю, почему это так, и я очень надеюсь, что кто-то, знакомый со способами мерзавца, даст нам хорошее объяснение.

Мое исправление было удалить эти файлы, и добавить autocrlf = falseпод [core]в .git/config.

Это не то же самое, что предыдущая конфигурация, так как для этого требуется каждый разработчик autocrlf = false. Я хотел бы найти лучшее решение.

РЕДАКТИРОВАТЬ:

Я прокомментировал компрометирующие строки, раскомментировал их, и это сработало. Что ... Я даже не ...!

Norswap
источник
1
У меня была такая же проблема, и это было единственное решение, которое сработало. В моем случае я переключился с ветви функций на свой мастер и извлек некоторые новые изменения из апстрима, и это только начало происходить для 2 файлов, которые были изменены. Похоже, что файлы, возможно, были переведены из Unix в окончания строк Windows, которые могут иметь какое-то отношение к этому. Не уверен, как или почему, хотя.
Стивен Суровец
+1 Та же проблема в Windows Git. Уже было autocrlf = false. Я объединил изменения из репозитория svn upstream ( git svn fetch/ git merge git-svn) и у меня остался 1 файл, помеченный как измененный. Странно то, что у меня была эта проблема раньше, и все, что мне нужно было сделать, это проверить другую ветку (с -fфлагом), а затем переключиться обратно. Я сделал это, и это сработало, но когда я переключился на ветку функций, «изменение» вернулось! Ваше редактирование внизу ответа было решением. В моем случае я прокомментировал / раскомментировал одну строку в верхней части моего файла .gitattributes:* text=auto !eol
Аарон Бленкуш
1
Этот EDIT работал и для меня: закомментируйте строки .gitattributes, запустите git status, раскомментируйте строки .gitattributes, git statusснова запустите
Ignitor
Это потому, что git сбрасывает эти файлы, а затем применяет окончания строк, указанные .gitattributesснова. git diff, Вероятно , показывает знаменитую стену красного / зеленого цвета стены , что является типичным для завершений строк различий.
Dagrooms
22

Возможная причина № 1 - Нормализация конца строки

Одна из ситуаций, в которой это может произойти, - когда рассматриваемый файл был зарегистрирован в хранилище без правильной конфигурации для концов строк (1), в результате чего в хранилище был файл с неправильными окончаниями строк или смешанными окончаниями строк. Для подтверждения убедитесь, что git diffотображаются только изменения в окончаниях строк (по умолчанию они могут быть не видны, попробуйте git diff | cat -vувидеть возврат каретки как буквенные ^Mсимволы).

Впоследствии кто-то, вероятно, добавил .gitattributesили изменил core.autocrlfнастройку, чтобы нормализовать окончания строк (2). На основе .gitattributesили глобальной конфигурации Git применил локальные изменения к вашей рабочей копии, которые применяют запрошенную нормализацию конца строки. К сожалению, почему-то git reset --hardне отменяются эти изменения нормализации линии.

Решение

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

Наилучший вариант - позволить git применить требуемую нормализацию путем нормализации всех концов строк в репо, чтобы они соответствовали .gitattributes, и фиксации этих изменений - см. Попытка исправить окончания строк с помощью git filter-branch, но безуспешно .

Если вы действительно хотите попытаться отменить изменения в файле вручную, то, кажется, самое простое решение - стереть измененные файлы, а затем указать git восстановить их, хотя я отмечаю, что это решение не работает согласованно на 100%. время ( ВНИМАНИЕ: НЕ запускайте это, если ваши измененные файлы имеют изменения, отличные от окончаний строки !!):

    git status --porcelain | grep "^ M" | cut -c4- | xargs rm
    git checkout -- .

Обратите внимание, что если вы не нормализуете окончание строк в репозитории в какой-то момент, вы продолжите сталкиваться с этой проблемой.

Возможная причина № 2 - нечувствительность к регистру

Вторая возможная причина - нечувствительность к регистру в Windows или Mac OS / X. Например, допустим, что в хранилище существует следующий путь:

/foo/bar

Теперь кто-то в Linux фиксирует файлы в /foo/Bar(возможно, из-за инструмента сборки или чего-то, что создало этот каталог) и отправляет. В Linux это фактически две отдельные директории:

/foo/bar/fileA
/foo/Bar/fileA

Проверка этого репо в Windows или Mac может привести к изменению, fileAкоторое не может быть сброшено, потому что при каждом сбросе git в Windows проверяется /foo/bar/fileA, а затем, поскольку Windows не учитывает регистр, перезаписывает содержимое fileAwith /foo/Bar/fileA, в результате чего они «модифицируются».

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

/foo/bar/fileA
/foo/bar/filea

Могут быть и другие подобные ситуации, которые могут вызвать такие проблемы.

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

Решение

Решение состоит в том, чтобы привести в соответствие регистр файлов в индексе git и регистр в файловой системе Windows. Это можно сделать либо в Linux, который покажет истинное положение вещей, либо в Windows с очень полезной утилитой с открытым исходным кодом Git-Unite . Git-Unite применяет необходимые изменения регистра к индексу git, который затем может быть зафиксирован в репо.

(1) Это было, скорее всего, кем-то, кто использовал Windows, без какого-либо .gitattributesопределения для рассматриваемого файла, и использовал глобальную настройку по умолчанию, для core.autocrlfкоторой false(см. (2)).

(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/

Раман
источник
Черт возьми, прошел весь путь до этого. Я должен был совершить после первой строки, но я смог, наконец, проверить мастер. Это было не весело.
Тим Либерман
16

Если другие ответы не работают, попробуйте добавить файлы, а затем сбросить

$ git add -A
$ git reset --hard

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

joshuakcockrell
источник
Это работает. Я просто использовал $ git add .вместо$ git add -A
Бьярне Герхардт-Педерсен
8

Другой причиной этого могут быть нечувствительные к регистру файловые системы . Если у вас есть несколько папок в вашем репо на одном уровне, имена которых отличаются только регистром, вы будете поражены этим. Просмотрите исходный репозиторий, используя его веб-интерфейс (например, GitHub или VSTS), чтобы убедиться.

Для получения дополнительной информации: https://stackoverflow.com/a/2016426/67824

Охад Шнайдер
источник
Чтобы найти имена таких файлов, запуститеgit ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d
Diomidis Spinellis
5

Вы можете stashудалить свои изменения, а затем выбросить тайник:

git stash
git stash drop
Shahbaz
источник
1
Вы также можете быть заинтересованы в этом .
Шахбаз
5

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

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

Запустите чистую команду:

# Remove all untracked files and directories. (`-f` is `force`, `-d` is `remove directories`)

git clean -fd
МРК
источник
3
К сожалению, это не решает проблемы, связанные с окончанием строки.
Кристофер Шнайдер
Это единственное, что решает мою проблему, какой бы она ни была. У меня не было .gitattributesфайлов, и окончания строк не были проблемой, так как я на Linux, и все разработчики и наш сервер - Linux.
Сэмюэл Нефф
4

Проверьте свой .gitattributes.

В моем случае у меня *.js text eol=lfв нем и git вариант core.autocrlfбыл true.

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

Я исправляю это, комментируя *.js text eol=lfв моем, .gitattributesи оставляю комментарий после него.

Похоже, это просто волшебство.

Ohar
источник
Это было для меня, модернизация моего проекта, представленного *.bat text eol=crlfв моем проекте.
Лев
1

Я столкнулся с аналогичной проблемой, которая также затрагивала .gitattributes, но в моем случае это LFS GitHub. Хотя это не совсем сценарий OP, я думаю, что он дает возможность проиллюстрировать, что .gitattributesделает файл и почему он может привести к неустановленным изменениям в форме «фантомных» различий.

В моем случае, файл уже был в моем хранилище, как с начала времен. В недавнем коммите я добавил новое git-lfs trackправило, используя шаблон, который был задним числом слишком широким, и в конечном итоге соответствовал этому древнему файлу. Я знаю, что не хотел менять этот файл; Я знаю, что не менял файл, но теперь он был в моих неустановленных изменениях, и никакие проверки или повторные сбросы этого файла не собирались исправить Зачем?

Расширение GitHub LFS работает в основном за счет использования хуков, которые gitобеспечивают доступ через .gitattributesфайл. Как правило, записи .gitattributesуказывают, как должны обрабатываться соответствующие файлы. В случае OP это было связано с нормализацией концов строк; по моему, было ли позволить LFS обрабатывать хранилище файлов. В любом случае, фактически файл, который gitвидит при вычислении a git diff, не совпадает с файлом, который вы видите при проверке файла. Следовательно, если вы измените способ обработки файла с помощью .gitattributesшаблона, который соответствует ему, он будет отображаться как неустановленные изменения в отчете о состоянии, даже если в файле действительно нет изменений.

Все, что я сказал, мой «ответ» на вопрос: если .gitattributesвы хотите сделать изменение в файле, вам следует просто добавить изменения и двигаться дальше. Если нет, то внесите изменения, .gitattributesчтобы лучше представлять, что вы хотите делать.

Ссылки

  1. GitHub LFS Specification - отличное описание того, как они подключаются к вызовам функций cleanи, smudgeчтобы заменить ваш файл в gitобъектах простым текстовым файлом с хэшем.

  2. gitattributes Documentation - Вся подробная информация о том, что доступно для настройки gitпроцесса обработки ваших документов.

Мерв
источник
0

У меня такая же проблема. Я делал, git reset --hard HEADно каждый раз, когда я делал, git statusя видел некоторые файлы как измененные.

Мое решение было относительно простым. Я просто закрыл свою IDE (здесь это был Xcode) и закрыл командную строку (здесь это был терминал на моей Mac OS) и попробовал снова, и это сработало.

Тем не менее, я так и не смог найти причину проблемы.

Мед
источник
0

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

git checkout master -f
git checkout <your branch>

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

Изменить: я мог бы действительно повезло в первый раз. Оказывается, я снова получил немного после переключения веток. Оказалось, что файлы, о которых git сообщает, были изменены после изменения веток. (Очевидно, потому что git не всегда правильно применял конец файла CRLF к файлам.)

Я обновился до последней версии Git для Windows и надеюсь, что проблема исчезла.

mrfelis
источник
0

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

старший старший
источник
0

Как указывалось в других ответах, проблема в автокоррекции конца строки. Я столкнулся с этой проблемой с * .svg файлами. Я использовал файл SVG для иконок в моем проекте.

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

* .svg бинарный

vuamitom
источник
0

В похожей ситуации. В результате многолетних мучений со многими программистами, которые смогли собрать разные кодировки концов строк ( .sp , .js, .css ... не суть) в один файл. Некоторое время назад отказался .gitattributes. Настройки для репо оставлены autorclf = trueи safecrlf = warn.

Последняя проблема возникла при синхронизации из архива с разными концами строк. После копирования из архива в git статусе многие файлы меняются с пометкой

The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ...

Советы от Как нормализовать рабочие окончания линий деревьев в Git? помог

git add -u

MrSwed
источник
0

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

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:   path/to/package (new commits)

Переход в path/to/packageпапку a git statusдолжен дать следующий результат:

HEAD detached at 7515f05

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

git checkout master

И вы получите сообщение о том, что ваша локальная ветвь будет иметь некоторое количество коммитов за удаленной веткой git pullи ты должен быть вне леса!

Робин Де Шеппер
источник
0

По какой-то причине

git add .

не работал , но

$ git add -A

сработало!

Даниил Даниелецкий
источник