Cherry-pick — это команда Git, которая применяет изменения из одного или нескольких существующих коммитов в текущую ветку. В отличие от Merge (переносит всю ветку) и Rebase (переносит последовательность коммитов), cherry-pick выбирает только указанные коммиты. По данным git-scm.com, 2025, cherry-pick наиболее востребован в сценариях переноса исправлений между релизными ветками.
Главное
Cherry-pick — это команда Git, которая копирует изменения из указанного коммита и применяет их как новый коммит в текущей ветке. Название происходит от метафоры "выбирать вишенки": разработчик выбирает только те коммиты, которые нужны, игнорируя остальные.
В отличие от Merge, cherry-pick не создаёт merge commit и не требует полного слияния веток. В отличие от Rebase, cherry-pick не переносит последовательность коммитов — только указанные. Это делает cherry-pick идеальным инструментом для точечного переноса исправлений.
По данным Atlassian, 2025, cherry-pick используется в 47% команд, работающих с несколькими релизными ветками одновременно. Особенно востребован cherry-pick в мобильной разработке, где одновременно поддерживаются несколько версий приложения (LTS-релизы) и требуется переносить исправления между ними.
При выполнении cherry-pick Git вычисляет diff между указанным коммитом и его родителем, затем применяет этот diff к текущей ветке. Если изменения применились без конфликта — Git создаёт новый коммит с тем же сообщением, но новым SHA. Если есть конфликт — cherry-pick приостанавливается для ручного разрешения.
Синтаксис cherry-pick прост: укажите хеш коммита, который нужно перенести. Git скопирует изменения в текущую ветку как новый коммит. Поддерживается перенос нескольких коммитов за раз и целых диапазонов.
# Перенос одного коммита в текущую ветку
git cherry-pick a1b2c3d4
# Перенос нескольких коммитов
git cherry-pick a1b2c3d4 e5f6g7h8
# Перенос диапазона коммитов (от a1b2 до f9e8, не включая a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6
После выполнения cherry-pick текущая ветка получает новый коммит с изменениями из исходного. Сообщение коммита по умолчанию копируется из исходного, но может быть изменено флагом -n (не создавать коммит) или --edit (редактировать сообщение).
Рассмотрим типичный сценарий: в develop найден и исправлен критический баг, который также присутствует в релизной ветке release/v2.0. Нужно перенести только этот фикс, не сливая всю develop в релизную ветку.
# Найти хеш коммита с исправлением в develop
git log --oneline develop
# a1b2c3d fix: null check in payment processing
# Переключиться на релизную ветку
git checkout release/v2.0
# Применить исправление
git cherry-pick a1b2c3d4
# Если конфликт — разрешить и продолжить
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue
Флаг -x добавляет в сообщение коммита ссылку на исходный SHA: "(cherry picked from commit a1b2c3d4)". Это упрощает отслеживание, откуда был перенесён коммит. Рекомендуется использовать -x во всех сценариях, кроме временных черновиков.
При конфликте cherry-pick ведёт себя как merge: Git останавливается и помечает конфликтные файлы. Разработчик разрешает конфликт, делает git add и выполняет git cherry-pick --continue. Для отмены — git cherry-pick --abort. Флаг --strategy позволяет указать стратегию слияния (например, recursive с опциями).
# Разрешение конфликта при cherry-pick
# Git показывает конфликтные файлы
git status
# Разрешить вручную, затем:
git add разрешённый_файл.kt
git cherry-pick --continue
# Или отменить cherry-pick:
git cherry-pick --abort
Cherry-pick оптимален в сценариях, где требуется точечный перенос изменений без слияния целых веток. Рассмотрим пять основных случаев, когда cherry-pick становится лучшим выбором.
Для мобильной разработки cherry-pick критически важен при поддержке нескольких версий приложения. Например, если баг найден в версии 3.2, уже выпущенной в Google Play, а develop содержит код для версии 4.0 — cherry-pick позволяет перенести исправление в ветку v3.x без слияния всех breaking changes. Это особенно актуально для проектов, где одновременно поддерживаются две и более мажорные версии с разными API и зависимостями.
Пример из практики: в мобильном приложении обнаружен crash при авторизации через Google Sign-In на Android 12. Исправление внесено в develop и прошло ревью. Однако текущая релизная ветка v2.5 уже на этапе beta-тестирования. Cherry-pick коммита фикса из develop в release/v2.5 позволяет включить исправление в ближайший релиз, не перенося остальные изменения, которые ещё не готовы к выпуску.
При использовании cherry-pick в мобильных проектах важно учитывать зависимости: если исправление затрагивает файлы, которые были изменены в develop после точки расхождения релизной ветки, cherry-pick может принести неполный набор изменений. В таких случаях необходимо проверить, что все связанные изменения также перенесены, иначе приложение может не собраться или работать некорректно. Всегда проверяйте сборку после cherry-pick перед тем, как пушить изменения в общую ветку.
Три основных инструмента интеграции изменений в Git — merge, rebase и cherry-pick — решают разные задачи. Выбор зависит от того, какой объём изменений нужно перенести и как должна выглядеть история.
| Критерий | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| Объём | Вся ветка | Серия коммитов | Выбранные коммиты |
| История | Сохраняет ветвление | Линейная | Линейная |
| Merge commit | Да (кроме ff) | Нет | Нет |
| Автоматизация | Полная | По цепочке | Только указанные |
| Для публичных веток | Безопасен | Опасен | Безопасен |
Merge — когда нужно объединить две ветки целиком и сохранить информацию о ветвлении. Rebase — когда нужно обновить личную ветку до актуального состояния с чистой историей. Cherry-pick — когда нужен только один коммит или несколько выбранных коммитов.
На практике эти инструменты комбинируются: фича разрабатывается с периодическим rebase на develop, затем сливается через --no-ff merge, а при необходимости перенести исправление в другую ветку используется cherry-pick. Каждый инструмент решает свою задачу на своём этапе.
Cherry-pick — полезный, но потенциально опасный инструмент при неправильном или чрезмерном использовании. Основные риски связаны с дублированием коммитов, потерей контекста и конфликтами при последующих слияниях.
Рекомендации по минимизации рисков: всегда используйте флаг -x для указания исходного SHA, документируйте причину cherry-pick в сообщении коммита, и по возможности используйте merge вместо cherry-pick, когда это позволяет контекст. Если cherry-pick-ов становится много — рассмотрите реструктуризацию веток.
CI-пайплайны должны учитывать cherry-pick как отдельный сценарий. Рекомендуется настроить автоматическую проверку: при создании cherry-pick коммита CI проверяет, что изменённые файлы соответствуют ожидаемому набору, и запускает тесты для затронутых модулей. Это снижает риск регрессии при точечном переносе изменений между ветками.
Часто задаваемые вопросы
Cherry-pick переносит изменения из коммита в другую ветку. Revert создаёт новый коммит, который отменяет изменения указанного коммита в той же ветке. Revert не удаляет историю — он добавляет обратное изменение.
Да: git cherry-pick A B C — перенос коммитов A, B и C по порядку. Или git cherry-pick A..C — перенос всех коммитов от A до C (не включая A). Порядок переноса соответствует порядку в команде.
По умолчанию cherry-pick merge commit не работает, потому что у merge commit два родителя. Используйте флаг -m 1, чтобы указать, с каким родителем сравнивать. -m 1 берёт diff относительно первого родителя.
Отменить cherry-pick можно через git reset --hard HEAD~1, если это последний коммит. Если коммит уже запушен — используйте git revert , чтобы создать отменяющий коммит.
Нет смысла, но технически возможно. Если коммит уже существует в ветке, Git обнаружит, что изменения уже применены, и сообщит: "The previous cherry-pick is now empty, possibly due to conflict resolution." Коммит не будет создан повторно.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также