Cherry-pick и сжатый диапазон коммитов в подкаталог или поддерево
Как я могу сказать cherry-pick, чтобы выбрать сжатый диапазон коммитов?
Или, другими словами, применить diff между двумя коммитами к текущему состоянию репозитория?
Следующее не работает (cherry-pick не имеет опции --squash):
git cherry-pick --squash e064480..eab48b59c
Примечание: мой вариант использования находится в рамках сценария поддерева - прежде чем кто-либо начнет утверждать, что я не должен раздавить.
Следующее работает, но тогда у меня есть ряд отдельных коммитов. Я могу раздавить их вручную с помощью интерактивной перебазировки потом.
git cherry-pick -X subtree=vendor/package e064480..eab48b59c
Есть ли какой-нибудь способ сделать сжатие как часть вишневого кирки?
5 ответов
Проходить -n
в git cherry-pick
, Это будет применять все коммиты, но не коммитить их. Тогда просто делай git commit
зафиксировать все изменения в одном коммите.
Полезная альтернатива vs
git cherry-pick -n
для некоторых случаев использования может быть
git merge --squash
- например, если вы хотите протестировать изменения функциональной ветки поверх своей интеграционной ветки без перебазирования.
Источник: в чем разница между git merge --squash и git cherry-pick?
Следовать от мастера => вишня выбрать два коммита из другой ветки
мастер проверки git
git cherry-pick: 1
git cherry-pick:2
git reset --soft HEAD~2 (количество коммитов Cherry Pick, т.е. 2)
git add.
git commit
Из этого обсуждения 2022 года есть и другие подходы:
git diff A...B | git apply --3wa
Но,- он не показывает сообщения фиксации,
- вы не сможете использовать графический инструмент слияния, который показывает весь исходный файл.
Когда используешь "git cherry-pick
" и есть конфликты, видно изменение контекста всего файла.
Йоханнес Сикст предлагает интерактивную перебазировку
Пересадить диапазон
A..B
истории поверх HEAD, например, я бы начал с (обратите внимание^0
after , так как я не доверяю себе, поэтому я бы оставил истинную ветку нетронутой, так как могу ошибаться при выполнении rebase):$ git checkout --detach HEAD ;# this is only to use @{-1} later $ git rebase -i --onto HEAD A B^0
Затем, если моя цель состоит в том, чтобы сжать все в один коммит, тогда замените все «выбрать», кроме первого, на «сквош».
Это даст мне единственный шанс отредактировать одно сообщение коммита, но буфер редактора начинается с сообщения журнала из всего оригинала, поэтому я могу выбрать из них хорошие фрагменты при написании нового материала. У меня будет результат на отдельном HEAD.
Если мне понравится результат, я могу обновить ветку, в которой я был изначально.$ git checkout -B @{-1}
Или, если я этого не сделаю, возможно, из-за того, что допустил ошибки, я могу просто отказаться от него и вернуться к исходной ветке.
$ git checkout @{-1}
Однако Ноам Йорав-Рафаэль возражает:
Моя основная проблема с использованием "
rebase -i
"заключается в том, что мне потребуется исправлять конфликты слияния один за другим при каждом коммите, в котором они появляются, вместо того, чтобы исправлять все конфликты сразу, рассматривая изменение с на как один. Это также требует ручного редактирования для каждого коммита
междуA
иB
.
Ноам предлагает:
Я думаю, что лучший способ сделать то, что я хочу, используя существующие команды, это:
git checkout A git merge --squash B git commit --no-edit git checkout @{2} # Go back to where we were at the beginning. # This is not exact, as you're in detached HEAD state. git cherry-pick --edit @{1} # cherry-pick the squashed commit A..B
Это позволяет вам исправить конфликты слияния за один раз, показывает все файлы, вызывающие конфликты, и позволяет вам редактировать сообщение коммита, начиная с описания всех сжатых коммитов.
Я думаю, что это также дает довольно хорошее объяснение тому, что "
cherry-pick --squash
" подойдет: это действительно аналог "merge --squash
", но для вишневого выбора.
- Использовать
git cherry-pick --no-commit <commit>…
. - Решите любые конфликты.
- Совершить.
- Продолжить с
git cherry-pick --continue
. - Решите любые конфликты.
- Теперь внесите изменения в предыдущий коммит.
- Пока
git status
показываетCherry-pick currently in progress.
петля из шага 4.