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