Возможно ли поместить файл в его версию в HEAD ~ 1, не изменяя его содержимое на диске? - PullRequest
1 голос
/ 25 апреля 2019

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

По сути, я хотел бы иметь возможность установить версию файла из предыдущего коммита, а затем иметь возможность повторно запустить git add -p filename, чтобы выбрать, какие изменения принадлежатв первом новом коммите против второго.Я не хочу, чтобы что-то на диске изменилось;Моя единственная цель - разделить один коммит на два с минимальными затратами.

git checkout HEAD~1 -- filename делает то, что я хочу, но удаляет изменения с диска.Мне нужно, чтобы они оставались на диске, чтобы я мог добавить их к следующему коммиту.(Примечание: вы можете отменить эту команду с помощью git reset filename && git checkout filename)

git add HEAD~1 -- filename чувствует, что она должна делать то, что я хочу, но команда не запускается с fatal: pathspec 'HEAD~1' did not match any files

1 Ответ

2 голосов
/ 25 апреля 2019

Как заметил 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 также делает это, так как имеет несколько различных пользовательских целей ( переключение на новую ветку , получение одного конкретного файла из одного конкретного коммита без переключения ветвей и т. Д.) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...