Пошук уроків, статей та іншого контенту
Альтернатива merge, що переписує історію гілки — і золоте правило, коли rebase небезпечний.
Rebase, як і merge (попередній модуль), вирішує задачу об'єднання роботи з двох гілок — але принципово інакше: замість створення коміту злиття з двома батьками, rebase переписує коміти однієї гілки так, ніби вони від початку були зроблені поверх останнього стану іншої гілки.
git switch feature/login-form
git rebase main # "перебазувати" коміти feature-гілки поверх поточного стану mainДо: main -> A -> B -> E
\
feature -> C -> D
Після rebase (нові коміти C' і D', історія лінійна):
main -> A -> B -> E -> C' -> D'Технічно rebase не «переміщує» старі коміти C і D — він створює нові коміти (C' і D') з тим самим вмістом змін, але новими хешами й новим батьком. Старі коміти C і D після rebase більше не належать жодній гілці й зрештою видаляються збирачем сміття Git — це і є причина, чому rebase вважається «переписуванням історії».
Merge зберігає точну історію того, як усе відбувалось насправді (включно з розгалуженнями), явним комітом злиття — прозоріше для аудиту, кому і коли яка робота приєдналась.
Rebase дає лінійну, «чисту» історію без комітів злиття — простіше читати git log, простіше git bisect (пошук коміту, що вніс баг), ціною втрати точного запису про паралельну структуру розробки.
Ніколи не робіть rebase гілки, яку вже отримали (fetch/pull) інші учасники команди. Оскільки rebase створює нові коміти замість старих, будь-хто, хто вже має локальну копію старих комітів, після pull-у отримає конфлікт і дубльовану, розбіжну історію — переписана публічна історія «ламає» роботу всіх, хто на неї покладався. Rebase безпечний лише для власної, ще не опублікованої (не запушеної, чи запушеної, але явно позначеної як особиста) гілки.
Типовий безпечний сценарій — оновити власну, ще не завершену feature-гілку останніми змінами з main перед відкриттям Pull Request: git rebase main (замість git merge main) тримає історію гілки лінійною й чистою для рев'юера, ще до того, як ця гілка стала спільною публічною історією через злиття.
Rebase гілки, з якою вже активно працюють інші учасники команди, — переписана історія ламає їхні локальні копії й змушує розплутувати дубльовані коміти.
Плутати git rebase з git merge за наслідками для історії — rebase переписує (нові хеші комітів), merge — лише додає новий коміт злиття, не чіпаючи існуючі.
Панікувати під час rebase-конфлікту й не знати про git rebase --abort — скасовує rebase повністю й повертає гілку в стан до його початку, так само, як git merge --abort для злиття.
Rebase переписує коміти гілки так, ніби вони від початку були зроблені поверх нового базового стану, — результат лінійна історія без комітів злиття, ціною того, що старі коміти замінюються новими (з новими хешами). Золоте правило: rebase лише власної, ще не опублікованої гілки — ніколи гілки, яку вже отримали інші учасники команди, бо це ламає їхню локальну історію.