Ответ
git cherry-pick — это операция, которая применяет изменения из указанного коммита (или коммитов) к текущей ветке, создавая при этом новый коммит. Это полезно для точечного переноса исправлений, например, когда нужно внести хотфикс из ветки main в стабильную ветку release, не выполняя полного слияния веток.
Базовое использование:
# 1. Переключиться на целевую ветку
$ git checkout release-1.2
# 2. Выполнить cherry-pick коммита по его хешу
$ git cherry-pick abc123def
# 3. Если конфликтов нет, изменения будут применены и создан новый коммит.
Типичные сценарии в DevOps/CI-CD:
- Перенос хотфикса: Исправление бага, сделанное в
mainпосле релиза, нужно применить к старой версии. - Избирательный бэкпорт: Не все фичи из
developподходят для текущего релиза — выбираем только конкретные коммиты.
Работа с конфликтами:
Если при переносе возникают конфликты, Git приостановит операцию. Нужно разрешить конфликты вручную, добавить файлы (git add) и завершить операцию:
$ git cherry-pick --continue
# Или отменить, если передумали:
$ git cherry-pick --abort
Важные нюансы из практики:
- Cherry-pick создаёт новый коммит с другим хешем, даже если изменения идентичны. Это может привести к дублированию кода в истории, если позже вы сделаете merge веток.
- Лучше использовать для отдельных, самодостаточных коммитов. Перенос цепочки коммитов (
git cherry-pick A..B) может быть сложным. - В пайплайнах CI/CD можно автоматизировать cherry-pick для промоутинга определённых коммитов между средами, но это требует аккуратного скриптования и проверки.
Ответ 18+ 🔞
А, git cherry-pick! Ну это, блядь, такая штука, когда тебе нужно не всю ветку целиком тащить, а выковыривать один конкретный коммит, как самую сочную вишенку с торта, и тыкать её в другое место. Представь: на main какой-то умник починил критичный баг, а у тебя на release-1.2 клиенты уже орут, что всё падает. Делать полный мердж — овердохуища гемора, потому что там ещё куча непроверенного кода. Вот тут-то наш спаситель и появляется.
Как это делается, по-простому:
# 1. Переключиться на целевую ветку
$ git checkout release-1.2
# 2. Выполнить cherry-pick коммита по его хешу
$ git cherry-pick abc123def
# 3. Если конфликтов нет, изменения будут применены и создан новый коммит.
Где это вкатывает в нашей движухе (DevOps/CI-CD):
- Хотфикс по-быстрому: Багу на продакшене дали по башке в
main, а тебе этот фикс надо воткнуть в старую, но живую версию. Cherry-pick — и ты уже герой. - Избирательный отлов: В
developнакодили фич на месяц вперёд, а в релиз нужно протащить только две из них, которые уже готовы. Берёшь коммиты именно этих фич — и вперёд, без лишнего мусора.
А вот тут начинается веселье — КОНФЛИКТЫ:
Идеально, конечно, когда пролетает как по маслу. Но если изменения в целевом месте уже другие, Git встанет в ступор и скажет: «Чувак, я нихуя не понял, разбирайся сам». Операция встанет на паузу.
Придётся лезть в файлы, смотреть, где эти красные <<<<<<< HEAD, решать, чей код круче, править, потом:
$ git add .
$ git cherry-pick --continue
# А если всё пошло по пизде и ты сам от себя охуел — всегда можно сдаться:
$ git cherry-pick --abort
Важные нюансы, про которые лучше знать, пока не стало поздно:
- Главный подводный камень: cherry-pick создаёт абсолютно новый коммит. Хеш будет другой, родитель другой. И если потом ты решишь смерджить ветки, Git может офигеть и показать тебе одни и те же изменения дважды, потому что он не всегда понимает, что это одно и то же. История становится пиздопроебибной.
- Тащить лучше коммиты-одиночки, самодостаточные. Пытаться cherry-pick'ом перенести целую цепочку (
A..B) — это уже высший пилотаж и волнение ебать, там можно так запутаться, что мало не покажется. - В автоматических пайплайнах можно заставить его самому делать cherry-pick, например, промоутить коммит из тестовой среды в прод. Но это, ёпта, надо скриптовать с умом, с кучей проверок, а то получится «нажми одну кнопку — и сервис ляжет». Доверия к таким автоматизациям, блядь, ноль, если делал не ты.