Rebase — це операція в Git, яка переносить коміти з однієї гілки на вершину іншої, створюючи лінійну історію без зайвих merge-комітів. На відміну від злиття, rebase перезаписує історію: кожен перенесений коміт отримує новий хеш, оскільки змінюється його батьки. Згідно з документацією Git (2026), rebase застосовується для синхронізації feature-гілок з актуальним станом main перед створенням pull request. Команда git rebase — один з основних інструментів для підтримки чистої історії в проектах, що використовують Git Flow.
Головне
Rebase — це команда Git, яка перебазує поточну гілку на зазначену: бере всі коміти поточної гілки, тимчасово зберігає їх, переміщує вказівник гілки на цільовий коміт і послідовно застосовує збережені коміти поверх нього. Результат — історія виглядає так, ніби розробник вів роботу безпосередньо від останнього коміту цільової гілки.
Основний синтаксис: git rebase main — перебуваючи в feature-гілці, ця команда переносить всі feature-коміти на вершину main. Git використовує стратегію three-way merge для кожного коміту окремо. Якщо коміт A вже присутній в цільовій гілці (визначається за хешем), Git автоматично пропускає його, що дозволяє уникнути дублювання змін.
Rebase також підтримує onto-режим для перенесення частини комітів: git rebase --onto target start end — ця форма дозволяє виділити діапазон комітів з однієї гілки та застосувати їх поверх іншої. Наприклад, git rebase --onto main feature~3 feature переносить останні три коміти гілки feature поверх main.
# Switch to feature branch
git checkout feature
# Rebase feature onto main
git rebase main
# After successful rebase — history is linear
git log --oneline --graph
# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD
Rebase та merge вирішують одне завдання — об’єднання змін з різних гілок — але роблять це принципово різними способами. Merge зберігає повну історію злиття, створюючи merge-коміт з двома батьками. Rebase перезаписує історію, роблячи її лінійною. Вибір між ними залежить від workflow команди та правил роботи з репозиторієм.
Основна відмінність — як фіксується факт злиття. Merge зберігає: «в цій точці ми об’єднали feature в main» — це інформативно для історії проекту, але засмічує лог при частих злиттях. Rebase показує: «коміти feature були зроблені послідовно від останнього стану main» — це чисто, але приховує той факт, що розробка велася паралельно.
Друга відмінність — обробка конфліктів. При merge конфлікти вирішуються один раз, і рішення фіксується в merge-коміті. При rebase конфлікти можуть виникнути для кожного перенесеного коміту, і кожен вимагає окремого вирішення. Це більш трудомістко, але дозволяє точніше контролювати, які зміни потрапляють в підсумкову версію.
| Критерій | Rebase | Merge |
|---|---|---|
| Історія | Лінійна, без merge-комітів | Нелінійна, з merge-комітами |
| Хеші комітів | Перезаписуються (нові) | Зберігаються оригінальні |
| Конфлікти | Для кожного коміту окремо | Один раз в merge-коміті |
| Публічні гілки | Заборонено | Дозволено |
| Команда відміни | git rebase --abort | git merge --abort |
Інтерактивний rebase (git rebase -i) — це режим, при якому Git відкриває редактор зі списком комітів та доступними діями для кожного з них. Розробник може переписати історію перед відправленням у віддалений репозиторій. Це основний інструмент для підтримки чистоти комітів в feature-гілці.
Доступні команди в інтерактивному режимі: pick (залишити коміт як є), reword (змінити повідомлення коміту), edit (зупинитися для змін), squash (об’єднати з попереднім комітом, зберігши обидва повідомлення), fixup (об’єднати, відкинувши повідомлення), drop (видалити коміт). Кожна команда вказується перед хешем коміту в відкритому редакторі.
Squash та fixup — найчастіше використовувані команди для об’єднання комітів. Якщо розробник зробив 5 дрібних комітів з правками в процесі роботи, squash об’єднає їх в один логічний коміт з осмисленим повідомленням. Fixup корисний для виправлення друкарських помилок: зміни потрапляють у попередній коміт без збереження свого повідомлення.
# Open editor for last 4 commits
git rebase -i HEAD~4
# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# After saving — Git performs rebase
# and opens editor for squashed commit message
# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash
Прапорець --autosquash автоматично розставляє fixup/squash для комітів, повідомлення яких починаються з fixup! або squash!. Це прискорює роботу, якщо розробник заздалегідь маркує коміти для подальшого об’єднання. Прапорець --committer-date-is-author-date зберігає оригінальну дату коміту при перебазуванні — корисно для збереження часової хронології в історії.
Конфлікти при rebase виникають, коли Git не може автоматично застосувати перенесений коміт через протиріччя з змінами в цільовій гілці. На відміну від merge, де конфлікт вирішується один раз, при rebase кожен коміт може викликати конфлікт, і його потрібно вирішувати послідовно для кожного коміту від найстарішого до найновішого.
Коли виникає конфлікт, Git призупиняє rebase та повідомляє, який коміт викликав проблему. Розробник відкриває конфліктний файл (Git позначає конфліктні ділянки маркерами <<<<<<<, =======, >>>>>>>), редагує його, додає до індексу (git add) та продовжує rebase командою git rebase --continue. Якщо рішення не знайдено — git rebase --abort повністю скасовує перебазування.
Порада: при множинних конфліктах ефективніше використовувати git mergetool, який відкриває візуальний редактор для вирішення конфліктів. Також можна пропустити проблемний коміт (git rebase --skip), але це видалить його зміни з підсумкової історії, що рідко буває правильним рішенням.
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Check status
git status
# both modified: file.txt
# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue
# If uncertain — abort
git rebase --abort
Золоте правило rebase: ніколи не перебазуйте коміти, які вже були відправлені до віддаленого репозиторію та доступні іншим розробникам. Оскільки rebase перезаписує хеші комітів, у колег виникнуть конфлікти при спробі синхронізації — їхня локальна історія буде розходитися з переписаною віддаленою.
Ситуація, в якій rebase категорично заборонено: якщо хтось вже створив гілку на основі ваших комітів (наприклад, ваш колега зробив гілку від вашої feature), переписування історії зламає його роботу. В таких випадках слід використовувати merge. Також не рекомендується робити rebase прямо перед дедлайном — помилка при вирішенні конфліктів може зайняти більше часу, ніж очікувалося, та заблокувати реліз.
Виняток: якщо гілка використовується лише одним розробником (особиста feature-гілка, не опублікована або опублікована в draft-режимі), rebase до пушу — стандартна практика. Після публікації та початку колективної роботи — тільки merge. GitHub та GitLab типово пропонують squash merge як компроміс: він об’єднує коміти в один, але не перезаписує історію цільової гілки.
У сучасних командах найчастіше використовується rebase-орієнтований workflow разом з GitHub Flow. Процес виглядає так: розробник створює feature-гілку від main, працює в ній, періодично синхронізується через git rebase main, а перед створенням pull request виконує інтерактивний rebase для очищення історії.
Після створення PR (якщо потрібно підтягнути нові зміни з main) використовується git pull --rebase main замість звичайного git pull. Це дозволяє підтягнути зміни без створення зайвого merge-коміту. Git pull з прапорцем --rebase еквівалентний git fetch + git rebase — Git спочатку завантажує нові коміти, потім перебазує локальні зміни поверх них.
Git дозволяє налаштувати rebase як поведінку за замовчуванням для pull: git config --global pull.rebase true. Після цієї налаштування git pull завжди виконує rebase замість merge. Якщо потрібен звичайний pull — використовується git pull --no-rebase. Багато команд також вмикають autostash: git config --global rebase.autoStash true — це автоматично ховає незакомічені зміни перед rebase та відновлює їх після.
Часто запитувані питання
Перебазувати — означає виконати git rebase: перенести коміти поточної гілки на вершину іншої. У результаті історія стає лінійною, кожен коміт отримує новий хеш, а merge-коміти не створюються. Команда використовується для синхронізації гілок без зайвих точок злиття в лозі.
Merge створює merge-коміт з двома батьками, зберігаючи паралельну історію та оригінальні хеші. Rebase перезаписує історію — коміти отримують нові хеші, а історія стає лінійною. Merge безпечніше для публічних гілок, rebase дає чистіший лог.
Команда git rebase -i HEAD~N відкриває редактор з N останніми комітами. Для кожного коміту можна вибрати дію: pick (залишити), reword (перейменувати), edit (змінити), squash (об’єднати з попереднім), fixup (об’єднати без повідомлення), drop (видалити). Після збереження Git застосовує вибрані зміни.
Rebase перезаписує хеші комітів, що робить історію несумісною з копіями тих самих комітів на комп’ютерах інших розробників. Якщо колега вже отримав ваші коміти через git pull, а ви потім перебазували їх, його git push буде відхилено, а git pull створить дубльовані коміти та конфлікти.
До завершення — git rebase --abort повністю скасовує. Після завершення можна відновити попередній стан через git reflog — знайти хеш коміту до rebase та виконати git reset --hard на нього. Reflog зберігає історію переміщень HEAD протягом 30 днів за замовчуванням.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також