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