Cherry-pick — это команда Git, которая применяет изменения из указанного коммита в текущую ветку, не перенося всю историю исходной ветки. В отличие от merge или rebase, cherry-pick работает с каждым коммитом индивидуально: разработчик выбирает конкретный коммит по хешу и переносит только его изменения. По данным документации Git (2026), cherry-pick особенно полезен для точечного переноса исправлений между релизными ветками, когда весь merge излишен или опасен. Команда создаёт новый коммит с новым хешем, но сохраняет оригинальное сообщение и автора.
Главное
Cherry-pick — это команда git cherry-pick, которая берёт изменения из существующего коммита и применяет их как новый коммит в текущей ветке. Исходный коммит остаётся на месте в своей ветке, а в целевой ветке создаётся копия изменений. Команда полезна, когда нужно перенести конкретное исправление, не перемещая всю ветку целиком.
Синтаксис: git cherry-pick <commit-hash>. Git анализирует разницу (diff) указанного коммита с его родителем и применяет эту разницу к текущей ветке. Если изменений несколько файлов — все они переносятся вместе. Команда принимает также диапазоны: git cherry-pick A..B — все коммиты от A до B, не включая A.
Флаги расширяют возможности: -n (--no-commit) применяет изменения к рабочей директории и индексу без создания коммита — полезно, когда нужно объединить изменения нескольких коммитов в один. Флаг -x добавляет в сообщение коммита строку (cherry picked from commit ...), что упрощает отслеживание происхождения изменений в истории.
# Cherry-pick a single commit by hash
git cherry-pick a1b2c3d
# Cherry-pick multiple commits (sequentially)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# Cherry-pick without auto-commit
git cherry-pick -n a1b2c3d
# Flag -x adds reference to original commit
git cherry-pick -x a1b2c3d
Основной сценарий — перенос исправлений между релизными ветками. Представьте: в develop нашли и исправили критический баг. Релизная ветка release/v2.1 уже отделена, и в ней этот баг тоже присутствует. Merge всей develop в release перенесёт много неготового кода, а cherry-pick одного коммита с фиксом — безопасное и точное решение.
Второй сценарий — отмена изменений (revert) с последующим восстановлением. Если коммит был отменён через git revert, а потом выяснилось, что отмена была ошибочной — cherry-pick отменённого коммита восстанавливает изменения. Это корректнее, чем отмена revert, так как не создаёт повторных конфликтов.
Третий сценарий — объединение коммитов из разных feature-веток в одну тестовую ветку для интеграционного тестирования. Вместо того чтобы сливать несколько незавершённых веток (с недоделанным кодом), можно выбрать только готовые коммиты из каждой и протестировать их совместную работу.
Cherry-pick отличается от rebase и merge тем, что работает на уровне отдельных коммитов, а не веток целиком. Если rebase переносит все коммиты ветки, а merge объединяет две ветки, то cherry-pick выбирает только нужные. Это делает его более точным инструментом, но и более ручным.
Ещё одно отличие — авторство. При cherry-pick Git по умолчанию сохраняет автора оригинального коммита (Author), но коммитером (Committer) становится текущий пользователь. В сообщении коммита можно отследить происхождение через флаг -x. При rebase автор и коммитер — оба текущий пользователь с новым хешем.
Производительность: cherry-pick одного коммита выполняется быстрее, чем merge двух веток с большим количеством коммитов. Но если нужно перенести десятки коммитов, лучше создать временную ветку и выполнить rebase — это будет более эффективно и не потребует указания десятков хешей.
| Операция | Область применения | Побочные эффекты |
|---|---|---|
| Cherry-pick | Отдельные коммиты | Новый хеш, дублирование кода |
| Rebase | Все коммиты ветки | Перезапись истории, новые хеши |
| Merge | Полное слияние веток | Merge-коммит, сохранение истории |
Несколько коммитов можно перенести одной командой, перечислив их хеши через пробел: git cherry-pick A B C. Git применит коммиты последовательно в указанном порядке. Если какой-то из коммитов вызывает конфликт, cherry-pick приостанавливается, и разработчик должен разрешить конфликт, после чего продолжить командой git cherry-pick --continue.
Диапазон коммитов: git cherry-pick A..B (все коммиты после A до B, не включая A) и git cherry-pick A^..B (все коммиты от A включительно до B). Диапазоны удобны, когда нужно перенести все коммиты из одной ветки, но без родительской связи — например, при переносе готовой фичи из старой ветки в новую.
Флаг --strategy определяет, как Git будет применять изменения. По умолчанию используется recursive-стратегия, но можно указать ours или theirs для автоматического выбора стороны конфликта. Флаг --mainline используется при cherry-pick merge-коммита — указывает номер родителя (1 или 2), относительно которого вычисляется diff.
# Cherry-pick commit range
git cherry-pick develop~5..develop~2
# Cherry-pick merge commit (specify parent)
git cherry-pick -m 1 m9n0o1p
# Use theirs strategy
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# Continue after conflict resolution
git cherry-pick --continue
Конфликты при cherry-pick возникают, когда изменения переносимого коммита затрагивают те же строки, которые были изменены в целевой ветке. Git приостанавливает выполнение, помечает конфликтующие файлы и ожидает разрешения. В статусе такие файлы отображаются как both modified.
Порядок действий при конфликте: открыть конфликтующий файл, найти маркеры конфликта (<<<<<<<, =======, >>>>>>>), отредактировать содержимое, убрать маркеры, выполнить git add для разрешённых файлов и запустить git cherry-pick --continue. Если конфликт неразрешим — git cherry-pick --abort отменяет весь cherry-pick, возвращая ветку в исходное состояние.
Частая проблема: коммит уже содержит изменения, эквивалентные существующим. В этом случае Git сообщает «nothing to commit» или «empty commit» при попытке cherry-pick. Флаги --keep-redundant-commits и --empty=keep заставляют Git создавать пустой коммит для сохранения последовательности, а --skip позволяет пропустить такой коммит.
# Conflict during cherry-pick — stop
git cherry-pick a1b2c3d
# error: could not apply a1b2c3d... commit message
# Resolve conflict → add to index
git add src/conflicted_file.swift
git cherry-pick --continue
# Skip empty commit (already applied)
git cherry-pick --skip
# Full abort
git cherry-pick --abort
Первое правило: всегда проверяйте, что переносимый коммит самодостаточен. Если коммит A зависит от изменений в коммите B, который не переносится, cherry-pick A может сломать сборку. Перед cherry-pick полезно проверить, какие файлы изменил коммит, через git show --stat <hash>.
Второе правило: документируйте cherry-pick. Используйте флаг -x, чтобы в сообщении коммита сохранилась ссылка на исходный коммит. Это поможет при последующем анализе истории понять, откуда взялось изменение. Без -x cherry-pick выглядит как обычный коммит, и его происхождение можно установить только через git log --graph.
Третье правило: избегайте cherry-pick между ветками, которые расходятся слишком сильно. Если от момента создания коммита прошло много времени и кодовая база существенно изменилась, конфликты будут многочисленными и сложными. В таких случаях лучше сделать фикс заново в целевой ветке — это займёт меньше времени, чем разрешение десятков конфликтов.
Часто задаваемые вопросы
Зачерипикнуть — применить изменения указанного коммита в текущую ветку через git cherry-pick. Команда создаёт новый коммит с теми же изменениями, но новым хешем. Исходный коммит остаётся без изменений в своей ветке. Это альтернатива слиянию целиком всей ветки, когда нужен только один конкретный коммит.
Cherry-pick выбирается, когда нужно перенести один или несколько конкретных коммитов без переноса всей ветки. Merge применяется для полного слияния веток. Типичный сценарий cherry-pick — перенос багфикса из ветки разработки в релизную ветку, в которой ещё не готовы остальные изменения.
До завершения — git cherry-pick --abort отменяет операцию полностью. После успешного завершения — git revert <hash> создаёт коммит, отменяющий изменения cherry-pick. Отличие от --abort: revert не удаляет коммит из истории, а создаёт новый отменяющий коммит.
Пустой коммит возникает, когда изменения уже присутствуют в целевой ветке. Используйте git cherry-pick --skip чтобы пропустить такой коммит, или git cherry-pick --keep-redundant-commits чтобы создать пустой коммит для сохранения последовательности хешей.
Cherry-pick переносит выбранные коммиты (по одному или списком) в текущую ветку. Rebase переносит все коммиты ветки на новую базу. Cherry-pick не изменяет исходную ветку, rebase переписывает историю. Cherry-pick точен, но ручной; rebase автоматичен, но опасен для публичных веток.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также