Ошибка the previous cherry-pick is now empty possibly due to conflict resolution появляется, когда после разрешения конфликтов при выполнении git cherry-pick в индексе не осталось ни одного изменения для коммита. Git сообщает об этом при попытке завершить операцию через git cherry-pick --continue и останавливает процесс, ожидая решения пользователя. Это не сбой системы, а защитное поведение: Git не хочет молча создавать пустой коммит или терять ваши правки.
Проблема особенно часто встречается при переносе коммитов между ветками, где изменения уже частично применены ранее — например, после git rebase, слияний или предыдущих cherry-pick. В этой статье разберём, почему возникает сообщение, как корректно завершить cherry-pick и как избежать ситуации в будущем.
Что означает это сообщение на самом деле
При выполнении git cherry-pick <commit> Git пытается применить изменения указанного коммита к текущей ветке. Если возникает конфликт, операция приостанавливается, и вы вручную разрешаете его в файлах. После этого изменения добавляются в индекс через git add, и вы запускаете git cherry-pick --continue.
Именно на этом шаге Git сравнивает содержимое индекса с состоянием HEAD. Если оказывается, что после разрешения конфликта дерево файлов полностью совпадает с текущим коммитом — то есть разницы нет — Git выводит сообщение: «The previous cherry-pick is now empty, possibly due to conflict resolution». Проще говоря, переносить стало нечего: либо вы в процессе разрешения конфликта удалили все изменения, либо они уже существуют в целевой ветке.
Ключевая мысль: это не ошибка Git, а сигнал о том, что коммит после разрешения конфликта стал пустым. Git предлагает три пути: создать пустой коммит, пропустить его или прервать операцию целиком.
Основные причины возникновения
Чтобы выбрать правильное действие, нужно понять, почему коммит оказался пустым. На практике встречаются несколько типичных сценариев.
- 🔄 Изменения уже есть в целевой ветке. Коммит (или его эквивалент) был перенесён ранее — например, через
cherry-pick,rebaseили ручное слияние. Git это обнаруживает только после применения патча. - ✂️ При разрешении конфликта вы отбросили свои правки. Если при выборе между ours и theirs вы оставили текущую версию файла, изменений для коммита не осталось.
- 📦 Коммит содержал только уже применённые строки. Например, часть изменений попала в ветку через другой коммит, и после слияния патч выродился в пустой.
- 🔀 Конфликт был разрешён «в ноль». При ручном редактировании файла вы случайно удалили и конфликтные маркеры, и сами изменения.
⚠️ Внимание: прежде чем выбирать действие, проверьте содержимое индекса командой
git statusиgit diff --cached. Если там действительно пусто — изменений нет, и решение нужно принимать осознанно, а не «на автомате».
Как диагностировать ситуацию перед принятием решения
Первым делом посмотрите, в каком состоянии находится репозиторий. Команда git status покажет, что cherry-pick ещё в процессе, и перечислит файлы, которые были в конфликте. Затем выполните git diff --cached — если вывод пустой, индекс действительно не содержит изменений.
Полезно также сравнить исходный коммит с текущим состоянием ветки. Это поможет понять, потерялись ли изменения или они уже присутствуют:
git show <хеш-коммита>
git log --oneline -10
git diff HEAD <хеш-коммита> --stat
Если git diff HEAD <коммит> показывает, что деревья идентичны по нужным файлам, значит, изменения уже в ветке, и коммит можно смело пропускать. Если различия есть, но индекс пуст — скорее всего, вы потеряли правки при разрешении конфликта, и операцию лучше прервать и начать заново.
Три способа завершить cherry-pick
Git прямо в тексте сообщения подсказывает варианты действий. Разберём каждый из них и когда его применять.
Способ 1: пропустить пустой коммит
Самый частый и безопасный вариант — если изменения уже есть в ветке, коммит просто пропускается:
git cherry-pick --skip
Эта команда отбрасывает текущий пустой коммит и продолжает перенос следующих коммитов из очереди (если вы переносили диапазон). История остаётся чистой, без лишних пустых записей. Именно этот вариант подходит в большинстве случаев, когда git diff --cached пуст, а нужные изменения уже присутствуют в ветке.
Способ 2: создать пустой коммит принудительно
Иногда пустой коммит нужен намеренно — например, чтобы сохранить сообщение коммита как маркер, удовлетворить требования CI/CD или зафиксировать факт переноса для истории. Тогда используйте:
git commit --allow-empty
После этого cherry-pick завершится, а в истории появится коммит с исходным сообщением, но без изменений. Применяйте этот способ осознанно: пустые коммиты загромождают историю и могут запутать коллег при ревью.
Если пустой коммит нужен только ради сообщения, добавьте к нему пояснение через git commit --allow-empty --amend -m "новое сообщение", чтобы в истории было понятно, почему коммит пустой.
Способ 3: прервать операцию и начать заново
Если вы подозреваете, что потеряли изменения при разрешении конфликта, отмените cherry-pick полностью:
git cherry-pick --abort
Репозиторий вернётся в состояние до начала операции. После этого можно повторить git cherry-pick <commit> и аккуратнее разрешить конфликт, сохранив нужные правки. Это правильный выбор, когда git diff HEAD <коммит> показывает различия, которых нет в вашем рабочем дереве.
☑️ Чек-лист перед завершением cherry-pick
Сравнение вариантов действий
| Действие | Команда | Когда применять | Результат |
|---|---|---|---|
| Пропустить коммит | git cherry-pick --skip |
Изменения уже есть в ветке | Коммит не создаётся, история чистая |
| Создать пустой коммит | git commit --allow-empty |
Нужно сохранить сообщение/факт переноса | Пустой коммит в истории |
| Прервать операцию | git cherry-pick --abort |
Правки потеряны при разрешении конфликта | Возврат к состоянию до cherry-pick |
| Продолжить перенос | git cherry-pick --continue |
Только если изменения в индексе есть | Обычный коммит с изменениями |
Сообщение «cherry-pick is now empty» — это не ошибка, а выбор: пропустить коммит (--skip), создать пустой (--allow-empty) или отменить операцию (--abort). Решение зависит от того, есть ли нужные изменения в ветке.
Как избежать проблемы в будущем
Полностью исключить ситуацию нельзя — она естественна при параллельной работе с ветками. Но снизить частоту её появления можно несколькими практиками.
- 🔍 Проверяйте дубликаты перед переносом. Команда
git cherry <ветка>илиgit log --cherry-pickпомогает увидеть, какие коммиты уже присутствуют в целевой ветке в виде эквивалентных патчей. - 🧹 Переносите коммиты небольшими порциями. Чем меньше диапазон, тем проще контролировать конфликты и их разрешение.
- 📝 Внимательно разрешайте конфликты. Не выбирайте механически ours или theirs — проверяйте итоговый файл, чтобы не потерять изменения.
- 🌿 Синхронизируйте ветки регулярно. Чем дольше ветки живут раздельно, тем выше вероятность дублирующихся изменений.
Почему Git не пропускает пустые коммиты автоматически?
По умолчанию Git не решает за вас, важен пустой коммит или нет. Пустой коммит может быть осмысленным (маркер, сообщение, триггер CI), а может быть следствием ошибки при разрешении конфликта. Поэтому Git останавливается и требует явного решения: --skip, --allow-empty или --abort. Начиная с современных версий Git, у git cherry-pick есть опция --empty=drop|keep|stop, позволяющая задать поведение по умолчанию для пустых коммитов.
⚠️ Внимание: не используйте
git cherry-pick --skip, не проверив предварительноgit diff --cachedиgit diff HEAD <коммит>. Если изменения были потеряны при разрешении конфликта, пропуск коммита окончательно их не вернёт — придётся восстанавливать правки вручную из исходного коммита.
Часто задаваемые вопросы
Что делать, если git cherry-pick --continue выдаёт это сообщение?
Это значит, что в индексе нет изменений для коммита. Проверьте git diff --cached: если он пуст, выберите один из вариантов — git cherry-pick --skip (пропустить), git commit --allow-empty (создать пустой коммит) или git cherry-pick --abort (отменить операцию).
Безопасно ли использовать git cherry-pick --skip?
Да, если вы убедились, что изменения коммита уже присутствуют в целевой ветке. Сравните состояние через git diff HEAD <хеш-коммита>. Если различий по нужным файлам нет — пропуск полностью безопасен.
Чем --allow-empty отличается от --skip?
--skip не создаёт коммит вообще — история остаётся без следов переноса. --allow-empty создаёт коммит с исходным сообщением, но без изменений, что бывает нужно для истории или автоматизации.
Можно ли настроить Git, чтобы он не останавливался на пустых коммитах?
Да, у git cherry-pick есть опция --empty=<режим> со значениями drop (автоматически пропускать), keep (сохранять пустые коммиты) и stop (останавливаться, поведение по умолчанию). Например: git cherry-pick --empty=drop <commit>.
Я потерял изменения при разрешении конфликта. Как их вернуть?
Выполните git cherry-pick --abort, чтобы откатить операцию, затем повторите git cherry-pick <commit> и разрешите конфликт заново, сохранив нужные правки. Исходный коммит при этом никуда не девается — он доступен по своему хешу через git show.