Как заметил phd , git reset
может сделать это, потому что одно из многих потенциальных заданий git reset
- это копирование файла из коммита в индекс, не касаясь рабочего дерева .
Это немного удивительно, потому что заданное по умолчанию задание git reset
запускает , перемещая текущую ветвь, как указано HEAD
, в какой-то новый указанный пользователем коммит, и только , затем может быть - в зависимости от --soft
против --mixed
против --hard
- также копировать файлы из указанного пользователем коммита в индекс, а затем, возможно, в рабочее дерево. Однако, когда git reset
используется с путевыми именами, это меняет тактику, полностью отбрасывая задание move на текущую ветвь . Вот почему git reset
не допускает --hard
, --soft
или --mixed
с именами путей.
Когда git reset
перемещает текущую ветку, если вы - пользователь - не указываете какую-то конкретную фиксацию, выбираемая git reset
фиксация - это та, которую именует текущая ветка. Таким образом, это «движение» от коммита $old
к коммиту $new
- это то, где $old
равно $new
, и движения вообще нет. Вот почему git reset --soft
без аргументов - это запрет, а git reset --mixed
или git reset --hard
без дополнительных аргументов не изменяет то, какой коммит является текущим, но сбрасывает индекс и, возможно, также рабочее дерево.
В конечном счете, я всегда думаю, что git reset
объединяет слишком много действий в одну команду, ориентированную на пользователя: это должно быть как минимум две, и, вероятно, более, отдельные команды, ориентированные на пользователя, причем все они могут выполнить git reset
как их версионная версия как нам выполнить эту ориентированную на пользователя операцию . Команда git checkout
также делает это, так как имеет несколько различных пользовательских целей ( переключение на новую ветку , получение одного конкретного файла из одного конкретного коммита без переключения ветвей и т. Д.) .