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

Другие вопросы по тегам