Перейти к содержанию

Cherry-pick: Выборочное применение коммитов

git cherry-pick позволяет применить изменения из конкретного коммита (или нескольких) из одной ветки в другую, без слияния целой ветки.

Зачем использовать Cherry-pick?

  • Нужно перенести только одно исправление (например, багфикс) из фич-ветки в main.
  • Хотим взять конкретную фичу из другой ветки, не сливая всё остальное.
  • Нужно применить коммит из чужой ветки или даже из другого репозитория.

Базовое использование

Применение одного коммита

# Находясь в целевой ветке
git checkout main
git cherry-pick <хеш-коммита>

Пример:

git cherry-pick a1b2c3d

Git применит изменения из указанного коммита к текущей ветке и создаст новый коммит.

Применение нескольких коммитов

git cherry-pick <хеш1> <хеш2> <хеш3>

Применение диапазона коммитов

git cherry-pick <начальный-хеш>^..<конечный-хеш>

Важно: Символ ^ включает начальный коммит в диапазон. Без него диапазон будет от следующего коммита после начального.

Пример:

git cherry-pick a1b2c3d^..e4f5g6h

Применит все коммиты от a1b2c3d до e4f5g6h включительно.

Опции Cherry-pick

Без создания коммита

Если хотите применить изменения, но сделать коммит позже (например, чтобы объединить несколько cherry-pick в один коммит):

git cherry-pick --no-commit <хеш>
# или кратко
git cherry-pick -n <хеш>

После применения всех нужных коммитов:

git commit -m "Применить исправления из ветки feature"

Изменение сообщения коммита

По умолчанию сообщение коммита копируется из оригинального. Можно изменить:

git cherry-pick --edit <хеш>

Откроется редактор для изменения сообщения перед коммитом.

Продолжение после конфликта

Если возник конфликт, разрешите его вручную, затем:

git add <разрешенные-файлы>
git cherry-pick --continue

Отмена cherry-pick

Если поняли, что пошли не туда:

git cherry-pick --abort

Что происходит с хешем коммита?

При cherry-pick Git создает новый коммит с новыми изменениями, поэтому хеш коммита будет отличаться от оригинального, даже если изменения идентичны.

До:
  A---B---C (feature)
       \
        D---E (main)

После git cherry-pick B (в main):

  A---B---C (feature)
       \
        D---E---B' (main)

Где B' — новый коммит с теми же изменениями, что и B, но с другим хешем.

Частые сценарии

Сценарий 1: Срочный багфикс

Разработчик работает в ветке feature и исправил критический баг. Нужно срочно применить исправление в main, не дожидаясь завершения всей фичи.

# В ветке feature найдите хеш коммита с исправлением
git log feature --oneline

# Переключитесь на main
git checkout main

# Примените только этот коммит
git cherry-pick <хеш-багфикса>

# Отправьте на сервер
git push origin main

Сценарий 2: Перенос фичи между ветками

Нужно перенести готовую фичу из одной ветки в другую, не сливая весь код.

git checkout target-branch
git cherry-pick <хеш-коммита-с-фичей>

Проблемы и ограничения

  • Дублирование истории: Если потом слить исходную ветку, могут возникнуть конфликты, так как коммиты уже были применены.
  • Потеря контекста: Cherry-pick копирует только изменения, но не историю развития фичи.
  • Не для частого использования: Лучше использовать слияние веток для регулярной работы. Cherry-pick — для исключительных случаев.

Альтернатива: Rebase

Если нужно перенести несколько последовательных коммитов, иногда проще сделать rebase:

git checkout feature
git rebase --onto main <точка-разделения> feature

Но это сложнее и требует понимания истории.


Назад: Теги → | Далее: Поиск и диффы →