TL; DR
Вам необходимо очистить бит пропуска рабочего дерева и заново запустить git status
, чтобы увидеть, что происходит.С этого момента все будет (несколько) яснее.
Long (ish)
Проблема здесь заключалась в том, что был установлен бит skip-worktree:
path/to/file.xml
Есть связанный бит, записанный как «предположим, без изменений».Оба бита имеют одинаковый фактический эффект.Ни то, ни другое не предназначено для того, как люди склонны использовать их, хотя в документации и ответах stackoverflow рекомендуют бит skip-worktree, 1 , и я тоже здесь;но любой из них делает то же самое на практике.Вам нужно запомнить (или заново обнаружить), какой бит вы установили, чтобы очистить его:
git update-index --no-skip-worktree path/to/file.xml
Когда любой бит установлен в файле, имя и содержимое которого записаны в индексе, Gitпредполагает, что содержимое, сохраненное через индекс, должно использоваться, а копия рабочего дерева должна игнорироваться во время операций git status
и git add
.
К счастью, Git достаточно умен, чтобы проверить фактическое рабочее деревокопировать на другие операции.Если Git собирается перезаписать копию рабочего дерева по какой-то причине - например, git checkout
или git merge
коммита, чья зафиксированная копия этого файла отличается от текущей индексной копии - Git удвоитпроверьте, что рабочее дерево копия path/to/file.xml
соответствует индексной копии.Если нет, Git будет жаловаться на то, что операция перезапишет копию рабочего дерева.
К сожалению, git status
, согласно проекту, не объявляет, что копия рабочего дерева вышласинхронизации с индексной копией.Это просто предполагает, что обе версии файла совпадают.Таким образом, вы запускаете git status
, и нет изменений для фиксации и, следовательно, ничего не сохраняется, но между тем git checkout
или git merge
продолжает жаловаться, что вы должны зафиксировать свои изменения., git status
замечает проблему.Мне кажется, что git status
здесь должно быть более информативным: нужно сказать, возможно, при использовании дополнительной опции или, возможно, просто всегда, что здесь есть какая-то разница, но она намеренно игнорируется из-за однойили оба этих бита.(Чтобы это работало хорошо с разреженным извлечением, он, вероятно, не должен ничего говорить о помеченном---skip-worktree
-файле, который находится в индексе, а не в рабочем дереве и исключен правилами разреженности.)
1 Предполагается, что без изменений подразумевается использование в файловых системах, где вызов lstat
является особенно медленным, и Git может его игнорировать.Skip-worktree предназначен для использования с разреженной проверкой, и Git не может игнорировать это.Git также не имеет ориентированных на пользователя команд разреженного извлечения, поэтому лучше установить бит пропуска рабочего дерева.