Могу ли я в интерактивном режиме выбирать фрагменты из другого git commit?
Я ищу точно такое же поведение, как
git add -i -p
Но вместо того, чтобы составлять коммит из моего рабочего каталога, я бы хотел составить свой рабочий каталог из (частей) коммита. Как я могу это сделать?
Мой вариант использования состоит в том, что у меня есть несколько различных функций, которые сгруппированы в одном коммите, и я хотел бы проверить их по одному
С помощью cherry-pick -n
на самом деле не является удовлетворительным, так как это оставляет мне грязную работу по удалению всего ненужного кода. Мне бы очень хотелось выбрать выбранные изменения, которые я хочу протестировать.
4 ответа
Использование cherry-pick -n не совсем удовлетворительно, так как у меня остается грязная работа по удалению всего ненужного кода. Мне бы очень хотелось выбрать выбранные изменения, которые я хочу протестировать.
Раньше работа могла быть грязной, но с появлением git checkout --patch
Теперь вы можете выборочно отменить изменения, аналогичные git add -p
для добавления.
Вы могли бы использовать git reset --mixed HEAD^1
чтобы вернуться к индексу, а затем выбрать нужные вам куски git add -i
,
reset
откатит индекс до предыдущего коммита (по сути, без фиксации того, что было HEAD), но это не коснется рабочего дерева. Теперь вы можете ставить куски, которые вы хотите, совершать их и выбрасывать остальные с git reset --hard HEAD
,
Основываясь на великолепном ответе Кэмерона Скиннера, я немного расширю его, чтобы включить случай, когда у вас есть ветвь с несколькими коммитами, возможно слияние коммитов, возможно много "шума" и вы хотите выбирать только очень специфические фрагменты от него. (что было именно то, что случилось со мной сегодня)
Следуй этим шагам:
git checkout source-branch
git checkout -b cherry-pick-branch # Gives you a new branch based on source-branch
git reset --mixed master
Это оставит вас с веткой, где все изменения находятся в файловой системе, но ничего не было зафиксировано / поставлено. Тогда используйте git add -p
выборочно добавить, какие части вы хотите поставить, а затем зафиксировать и нажать как обычно.
грязная работа по удалению всего ненужного кода
Если это неприемлемо,
git cherry-pick -n ... # Starting from clean status
git reset # unstage
git add -p / -i [<pathspec>…] # add hunks interactively
git restore . # wipe the rest (at root dir)
, например, если вы хотите объединиться с незафиксированными изменениями или не хотите портить временные метки, то использование такого варианта может быть более чистым вариантом:
git show <commit> | tee _.patch
edit _.patch # strip unwanted hunks
git apply -3 _.patch
(Так долго как
git cherry-pick
а также
git apply
не поддерживаю
-p
напрямую)
Примечание: такие методы, как
git checkout / restore -p ...
не возвращайте последовательно фрагменты из определенного коммита, а выбирайте части из определенного состояния файла - возможно, потеряв изменения в других более поздних коммитах.