# git cherry-pick _Ветки и слияния · GitLab Knowledge Base_ **TL;DR:** Берёт один коммит из другой ветки и применяет его на текущую, создавая дубликат с новым SHA. Используется для hotfix'ов в нескольких релиз-ветках и переноса одиночных коммитов. `git cherry-pick ` берёт правку конкретного коммита и применяет её на твою ветку. Без всей истории, без merge, без rebase - только этот один коммит. ## Базовая форма ```bash git switch main git cherry-pick a1b2c3d # → создаёт новый коммит на main с тем же содержимым, # что и a1b2c3d, но с новым SHA ``` Сообщение коммита копируется как есть. Можно добавить `cherry-picked from`-метку: ```bash git cherry-pick -x a1b2c3d # Добавит в сообщение строку: # (cherry picked from commit a1b2c3d...) ``` Полезно для аудита: видно, что коммит - копия другого. ## Типичные сценарии **Hotfix в нескольких релизных ветках.** ```bash # На main починили баг git switch main git commit -m "fix: handle null in user.profile" # SHA = a1b2c3d # Перенесли в release/v1.4 git switch release/v1.4 git cherry-pick a1b2c3d # И в release/v1.5 git switch release/v1.5 git cherry-pick a1b2c3d ``` **Достать полезный коммит из заброшенной ветки.** Кто-то начал ветку, забросил, ушёл. Часть коммитов оттуда пригодилась бы. Cherry-pick'аешь нужные. **Коммит ошибочно сделан не в ту ветку.** Закоммитил на main вместо feature. ```bash # Запомним SHA LAST=$(git rev-parse HEAD) # Откатим main на один коммит git reset --hard HEAD~1 # Применим на feature git switch feature git cherry-pick $LAST ``` ## Диапазон коммитов ```bash git cherry-pick A..B # коммиты после A до B включительно # (не сам A) git cherry-pick A^..B # включая A ``` Применяются по одному, в исходном порядке. При конфликте на любом Git останавливается. ## --no-commit ```bash git cherry-pick -n a1b2c3d # Применит правку, но не закоммитит - оставит в индексе ``` Удобно, если хочется объединить несколько cherry-pick в один коммит: ```bash git cherry-pick -n sha1 sha2 sha3 git commit -m "backport: nullability fixes from main" ``` ## Конфликт Разрешается как при merge или rebase: ```bash # Конфликт после cherry-pick - править файлы, # убрать маркеры git add git cherry-pick --continue # или отмена: git cherry-pick --abort ``` ## Подводные камни - **Дубли коммитов.** После cherry-pick один и тот же набор правок лежит в двух коммитах с разными SHA. При последующем merge между ветками может возникнуть «ложный» конфликт. - **Зависимости.** Cherry-pick переносит один коммит без предыдущих. Если он опирался на что-то добавленное в предыдущем коммите ветки-источника, на ветке-цели этого может не оказаться, и сборка сломается. - **Merge-коммиты.** Cherry-pick merge-коммита требует флага `-m N`, чтобы указать, какого родителя считать «основным». Обычно сложнее, чем кажется; чаще проще cherry-pick'нуть каждый коммит из merge'нутой ветки по отдельности. ## Команды ```bash git cherry-pick ``` Применить один коммит на текущую ветку ```bash git cherry-pick -x ``` Применить и добавить `cherry picked from` в сообщение ```bash git cherry-pick -n ``` Применить, но не коммитить (оставить в индексе) ```bash git cherry-pick A..B ``` Применить диапазон коммитов ## См. также - [git rebase](/courses/git/kb/rebase.md) - [git merge](/courses/git/kb/merge.md) - [git reflog](/courses/git/kb/reflog.md)