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, например, я бы начал с (обратите внимание^0after , так как я не доверяю себе, поэтому я бы оставил истинную ветку нетронутой, так как могу ошибаться при выполнении 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", но для вишневого выбора.

  1. Использоватьgit cherry-pick --no-commit <commit>…​.
  2. Решите любые конфликты.
  3. Совершить.
  4. Продолжить сgit cherry-pick --continue.
  5. Решите любые конфликты.
  6. Теперь внесите изменения в предыдущий коммит.
  7. Покаgit statusпоказываетCherry-pick currently in progress.петля из шага 4.
Другие вопросы по тегам