EMZETT.
Войти

git bisect и cherry-pick: поиск ошибок и перенос коммитов

Коротко: С git bisect вы находите половинным делением коммит, внёсший ошибку; с git cherry-pick переносите отдельные коммиты в другую ветку.

Подробнее: Две продвинутые команды Git, которые сильно экономят время в повседневной работе. Обе предполагают, что история чисто разделена на осмысленные небольшие коммиты.

Подробности

git bisect: поиск ошибки бинарным поиском

Вы знаете: три недели назад работало, теперь нет, а между ними 200 коммитов. git bisect многократно делит диапазон пополам (бинарный поиск), и примерно через восемь шагов вы знаете виновника.

git bisect start
git bisect bad                 # текущее состояние неисправно
git bisect good v1.4.0         # это состояние было исправным
git bisect good                # или: git bisect bad
git bisect reset               # вернуться в исходное состояние

С тестовым скриптом он работает автоматически: git bisect run npm test (код завершения 0 = хорошо, 1–127 = плохо, 125 = пропустить).

git cherry-pick: перенос отдельных коммитов

Обычно сливают целые ветки. cherry-pick, напротив, копирует один или несколько коммитов в текущую ветку:

git switch release/1.2
git cherry-pick 3f4a2b1           # перенести один коммит
git cherry-pick A..B              # диапазон
git cherry-pick -x 3f4a2b1        # указать источник в сообщении

Типичный случай: ошибка исправлена в основной ветке, но должна попасть и в ветку релиза. Перенесённый коммит получает новый хеш-идентификатор, потому что находится поверх другого родителя.

Конфликты и подводные камни

При конфликтах Git останавливается: разрешите конфликт, git add, затем git cherry-pick --continue (или --abort). Кто многократно переносит коммиты, создаёт в истории дубликаты, которые могут запутать последующие слияния. Cherry-pick не заменяет чистый процесс работы с ветками. При bisect проверяемые состояния должны собираться и быть тестируемыми; с git bisect skip пропускаются неработающие промежуточные состояния.

Связь

Небольшие чистые коммиты (см. Conventional Commits) вообще делают оба инструмента эффективными: огромный коммит «изменил всё» нельзя ни целенаправленно найти, ни целенаправленно перенести. git blame и git log -S также помогают в поиске.

См. также: Git, Git rebase, Конфликты слияния, Conventional Commits