Как получить один коммит из одной ветки в другую без слияния всей ветки в Git
Что проверяют
Умеете ли вы переносить точечные изменения, не таща за собой чужую работу, и понимаете ли, что при этом происходит с историей. Следом обычно спрашивают, чем cherry-pick отличается от rebase и что делать при конфликте.
Как отвечать
Основной инструмент git cherry-pick. Он берёт изменения указанного коммита и создаёт в текущей ветке новый коммит с тем же диффом и сообщением, но с другим хешем:
- найти коммит:
git log --oneline featureилиgit log feature -- src/components/Button.tsx, если нужен коммит по конкретному файлу; - перенести:
git switch release, затемgit cherry-pick <hash>. Несколько коммитов перечисляются через пробел, диапазон задаётся какA^..B; - конфликт: Git останавливается, вы правите файлы, делаете
git addиgit cherry-pick --continue. Передумали:git cherry-pick --abort; - полезные флаги:
-xдописывает в сообщение строку с исходным хешем, это спасает, когда потом ищут, откуда пришёл хотфикс;-nприменяет изменения без коммита, если хотите собрать несколько в один.
Типичный сценарий во фронтенде: фикс уже лежит в фиче, а выпустить его нужно из release прямо сейчас. Перенесли, прогнали линтер, тесты и сборку: окружающий код в целевой ветке может отличаться, и Git этого не проверит.
Если нужен не коммит, а один файл из другой ветки, есть git restore --source feature -- path/to/file. Это уже не перенос коммита, а копирование содержимого файла.
Где спотыкаются
Думают, что после cherry-pick коммит «тот же самый». Хеш новый, и при последующем слиянии исходной ветки правки тех же строк могут дать повторный конфликт.
Переносят коммит, который зависит от предыдущих: функция, импорт или переменная стилей появились раньше в фиче. Код применился без конфликтов, а сборка упала.
Путают с rebase и merge. rebase переносит серию коммитов на новую базу, merge соединяет истории целиком, а cherry-pick копирует конкретные изменения поштучно.