После tar/untar git repo gitk показывает "Локальные незафиксированные изменения, не зарегистрированные в индексе"
У меня есть каталог, содержащий небольшой репозиторий git.
git status, и gitk --all, не показывают незафиксированных изменений.
Если я tar/ сжимаю этот каталог с:
tar czf git-repo.tar.gz git-repo/
Затем перенесите этот tar-файл в тестовый каталог и распакуйте его:
tar xzf git-repo.tar.gz
Когда я
cd test/git-repo/
gitk --all
gitk показывает строку вверху всех коммитов (с обычной красной точкой):
"Локальные незафиксированные изменения, не зарегистрированные в индексе"
git status все еще показывает:
On branch master
nothing to commit, working tree clean
Тестирование на различия с:
diff -r git-repo/ test/git-repo/
Не показывает различий.
Если я запустил git clean, эта строка исчезнет.
я пробовал git clean -i
в надежде увидеть оскорбительное имя файла, однако оно завершается без запроса интерактивного подтверждения очистки. И после этого Гитк не показывает незафиксированных изменений.
Я работаю: GIT версии 2.11.0
Просто немного сложно объяснить клиенту "Почему происходят незавершенные изменения?" когда на самом деле нет.
Спасибо за понимание...
2 ответа
gitk
просматривает информацию кеша в индексе, чтобы определить, является ли ваш рабочий каталог грязным или нет. Индекс хранит информацию о состоянии текущего рабочего каталога, так что ему не нужно анализировать файлы.
Когда ты бежишь git status
, он будет сравнивать содержимое HEAD
к содержанию индекса, чтобы показать поэтапные изменения. Это просто и быстро; если идентификатор файла отличается, то его содержимое должно быть другим. Тем не менее, существует более дорогостоящее вычисление, чтобы определить, есть ли в файле изменения без изменений. Файл должен иметь свой SHA1, вычисленный, а затем сравнить со значением в индексе.
Чтобы избежать этого дорогостоящего вычисления, git кэширует struct stat
информация о рабочем каталоге содержимого в индексе:
README.md
ctime: 1516120578:638662531
mtime: 1516120578:638662531
dev: 16777220 ino: 1752439
uid: 501 gid: 20
size: 13224 flags: 0
Теперь, когда вы бежите git status
, это может просто stat
содержимое рабочего каталога. Если какой-либо файл имеет одинаковый размер, inode, ctime, mtime и т. Д., То git предполагает, что файл не изменился. Это позволяет git status
оставаться в курсе, когда у вас есть неизмененные файлы. Но если какой-либо файл имеет другое значение, он будет хэшировать файл. Если файл имеет тот же хеш (т.е. вы просто запустите touch
на файл без изменения содержимого), то индекс будет обновляться с новой информацией кеша. Если вы действительно изменили файл, то git status
сообщит о неустановленном изменении.
gitk
однако не пытается хэшировать файл, чтобы определить, действительно ли он изменился. Вы можете сами убедиться в этом на тривиальном примере. Здесь у меня есть хранилище с одним файлом, foo
без изменений.
Если в командной строке я коснусь файла, обновляя его метку времени:
% touch foo
Теперь gitk сообщает о моем хранилище как о незафиксированных изменениях:
Тем не менее, если я бегу git status
снова в командной строке обновит информацию о кеше в индексе, а теперь gitk
поймет, что на самом деле нет никаких неустановленных изменений:
Когда вы копируете свой репозиторий - с рабочим каталогом - вы помещаете на диск рабочий каталог, который не соответствует информации кэша в индексе. git
будет фактически перефразировать содержимое, чтобы определить, что ваш рабочий каталог на самом деле не грязный, но gitk
не.
Как правило, не очень хорошая идея копировать git-репозиторий и рабочий каталог; Вообще говоря, вы должны проверить новый рабочий каталог.
Хотя ответ Эдварда объясняет проблему, я хочу предложить потенциальный обходной путь.
имеет полезный--argscmd
флаг, который запускается при каждом обновлении. Предполагая, что это не займет слишком много времени (примечание:git gc
может ускорить его), вы можете запуститьgit status
при каждом обновлении, запустив его так:
gitk --argscmd="git status >/dev/null"
Это должно скрыть проблему доgitk
реализует проверку состояния файла, которая больше соответствует git.