Назад до блога

Git cherry-pick: кілька комітів, гілок і конфліктів

12 вересня 2026 р.

TL;DR: git cherry-pick <sha> копіює один коміт з будь-якої гілки на вашу поточну — той самий патч, новий SHA, жодна історія не рушила. Для кількох комітів — перелічіть SHA або візьміть діапазон (git cherry-pick A..B); зверніть увагу, що діапазон виключає A, тож пишіть A^..B, щоб включити. Якщо зупиниться на конфлікті — виправте, зробіть git add, потім git cherry-pick --continue. Cherry-pick — для перенесення конкретного виправлення; коли хочете все з іншої гілки — беріть merge чи rebase.

Що git cherry-pick насправді робить?

Cherry-pick бере наявний коміт і застосовує його диф як новий коміт на поточній гілці. Оригінальний коміт лишається на місці; копія отримує свіжий SHA. Git нічого не «переміщує» — ті, хто згодом дивується, чому коміт досі видно на старій гілці, бачать саме це.

Модель «копіювання, а не переміщення» вирішує, коли cherry-pick — правильний інструмент:

  • Потрібне одне виправлення з feature-гілки на main зараз, без мержу решти.
  • Хотфік, закомічена не на ту гілку, має потрапити на правильну.
  • Патч треба перепроіграти на release-гілку, яка ніколи не мержить з main.

Доповнююча навичка — уміти відкатити коміт, що виявився помилковим; механіка цього — у git undo last commit: зі збереженням змін.

Як cherry-pick коміт з іншої гілки?

Знайдіть SHA, перейдіть на цільову гілку, виберіть:

# 1. Знайдіть коміт на гілці-джерелі
git log feature/payment-fix --oneline -5

# 2. Перейдіть на гілку, що має його отримати
git switch main

# 3. Скопіюйте
git cherry-pick 1a2b3c4

Дві зручності, варте знання:

  • git cherry-pick <branch> бере вершинний коміт гілки — зручно, але легко зробити випадково з застарілим уявленням про те, що таке «вершина».
  • Після вибору git log -1 --stat підтверджує, що приземлилося. Секунда читання — і економите revert.

Коміти лишаються на feature/payment-fix; ту гілку видаляйте коли завгодно — скопійований примірник на main має свій SHA і не залежить від старого.

Як cherry-pick кілька комітів?

Три форми в порядку частоти потреби:

# 1. Явний список — у порядку перерахування
git cherry-pick 1a2b3c4 5d6e7f8

# 2. Діапазон — усе після A до B включно
git cherry-pick A..B

# 3. Діапазон з включенням A
git cherry-pick A^..B

Різниця між A..B і A^..B — класичний сюрприз: A..B виключає A. Якщо візуалізуєте діапазон із git log і берете oldest..newest, ви мовчки пропускаєте найстаріший коміт. Коли мета — «найдавніші кілька комітів, у порядку», пишіть oldest^..newest, і off-by-one зникає.

Щоб згорнути кілька виборів в один коміт замість трьох, стейджте без коміту через -n / --no-commit, а потім комітьте раз:

git cherry-pick -n 1a2b3c4 5d6e7f8
git commit -m "Backport: payment retry fixes"

Чому git cherry-pick не працює?

Чотири справжні причини за частотою:

1. Конфлікт зупинив вибір. Git застосовує патч, натикається на рядок, змінений в обох гілках, і паузує посеред послідовності:

# виправте файли, потім:
git add <resolved-files>
git cherry-pick --continue   # чи --abort, щоб повернутися до стану перед вибором

--continue — не опція і не мається на увазі: доки не виконаєте, ви всередині призупиненої послідовності cherry-pick, і git status дотримуватиметься цього.

2. Вибір порожній («The previous cherry-pick is now empty»). Зміна вже є на цій гілці — часто від попереднього вибору чи сквошнутого мержу. Скіпніть через git cherry-pick --skip, або форсуйте порожній коміт через --allow-empty, якщо маркер вам справді потрібен.

3. Коміт — це merge-коміт. У мержу два батьки, тож «застосувати цей диф» неоднозначно — git відмовляється замість вгадування. Скажіть, від якого батька берете диф:

git cherry-pick -m 1 <merge-sha>   # батько 1 = гілка, *у яку* мержили

4. Не те робоче дерево чи detached HEAD. Вибір приземляється куди вказує HEAD. Перевірте git branch --show-current перед вибором; якщо нічого не друкує — ви в detached HEAD, і коміт осиротіє при перемиканні.

Cherry-pick vs merge vs rebase: що коли?

КомандаЩо приземляється на цільІсторіяКоли
git cherry-pick <sha>Лише названі комітиКопія, нові SHAКонкретне виправлення має поїхати зараз
git merge <branch>Уся гілкаMerge-коміт чи fast-forwardХочете цілу гілку, видиму розбіжність
git rebase <base>Усі коміти гілки, перепроіграніЛінійна, переписані SHAХочете гілку як чисту лінійну серію
git revert <sha>Обернений комітДодає undo-комітПриземлений коміт треба скасувати на спільній історії

Правило одним рядком: cherry-pick переносить вибірку; merge і rebase переносять усе. Потяг до cherry-pick «для синхронізації» з гілкою — ознака, що ви насправді хочете merge; а якщо гілка — main вашого форку проти upstream, повний ритуал у синхронізації fork з upstream, крок за кроком.

Звичка, яку варто пропустити: довгостроковий cherry-pick одного коміта в кілька гілок. Кожне майбутнє виправлення на гілці-джерелі потребує нового вибору, і гілки рано чи пізно розповзаються. Бекпорти на release-гілки — нормальний патерн; вічний паралельний всесвіт — ні.

Робочий процес cherry-pick, стисло

git log <source-branch> --oneline -5   # знайдіть SHA
git switch <target-branch>             # приземліться в правильному місці
git cherry-pick A^..B                  # діапазон, список чи один SHA
# при конфлікті: виправити → git add → git cherry-pick --continue
git log -1 --stat                      # підтвердіть, що прилетіло

Знайди, перемкнись, вибери, перевір. У команди репутація небезпечної, якої вона не заслуговує — диф або застосується, або зупиниться і скаже чому. Єдина справді руйнівна помилка — вибір не на ту гілку, і git log -1 перед пушем робить її важкопропустимою.

— mrsaynothing

— mrsaynothing

Польові нотатки про ШІ, Linux і self-hosting.

Обговорити пост на dev.to dev.to ↗

Наступний гайд — на email

Один лист на пост. Полагодили — і далі.

self-hosted · без третіх сторін · відписка в один клік

що це таке?

Cron чи таймери systemd: що обрати?

Читається добре? Таке я будую за гроші. найміть мене