Индекс git
позволяет нам указать файлы, которые входят в новый объект tree
— такой объект tree
— это то, на что будет указывать любой вновь созданный объект commit
.
Я знаю, что использование git add <filename>
помещает файл в индекс, чтобы можно было создать дерево.
Однако кажется, что индекс хранит файлы даже до того, как они были добавлены в индекс. После выполнения следующей команды даже в «чистом» каталоге будут отображаться все те же файлы, что и в коммите, на который указывает HEAD
.
git ls-files --stage
(Я предполагаю, что это отображает файлы в index
, потому что stage
является синонимом с index
)
Зачем git
хранить в индексе «недобавленные» файлы? Разве эти файлы не доступны, глядя на HEAD
? Это кажется излишним.
Различие между HEAD, индексом и рабочим деревом становится еще более размытым при чтении определенных man
страниц. Например, это из man git-restore
.
По умолчанию, если задан --staged, содержимое восстанавливается из HEAD, иначе из индекса
b.txt
редактируется, но не добавляется в индекс (т.е. git status
показывает красные буквы), то версия b.txt
в index
такая же, как и в HEAD
. Однако git restore --staged -- b.txt
ничего не делает, тогда как git restore -- b.txt
восстанавливает рабочее дерево до версии в HEAD
фиксации.stage
является синонимом с index
, то почему --staged
ссылается на HEAD
на этой man
странице?Не используйте git ls-files --stage
для проверки подготовленных файлов, используйте git status
.
Когда человек разговаривает с другим человеком о git, он обычно использует «индекс» для обозначения изменений, которые вы внесли в свой репозиторий.
Но с точки зрения внутреннего устройства git: «индекс» на самом деле является содержимым текущего коммита HEAD плюс внесенные вами изменения.
Чтобы дать простую иллюстрацию: когда вы запускаете git diff --cached
, который сравнивает индекс с текущим коммитом HEAD, файлы, которые не были изменены, не будут отмечены как «отсутствующие» в индексе.
git ls-files --stage
просто сообщает содержимое индекса (внутреннего git). Есть отдельные случаи, когда эта информация может быть интересна, но в основном пользователи ищут git status
.
Относительно git restore
: я думаю, что есть путаница между вариантом --staged
для git restore
и вариантом --cached
для git diff
.
([edit] Я также скажу, что со стороны команды git довольно обманчиво иметь команду, которая успешно сочетает -s
, -S
, --source
и --staged
, и у меня также было несколько головных болей, прежде чем я понял, что к чему с эта команда. Варианты использования имеют смысл, имхо.)
Обратите внимание, что значение --staged для восстановления git сильно отличается: оно указывает, куда вы хотите записать свои файлы, например, «в хранилище git, в индексе» или «на диске, в рабочем дереве» (мой «против» также вводит в заблуждение: на самом деле вы можете попросить и то, и другое с помощью git restore -SW
).
цитирую документ:
-W, --worktree
-S, --постановкаУкажите место восстановления. Если ни одна из опций не указана, по умолчанию восстанавливается рабочее дерево. Указание --staged восстановит только индекс. Указание обоих восстанавливает оба.
Документация, которую вы цитируете, относится к -s|--source : если указано -S|--staged
, то значение по умолчанию для --source
не то же самое.
Итак: если файл b.txt
не имеет поэтапных изменений, это означает, что содержимое индекса для этого файла совпадает с содержимым HEAD, и, как вы правильно заметили, git restore --staged -- b.txt
не работает.
Использование --staged
- это другие случаи:
git restore --staged -- b.txt
удалил бы поэтапные изменения, если бы они былиgit restore -s that/other/commit --staged -- b.txt
поместит в индекс содержимое b.txt
, поступающее из that/other/commit
, без изменения рабочего дереваРазличие между чтением и записью в restore
не очень хорошо сформулировано в документах. Затем в смесь добавляется index
, чтобы сделать его более запутанным, когда index
действительно идентичен HEAD
в большинстве случаев. У них должна быть опция --dest=
в качестве аналога --source=
.
Мне по-прежнему кажется излишним, что индекс хранит ссылки на недобавленные файлы, когда эти файлы всегда будут идентичны тем, на которые указывает фиксация HEAD.
шутка для большей ясности, пожалуйста, обратитесь к генератору man-страниц git /joke